zoukankan      html  css  js  c++  java
  • springdata-jpa学习

    1.0 jdbc操作数据库回顾

      

    2.0 orm思想的引入

      

       实现orm思想的框架有mybatis(半orm)与hibernate,主要就是建立实体类与表的关系,建立实体类属性与表字段的关系

    3.0 jpa规范的引入

      由于出现了很多像hibernate这样的orm框架,比较混乱,于是sun公司提出了jpa规范,内部时接口和抽象类

      

    4.0 jpa基本操作

     4.1工程搭建

        1.创建maven工程导入坐标
        2.需要配置jpa的核心配置文件
           *位置:配置到类路径下的一个叫做 META-INF 的文件夹下
           *命名:persistence.xml
        3.编写客户的实体类
        4.配置实体类和表,类中属性和表中字段的映射关系

     4.2 操作步骤

      1.加载配置文件创建实体管理器工厂  

      2.根据实体管理器工厂,创建实体管理器 

        3.创建事务对象,开启事务

        4.增删改查操作

        5.提交事务

        6.释放资源

     4.3基本操作

     @Test
        public void testSave(){
            // 加载配置文件创建实体管理器工厂
            EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myJpa");
            // 通过实体管理器工厂获取实体管理器
            EntityManager entityManager = entityManagerFactory.createEntityManager();
            // 获取事务,开启事务
            EntityTransaction tx = entityManager.getTransaction();
            tx.begin();
            // 完成jpa增删改查操作
            Customer customer = new Customer();
            customer.setCustName("传智播客");
            customer.setCustIndustry("教育");
            // 实体管理器保存对象
            entityManager.persist(customer);
            // 事务提交
            tx.commit();
            // 释放资源
            entityManager.close();
            entityManagerFactory.close();
        }
    

      

    /**
         * 根据id查询
         */
        @Test
        public void testFind(){
            EntityManager entityManager = JpaUtils.getEntityManager();
            EntityTransaction tx = entityManager.getTransaction();
            tx.begin();
            Customer customer = entityManager.find(Customer.class, 1L);
            System.out.println(customer);
            tx.commit();
            entityManager.close();
        }
    

      

        /**
         * 根据id查询(延迟加载)
         */
        @Test
        public void testGetReference(){
            EntityManager entityManager = JpaUtils.getEntityManager();
            EntityTransaction tx = entityManager.getTransaction();
            tx.begin();
            Customer customer = entityManager.getReference(Customer.class,1L);
            System.out.println(customer);
            tx.commit();
            entityManager.close();
        }
    

      

       /**
         * 删除客户的案例
         */
        @Test
        public void testDelete(){
            EntityManager entityManager = JpaUtils.getEntityManager();
            EntityTransaction tx = entityManager.getTransaction();
            tx.begin();
    //        Customer customer = new Customer();
    //        customer.setCustId(2L);
            Customer customer = entityManager.find(Customer.class, 1L);
            entityManager.remove(customer);
            tx.commit();
            entityManager.close();
        }
    

      

        /**
         * 更新客户的案例
         */
        @Test
        public void testUpdate(){
            EntityManager entityManager = JpaUtils.getEntityManager();
            EntityTransaction tx = entityManager.getTransaction();
            tx.begin();
            Customer customer = entityManager.find(Customer.class, 2L);
            customer.setCustIndustry("it教育");
            entityManager.merge(customer);
            tx.commit();
            entityManager.close();
        }
    

     4.4 jpql操作

       /**
         * 查询全部
         */
        @Test
        public void findAll(){
            EntityManager entityManager = JpaUtils.getEntityManager();
            EntityTransaction tx = entityManager.getTransaction();
            tx.begin();
            Query query = entityManager.createQuery("from Customer ");
            List list = query.getResultList();
            list.stream().forEach(customer-> System.out.println(customer));
            tx.commit();
            entityManager.close();
        }
    

      

       /**
         * 结果排序
         */
        @Test
        public void findOrder(){
            EntityManager entityManager = JpaUtils.getEntityManager();
            EntityTransaction tx = entityManager.getTransaction();
            tx.begin();
            Query query = entityManager.createQuery("from Customer order by custId desc");
            List list = query.getResultList();
            list.stream().forEach(customer-> System.out.println(customer));
            tx.commit();
            entityManager.close();
        }
    

      

         /**
         * 结果统计
         */
        @Test
        public void findTotal(){
            EntityManager entityManager = JpaUtils.getEntityManager();
            EntityTransaction tx = entityManager.getTransaction();
            tx.begin();
            Query query = entityManager.createQuery("select count(custId) from Customer");
            Object result = query.getSingleResult();
            System.out.println(result);
            tx.commit();
            entityManager.close();
        }
    

      

        /**
         * 分页查询
         */
        @Test
        public void findPaged(){
            EntityManager entityManager = JpaUtils.getEntityManager();
            EntityTransaction tx = entityManager.getTransaction();
            tx.begin();
            Query query = entityManager.createQuery("from Customer");
            query.setFirstResult(0);
            query.setMaxResults(2);
            List list = query.getResultList();
            list.stream().forEach(customer-> System.out.println(customer));
            tx.commit();
            entityManager.close();
        }
    

      

        /**
         * 条件查询
         */
        @Test
        public void findCondition(){
            EntityManager entityManager = JpaUtils.getEntityManager();
            EntityTransaction tx = entityManager.getTransaction();
            tx.begin();
            Query query = entityManager.createQuery("from Customer where custName like ?");
            query.setParameter(1,"传智%");
            List list = query.getResultList();
            list.stream().forEach(customer-> System.out.println(customer));
            tx.commit();
            entityManager.close();
        }
    

    5.0 springdata-jpa 

      Spring Data JPA 是 Spring 基于 ORM 框架、JPA 规范的基础上封装的一套JPA应用框架,可使开发者用极简的代码即可实现对数据库的访问和操作。

    Spring Data JPA 让我们解脱了DAO层的操作,基本上所有CRUD都可以依赖于它来实现,在实际的工作工程中,推荐使用Spring Data JPA + ORM(如:hibernate)

    完成操作,这样在切换不同的ORM框架时提供了极大的方便,同时也使数据库层操作更加简单,方便解耦。使用了SpringDataJpa,我们的dao层中只需要写接口,

    就自动具有了增删改查、分页查询等方法

      

       5.1 基本增删改查

        i.搭建环境
          创建工程导入坐标
          配置spring的配置文件(配置spring Data jpa的整合)
          编写实体类(Customer),使用jpa注解配置映射关系
         ii.编写一个符合springDataJpa的dao层接口
          * 只需要编写dao层接口,不需要编写dao层接口的实现类
          * dao层接口规范
           1.需要继承两个接口(JpaRepository,JpaSpecificationExecutor)
           2.需要提供响应的泛型

          findOne(id) :根据id查询
          save(customer):保存或者更新(依据:传递的实体类对象中,是否包含id属性)
          delete(id) :根据id删除
          findAll() : 查询全部

          

      5.2 原理分析

         1.通过JdkDynamicAopProxy的invoke方法创建了一个动态代理对象
         2.SimpleJpaRepository当中封装了JPA的操作(借助JPA的api完成数据库的CRUD)
         3.通过hibernate完成数据库操作(封装了jdbc)

      

      5.3 jpql方法    

        使用Spring Data JPA提供的查询方法已经可以解决大部分的应用场景,但是对于某些业务来说,我们还需要灵活的构造查询条件,这时就可以使用@Query注解,结合JPQL的语句方式完成查询

      5.4 sql查询

      1.特有的查询:需要在dao接口上配置方法
         2.在新添加的方法上,使用注解的形式配置sql查询语句
         3.注解 : @Query
            value :jpql语句 | sql语句
            nativeQuery :false(使用jpql查询) | true(使用本地查询:sql查询)
           是否使用本地查询

      5.5方法名称规则查询

    6.0 Specification动态条件查询,分页排序

      

         @Test
        public void specTest4(){
            Page<Customer> page = customerDao.findAll(new Specification<Customer>() {
                @Override
                public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                    Path<Object> custName = root.get("custName");
                    Predicate predicate = criteriaBuilder.like(custName.as(String.class), "传智播客%");
                    return predicate;
                }
            }, new PageRequest(1, 1, new Sort(Sort.Direction.DESC, "custId")));
            List<Customer> customers = page.getContent();
            customers.stream().forEach((customer -> System.out.println(customer)));
        }
    

    7.0 表间关系

      7.1 一对多 

        1 都不设置关系,save两次,则联系人和客户为两条不相关的数据

        2 只设置客户到联系人,save两次,即一对多,则会发送两个insert一个update

        customer.getLinkMens().add(linkMan);

        3 只设置联系人到客户,即多对一,save两次,会发送两个insert语句,因为插入多时已经设置了外键  

        linkMan.setCustomer(customer);

        4 两个都设置,即一对多,多对一,save两次,会发送两个insert和一个update,但是此时update是多余的,因为插入时已经设置了外键  

        linkMan.setCustomer(customer);//由于配置了多的一方到一的乙方,保存时已经保存了外键
        customer.getLinkMens().add(linkMan);//由于配置了一的一方到多的一方的关系会发送update 重复

        5 两个都设置,但是让一的那方放弃一对多外键维护,这样就不会update重复了

        

        6 级联问题(级联删除)   

          删除从表数据:可以随时任意删除。

          删除主表数据:

            有从表数据

              1、在默认情况下,它会把外键字段置为null,然后删除主表数据。如果在数据库的表结构上,外键字段有非空约束,默认情况就会报错了

              2、如果配置了放弃维护关联关系的权利,则不能删除(与外键字段是否允许为null 没有关系)因为在删除时,它根本不会去更新从表的外键字段了。

              3、如果还想删除,使用级联删除引用

            没有从表数据引用:随便删

          在实际开发中,级联删除请慎用!(在一对多的情况下)

        7 级联问题(级联添加)

          

      7.2 多对多

     8 总结

      首先看一对多

        两个关系任意设置一个即可,两个都设置会重复,设置一下一的一方放弃外键,然后想要只保存一次即可,所以设置级联操作

      再来看多对多

        两个关系任意设置一个即可,两个都设置会报错,设置被动的一方放弃外键,然后想要保存一次即可,则设置级联操作

    9 对象导航查询

      一get多默认延迟加载

      多get一默认立即加载

  • 相关阅读:
    第一次结对编程作业
    第7组 团队展示
    第一次个人编程作业
    js学习笔记(1)
    第一次博客作业
    期末总结
    王者光耀团队作业
    第四次c++作业
    c++第三次作业
    第一次编程作业
  • 原文地址:https://www.cnblogs.com/helloworldmybokeyuan/p/11601196.html
Copyright © 2011-2022 走看看