zoukankan      html  css  js  c++  java
  • 12 Spring Data JPA:springDataJpa的运行原理以及基本操作(下)

    spring data jpa
    day1:orm思想和hibernate以及jpa的概述和jpa的基本操作

    day2:springdatajpa的运行原理

    day2:springdatajpa的基本操作

    day3:多表操作,复杂查询

    day2:springdatajpa的运行原理以及基本操作 (下)


     环境搭建及前面的代码在: day2:springdatajpa的运行原理

        

    第四 复杂查询
        i.借助接口中的定义好的方法完成查询
            findOne(id):根据id查询
        ii.jpql的查询方式
            jpql : jpa query language  (jpq查询语言)
            特点:语法或关键字和sql语句类似
                查询的是类和类中的属性
                
            * 需要将JPQL语句配置到接口方法上
                1.特有的查询:需要在dao接口上配置方法
                2.在新添加的方法上,使用注解的形式配置jpql查询语句
                3.注解 : @Query
    
        iii.sql语句的查询
                1.特有的查询:需要在dao接口上配置方法
                2.在新添加的方法上,使用注解的形式配置sql查询语句
                3.注解 : @Query
                    value :jpql语句 | sql语句
                    nativeQuery :false(使用jpql查询) | true(使用本地查询:sql查询)
                        是否使用本地查询
                        
        iiii.方法名称规则查询
    @RunWith(SpringJUnit4ClassRunner.class) //声明spring提供的单元测试环境
    @ContextConfiguration(locations = "classpath:applicationContext.xml")//指定spring容器的配置信息
    public class CustomerDaoTest {
        @Autowired
        private CustomerDao customerDao;

    19-spring Data JPA查询:调用接口方法查询(count,exists)

        /**
         * 测试统计查询:查询客户的总数量
         *      count:统计总条数
         */
        @Test
        public void testCount() {
            long count = customerDao.count();//查询全部的客户数量
            System.out.println(count);
        }
    
        /**
         * 测试:判断id为4的客户是否存在
         *      1. 可以查询以下id为4的客户
         *          如果值为空,代表不存在,如果不为空,代表存在
         *      2. 判断数据库中id为4的客户的数量
         *          如果数量为0,代表不存在,如果大于0,代表存在
         */
        @Test
        public void  testExists() {
            boolean exists = customerDao.exists(4l);
            System.out.println("id为4的客户 是否存在:"+exists);
        }

    20-spring Data JPA查询:调用接口方法查询(findOne和getOne的区别)

        /**
         * 根据id从数据库查询
         *      @Transactional : 保证getOne正常运行
         *
         *  findOne:
         *      em.find()           :立即加载
         *  getOne:
         *      em.getReference     :延迟加载
         *      * 返回的是一个客户的动态代理对象
         *      * 什么时候用,什么时候查询
         */
        @Test
        @Transactional
        public void  testGetOne() {
            Customer customer = customerDao.getOne(2l);
            System.out.println(customer);
        }

    第4章     Spring Data JPA的查询方式

    4.1    使用Spring Data JPA中接口定义的方法进行查询

    在继承JpaRepository,和JpaRepository接口后,我们就可以使用接口中定义的方法进行查询

     

     


    4.2    使用JPQL的方式查询 

     21-spring Data JPA查询:JPQL查询引入

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

        ii.jpql的查询方式
            jpql : jpa query language  (jpq查询语言)
            特点:语法或关键字和sql语句类似
                 查询的是类和类中的属性
                
            * 需要将JPQL语句配置到接口方法上
                1.特有的查询:需要在dao接口上配置方法
                2.在新添加的方法上,使用注解的形式配置jpql查询语句
                3.注解 : @Query

    22-jpql:使用jpql完成基本查询 

    package cn.bjut.dao;
    
    
    import cn.bjut.domain.Customer;
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
    import org.springframework.data.jpa.repository.Query;
    
    /**
     * 符合SpringDataJpa的dao层接口规范
     *      JpaRepository<操作的实体类类型,实体类中主键属性的类型>
     *          * 封装了基本CRUD操作
     *      JpaSpecificationExecutor<操作的实体类类型>
     *          * 封装了复杂查询(分页)
     */
    public interface CustomerDao extends JpaRepository<Customer,Long>, JpaSpecificationExecutor<Customer> {
    
        /**
         * 案例:根据客户名称查询客户
         *      使用jpql的形式查询
         *  jpql:from Customer where custName = ?
         *
         *  配置jpql语句,使用的@Query注解
         */
        @Query(value="from Customer where custName = ?")
        public Customer findJpql(String custName);
    
    
    }

     新建一个测试类  

     JpqlTest

    @RunWith(SpringJUnit4ClassRunner.class) //声明spring提供的单元测试环境
    @ContextConfiguration(locations = "classpath:applicationContext.xml")//指定spring容器的配置信息
    public class JpqlTest {
        @Autowired
        private CustomerDao customerDao;

      23-jpql:多占位符的赋值 

        /**
         * 案例:根据客户名称和客户id查询客户
         *      jpql: from Customer where custName = ? and custId = ?
         *
         *  对于多个占位符参数
         *      赋值的时候,默认的情况下,占位符的位置需要和方法参数中的位置保持一致
         *
         *  可以指定占位符参数的位置
         *      ? 索引的方式,指定此占位的取值来源
         */
        @Query(value = "from Customer where custName = ?2 and custId = ?1")
        public Customer findCustNameAndId(Long id,String name);

     24-jpql:使用jpql完成更新操作 

    此外,也可以通过使用 @Query 来执行一个更新操作,为此,我们需要在使用 @Query 的同时,用 @Modifying 来将该操作标识为修改查询,这样框架最终会生成一个更新的操作,而非查询。

      

        /**
         * 使用jpql完成更新操作
         *      案例 : 根据id更新,客户的名称
         *          更新3号客户的名称,将名称改为“初级程序员”
         *
         *  sql  :update cst_customer set cust_name = ? where cust_id = ?
         *  jpql : update Customer set custName = ? where custId = ?
         *
         *  @Query : 代表的是进行查询
         *      * 声明此方法是用来进行更新操作
         *  @Modifying
         *      * 当前执行的是一个更新操作
         *
         */
        @Query(value = " update Customer set custName = ?2 where custId = ?1 ")
        @Modifying
        public void updateCustomer(long custId,String custName);
    springDataJpa中使用jpql完成 更新/删除操作
    需要手动添加事务的支持
    默认会执行结束之后,回滚事务 
        /**
         * 测试jpql的更新操作
         *  * springDataJpa中使用jpql完成 更新/删除操作
         *         * 需要手动添加事务的支持
         *         * 默认会执行结束之后,回滚事务
         *   @Rollback : 设置是否自动回滚
         *          false | true
         */
        @Test
        @Transactional //添加事务的支持
        @Rollback(value = false)
        public void testUpdateCustomer() {
            customerDao.updateCustomer(3l,"初级程序员");
        }

       

     4.3  使用SQL语句查询 

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

     25-sql查询:查询全部 

        /**
         * 使用sql的形式查询:
         *     查询全部的客户
         *  sql : select * from cst_customer;
         *  Query : 配置sql查询
         *      value : sql语句
         *      nativeQuery : 查询方式
         *          true : sql查询
         *          false:jpql查询
         *
         */
        //@Query(value = " select * from cst_customer" ,nativeQuery = true)
        @Query(value="select * from cst_customer where cust_name like ?1",nativeQuery = true)
        public List<Object []> findSql(String name);

      26-sql查询:条件全部 

        //测试sql查询
        @Test
        public void testFindSql() {
            List<Object[]> list = customerDao.findSql("传智播客%");
            for(Object [] obj : list) {
                System.out.println(Arrays.toString(obj));
            }
        }

    4.4    方法命名规则查询

    按照Spring Data JPA 定义的规则,查询方法以findBy开头,涉及条件查询时,条件的属性用条件关键字连接,要注意的是:条件属性首字母需大写。框架在进行方法名解析时,会先把方法名多余的前缀截取掉,然后对剩下部分进行解析。

      具体的关键字,使用方法和生产成SQL如下表所示

      

             

    Keyword

    Sample

    JPQL

       

    And

    findByLastnameAndFirstname

    … where x.lastname = ?1 and x.firstname = ?2

       

    Or

    findByLastnameOrFirstname

    … where x.lastname = ?1 or x.firstname = ?2

       

    Is,Equals

    findByFirstnameIs,

    findByFirstnameEquals

    … where x.firstname = ?1

       

    Between

    findByStartDateBetween

    … where x.startDate between ?1 and ?2

       

    LessThan

    findByAgeLessThan

    … where x.age < ?1

       

    LessThanEqual

    findByAgeLessThanEqual

    … where x.age ⇐ ?1

       

    GreaterThan

    findByAgeGreaterThan

    … where x.age > ?1

       

    GreaterThanEqual

    findByAgeGreaterThanEqual

    … where x.age >= ?1

       

    After

    findByStartDateAfter

    … where x.startDate > ?1

       

    Before

    findByStartDateBefore

    … where x.startDate < ?1

       

    IsNull

    findByAgeIsNull

    … where x.age is null

       

    IsNotNull,NotNull

    findByAge(Is)NotNull

    … where x.age not null

       

    Like

    findByFirstnameLike

    … where x.firstname like ?1

       

    NotLike

    findByFirstnameNotLike

    … where x.firstname not like ?1

       

    StartingWith

    findByFirstnameStartingWith

    … where x.firstname like ?1 (parameter bound with appended %)

       

    EndingWith

    findByFirstnameEndingWith

    … where x.firstname like ?1 (parameter bound with prepended %)

       

    Containing

    findByFirstnameContaining

    … where x.firstname like ?1 (parameter bound wrapped in %)

       

    OrderBy

    findByAgeOrderByLastnameDesc

    … where x.age = ?1 order by x.lastname desc

       

    Not

    findByLastnameNot

    … where x.lastname <> ?1

       

    In

    findByAgeIn(Collection ages)

    … where x.age in ?1

       

    NotIn

    findByAgeNotIn(Collection age)

    … where x.age not in ?1

       

    TRUE

    findByActiveTrue()

    … where x.active = true

       

    FALSE

    findByActiveFalse()

    … where x.active = false

       

    IgnoreCase

    findByFirstnameIgnoreCase

    … where UPPER(x.firstame) = UPPER(?1)

       

     27-方法命名规则查询:基本查询 

     28-方法命名规则查询:模糊匹配

     29-方法命名规则查询:多条件查询

        /**
         * 方法名的约定:
         *      findBy : 查询
         *            对象中的属性名(首字母大写) : 查询的条件
         *            CustName
         *            * 默认情况 : 使用 等于的方式查询
         *                  特殊的查询方式
         *
         *  findByCustName   --   根据客户名称查询
         *
         *  再springdataJpa的运行阶段
         *          会根据方法名称进行解析  findBy    from  xxx(实体类)
         *                                      属性名称      where  custName =
         *
         *      1.findBy  + 属性名称 (根据属性名称进行完成匹配的查询=)
         *      2.findBy  + 属性名称 + “查询方式(Like | isnull)”
         *          findByCustNameLike
         *      3.多条件查询
         *          findBy + 属性名 + “查询方式”   + “多条件的连接符(and|or)”  + 属性名 + “查询方式”
         */
        public Customer findByCustName(String custName);
    
    
        public List<Customer> findByCustNameLike(String custName);
    
        //使用客户名称模糊匹配和客户所属行业精准匹配的查询
        public Customer findByCustNameLikeAndCustIndustry(String custName,String custIndustry);

      测试类中的代码如下 

      

        //测试方法命名规则的查询
        @Test
        public void testNaming() {
            Customer customer = customerDao.findByCustName("传智播客");
            System.out.println(customer);
        }
    
    
        //测试方法命名规则的查询
        @Test
        public void testFindByCustNameLike() {
            List<Customer> list = customerDao.findByCustNameLike("传智播客%");
            for (Customer customer : list) {
                System.out.println(customer);
            }
        }
    
    
        //测试方法命名规则的查询
        @Test
        public void testFindByCustNameLikeAndCustIndustry() {
            Customer customer = customerDao.findByCustNameLikeAndCustIndustry("传智播客1%", "it教育");
            System.out.println(customer);
        }

    ========================

    end

    部分内容来自于学习编程期间收集于网络的免费分享资源和工作后购买的付费内容。
  • 相关阅读:
    Classification and Representation(分类与表示)
    静态链表
    拓扑序列
    二分图问题
    大数据概述
    QT出现应用程序无法正常启动0xc000007b的错误
    简易有穷自动机实验
    一个简易的C语言文法
    词法分析器实验报告
    浅谈词法分析器
  • 原文地址:https://www.cnblogs.com/MarlonKang/p/11611077.html
Copyright © 2011-2022 走看看