zoukankan      html  css  js  c++  java
  • SpringDataJPA第二天讲义

    第1章     Spring Data JPA的概述

    1.1    Spring Data JPA概述

      Spring Data JPA 是 Spring 基于 ORM 框架、JPA 规范的基础上封装的一套JPA应用框架,可使开发者用极简的代码即可实现对数据库的访问和操作。它提供了包括增删改查等在内的常用功能,且易于扩展!学习并使用 Spring Data JPA 可以极大提高开发效率!

      Spring Data JPA 让我们解脱了DAO层的操作,基本上所有CRUD都可以依赖于它来实现,在实际的工作工程中,推荐使用Spring Data JPA + ORM(如:hibernate)完成操作,这样在切换不同的ORM框架时提供了极大的方便,同时也使数据库层操作更加简单,方便解耦。

    1.2    Spring Data JPA的特性

      SpringData Jpa 极大简化了数据库访问层代码。 如何简化的呢? 使用了SpringDataJpa,我们的dao层中只需要写接口,就自动具有了增删改查、分页查询等方法。

    1.3    Spring Data JPA 与 JPA和hibernate之间的关系

      JPA是一套规范,内部是由接口抽象类组成的。hibernate是一套成熟的ORM框架,而且Hibernate实现了JPA规范,所以也可以称hibernate为JPA的一种实现方式,我们使用JPA的API编程,意味着站在更高的角度上看待问题(面向接口编程)

      Spring Data JPA是Spring提供的一套对JPA操作更加高级的封装,是在JPA规范下的专门用来进行数据持久化的解决方案。

    第2章     Spring Data JPA的快速入门

    2.1    需求说明

    Spring Data JPA完成客户的基本CRUD操作

    2.2    搭建Spring Data JPA的开发环境

    2.2.1     引入Spring Data JPA的坐标

      使用Spring Data JPA,需要整合Spring与Spring Data JPA,并且需要提供JPA的服务提供者hibernate,所以需要导入spring相关坐标,hibernate坐标,数据库驱动坐标等

      1     <properties>
      2         <spring.version>5.0.2.RELEASE</spring.version>
      3         <hibernate.version>5.0.7.Final</hibernate.version>
      4         <slf4j.version>1.6.6</slf4j.version>
      5         <log4j.version>1.2.12</log4j.version>
      6         <c3p0.version>0.9.1.2</c3p0.version>
      7         <mysql.version>5.1.6</mysql.version>
      8     </properties>
      9 
     10     <dependencies>
     11         <!-- junit单元测试 -->
     12         <dependency>
     13             <groupId>junit</groupId>
     14             <artifactId>junit</artifactId>
     15             <version>4.12</version>
     16             <scope>test</scope>
     17         </dependency>
     18 
     19         <!-- spring beg -->
     20         <dependency>
     21             <groupId>org.aspectj</groupId>
     22             <artifactId>aspectjweaver</artifactId>
     23             <version>1.6.8</version>
     24         </dependency>
     25 
     26         <dependency>
     27             <groupId>org.springframework</groupId>
     28             <artifactId>spring-aop</artifactId>
     29             <version>${spring.version}</version>
     30         </dependency>
     31 
     32         <dependency>
     33             <groupId>org.springframework</groupId>
     34             <artifactId>spring-context</artifactId>
     35             <version>${spring.version}</version>
     36         </dependency>
     37 
     38         <dependency>
     39             <groupId>org.springframework</groupId>
     40             <artifactId>spring-context-support</artifactId>
     41             <version>${spring.version}</version>
     42         </dependency>
     43 
     44         <!-- spring对orm框架的支持包-->
     45         <dependency>
     46             <groupId>org.springframework</groupId>
     47             <artifactId>spring-orm</artifactId>
     48             <version>${spring.version}</version>
     49         </dependency>
     50 
     51         <dependency>
     52             <groupId>org.springframework</groupId>
     53             <artifactId>spring-beans</artifactId>
     54             <version>${spring.version}</version>
     55         </dependency>
     56 
     57         <dependency>
     58             <groupId>org.springframework</groupId>
     59             <artifactId>spring-core</artifactId>
     60             <version>${spring.version}</version>
     61         </dependency>
     62 
     63         <!-- spring end -->
     64 
     65         <!-- hibernate beg -->
     66         <!--hiberate核心包-->
     67         <dependency>
     68             <groupId>org.hibernate</groupId>
     69             <artifactId>hibernate-core</artifactId>
     70             <version>${hibernate.version}</version>
     71         </dependency>
     72         <!--hibernate对jpa的实现-->
     73         <dependency>
     74             <groupId>org.hibernate</groupId>
     75             <artifactId>hibernate-entitymanager</artifactId>
     76             <version>${hibernate.version}</version>
     77         </dependency>
     78         <!--验证包-->
     79         <dependency>
     80             <groupId>org.hibernate</groupId>
     81             <artifactId>hibernate-validator</artifactId>
     82             <version>5.2.1.Final</version>
     83         </dependency>
     84         <!-- hibernate end -->
     85 
     86         <!-- c3p0 beg -->
     87         <dependency>
     88             <groupId>c3p0</groupId>
     89             <artifactId>c3p0</artifactId>
     90             <version>${c3p0.version}</version>
     91         </dependency>
     92         <!-- c3p0 end -->
     93 
     94         <!-- log end -->
     95         <dependency>
     96             <groupId>log4j</groupId>
     97             <artifactId>log4j</artifactId>
     98             <version>${log4j.version}</version>
     99         </dependency>
    100 
    101         <dependency>
    102             <groupId>org.slf4j</groupId>
    103             <artifactId>slf4j-api</artifactId>
    104             <version>${slf4j.version}</version>
    105         </dependency>
    106 
    107         <dependency>
    108             <groupId>org.slf4j</groupId>
    109             <artifactId>slf4j-log4j12</artifactId>
    110             <version>${slf4j.version}</version>
    111         </dependency>
    112         <!-- log end -->
    113 
    114 
    115         <dependency>
    116             <groupId>mysql</groupId>
    117             <artifactId>mysql-connector-java</artifactId>
    118             <version>${mysql.version}</version>
    119         </dependency>
    120 
    121         <!-- spring data jpa 的坐标-->
    122         <dependency>
    123             <groupId>org.springframework.data</groupId>
    124             <artifactId>spring-data-jpa</artifactId>
    125             <version>1.9.0.RELEASE</version>
    126         </dependency>
    127 
    128         <dependency>
    129             <groupId>org.springframework</groupId>
    130             <artifactId>spring-test</artifactId>
    131             <version>${spring.version}</version>
    132         </dependency>
    133 
    134         <!-- el beg 使用spring data jpa 必须引入 -->
    135         <dependency>
    136             <groupId>javax.el</groupId>
    137             <artifactId>javax.el-api</artifactId>
    138             <version>2.2.4</version>
    139         </dependency>
    140 
    141         <dependency>
    142             <groupId>org.glassfish.web</groupId>
    143             <artifactId>javax.el</artifactId>
    144             <version>2.2.4</version>
    145         </dependency>
    146         <!-- el end -->
    147 
    148         <dependency>
    149             <groupId>org.projectlombok</groupId>
    150             <artifactId>lombok</artifactId>
    151             <version>1.18.8</version>
    152             <scope>provided</scope>
    153         </dependency>
    154     </dependencies>

    2.2.2     整合Spring Data JPA与Spring

    applicationContext.xml

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
     4        xmlns:context="http://www.springframework.org/schema/context"
     5        xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
     6        xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:task="http://www.springframework.org/schema/task"
     7        xsi:schemaLocation="
     8         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
     9         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
    10         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    11         http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
    12         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
    13         http://www.springframework.org/schema/data/jpa
    14         http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
    15 
    16     <!--spring 和 spring data jpa的配置-->
    17 
    18     <!-- 1.创建entityManagerFactory对象交给spring容器管理-->
    19     <bean id="entityManagerFactoty" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    20         <property name="dataSource" ref="dataSource" />
    21         <!--配置的扫描的包(实体类所在的包) -->
    22         <property name="packagesToScan" value="cn.itcast.domain" />
    23         <!-- jpa的实现厂家 -->
    24         <property name="persistenceProvider">
    25             <bean class="org.hibernate.jpa.HibernatePersistenceProvider"/>
    26         </property>
    27 
    28         <!--jpa的供应商适配器 -->
    29         <property name="jpaVendorAdapter">
    30             <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
    31                 <!--配置是否自动创建数据库表 (false:不自动创建) -->
    32                 <property name="generateDdl" value="false" />
    33                 <!--指定数据库类型(MYSQL必须大写) -->
    34                 <property name="database" value="MYSQL" />
    35                 <!--数据库方言:支持的特有语法 -->
    36                 <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
    37                 <!--是否显示sql -->
    38                 <property name="showSql" value="true" />
    39             </bean>
    40         </property>
    41 
    42         <!--jpa的方言 :高级的特性 -->
    43         <property name="jpaDialect" >
    44             <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
    45         </property>
    46 
    47     </bean>
    48 
    49     <!--2.创建数据库连接池 -->
    50     <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    51         <property name="user" value="root"></property>
    52         <property name="password" value="root"></property>
    53         <property name="jdbcUrl" value="jdbc:mysql:///jpa" ></property>
    54         <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
    55     </bean>
    56 
    57     <!--3.整合spring dataJpa-->
    58     <jpa:repositories base-package="cn.itcast.dao" transaction-manager-ref="transactionManager"
    59                       entity-manager-factory-ref="entityManagerFactoty" ></jpa:repositories>
    60 
    61     <!--4.配置事务管理器 -->
    62     <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    63         <property name="entityManagerFactory" ref="entityManagerFactoty"></property>
    64     </bean>
    65 
    66     <!-- 4.txAdvice-->
    67     <tx:advice id="txAdvice" transaction-manager="transactionManager">
    68         <tx:attributes>
    69             <tx:method name="save*" propagation="REQUIRED"/>
    70             <tx:method name="insert*" propagation="REQUIRED"/>
    71             <tx:method name="update*" propagation="REQUIRED"/>
    72             <tx:method name="delete*" propagation="REQUIRED"/>
    73             <tx:method name="get*" read-only="true"/>
    74             <tx:method name="find*" read-only="true"/>
    75             <tx:method name="*" propagation="REQUIRED"/>
    76         </tx:attributes>
    77     </tx:advice>
    78 
    79     <!-- 5.aop-->
    80     <aop:config>
    81         <aop:pointcut id="pointcut" expression="execution(* cn.itcast.service.*.*(..))" />
    82         <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut" />
    83     </aop:config>
    84 
    85 
    86     <!--5.声明式事务 -->
    87 
    88     <!-- 6. 配置包扫描-->
    89     <context:component-scan base-package="cn.itcast" ></context:component-scan>
    90 </beans>

    带有声明式事务的配置:

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
     4     xmlns:context="http://www.springframework.org/schema/context"
     5     xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
     6     xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:task="http://www.springframework.org/schema/task"
     7     xsi:schemaLocation="
     8         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
     9         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
    10         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    11         http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
    12         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
    13         http://www.springframework.org/schema/data/jpa 
    14         http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
    15     
    16     <!-- 1.dataSource 配置数据库连接池-->
    17     <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    18         <property name="driverClass" value="com.mysql.jdbc.Driver" />
    19         <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/jpa" />
    20         <property name="user" value="root" />
    21         <property name="password" value="111111" />
    22     </bean>
    23     
    24     <!-- 2.配置entityManagerFactory -->
    25     <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    26         <property name="dataSource" ref="dataSource" />
    27         <property name="packagesToScan" value="cn.itcast.entity" />
    28         <property name="persistenceProvider">
    29             <bean class="org.hibernate.jpa.HibernatePersistenceProvider" />
    30         </property>
    31         <!--JPA的供应商适配器-->
    32         <property name="jpaVendorAdapter">
    33             <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
    34                 <property name="generateDdl" value="false" />
    35                 <property name="database" value="MYSQL" />
    36                 <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
    37                 <property name="showSql" value="true" />
    38             </bean>
    39         </property>
    40         <property name="jpaDialect">
    41             <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
    42         </property>
    43     </bean>
    44     
    45     
    46     <!-- 3.事务管理器-->
    47     <!-- JPA事务管理器  -->
    48     <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    49         <property name="entityManagerFactory" ref="entityManagerFactory" />
    50     </bean>
    51     
    52     <!-- 整合spring data jpa-->
    53     <jpa:repositories base-package="cn.itcast.dao"
    54         transaction-manager-ref="transactionManager"
    55         entity-manager-factory-ref="entityManagerFactory"></jpa:repositories>
    56         
    57     <!-- 4.txAdvice-->
    58     <tx:advice id="txAdvice" transaction-manager="transactionManager">
    59         <tx:attributes>
    60             <tx:method name="save*" propagation="REQUIRED"/>
    61             <tx:method name="insert*" propagation="REQUIRED"/>
    62             <tx:method name="update*" propagation="REQUIRED"/>
    63             <tx:method name="delete*" propagation="REQUIRED"/>
    64             <tx:method name="get*" read-only="true"/>
    65             <tx:method name="find*" read-only="true"/>
    66             <tx:method name="*" propagation="REQUIRED"/>
    67         </tx:attributes>
    68     </tx:advice>
    69     
    70     <!-- 5.aop-->
    71     <aop:config>
    72         <aop:pointcut id="pointcut" expression="execution(* cn.itcast.service.*.*(..))" />
    73         <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut" />
    74     </aop:config>
    75     
    76     <context:component-scan base-package="cn.itcast"></context:component-scan>
    77         
    78     <!--组装其它 配置文件-->
    79     
    80 </beans>

    2.2.3     使用JPA注解配置映射关系

    我们使用案例中的Customer实体类对象,已经配置好了映射关系

    Customer.java

     1 package cn.itcast.domain;
     2 
     3 import lombok.Getter;
     4 import lombok.Setter;
     5 import lombok.ToString;
     6 
     7 import javax.persistence.*;
     8 
     9 /**
    10  * 1.实体类和表的映射关系
    11  *      @Eitity
    12  *      @Table
    13  * 2.类中属性和表中字段的映射关系
    14  *      @Id
    15  *      @GeneratedValue
    16  *      @Column
    17  */
    18 /**
    19  *
    20  *      * 所有的注解都是使用JPA的规范提供的注解,
    21  *      * 所以在导入注解包的时候,一定要导入javax.persistence下的
    22  */
    23 @Entity
    24 @Table(name="cst_customer")
    25 @Getter
    26 @Setter
    27 @ToString
    28 public class Customer {
    29 
    30     @Id
    31     @GeneratedValue(strategy = GenerationType.IDENTITY)
    32     @Column(name = "cust_id")
    33     private Long custId;
    34     @Column(name = "cust_address")
    35     private String custAddress;
    36     @Column(name = "cust_industry")
    37     private String custIndustry;
    38     @Column(name = "cust_level")
    39     private String custLevel;
    40     @Column(name = "cust_name")
    41     private String custName;
    42     @Column(name = "cust_phone")
    43     private String custPhone;
    44     @Column(name = "cust_source")
    45     private String custSource;
    46 
    47 }

    2.3    使用Spring Data JPA完成需求

    2.3.1     编写符合Spring Data JPA规范的Dao层接口

    Spring Data JPA是spring提供的一款对于数据访问层(Dao层)的框架,使用Spring Data JPA,只需要按照框架的规范提供dao接口,不需要实现类就可以完成数据库的增删改查、分页查询等方法的定义,极大的简化了我们的开发过程。

    在Spring Data JPA中,对于定义符合规范的Dao层接口,我们只需要遵循以下几点就可以了:

      1.创建一个Dao层接口,并实现JpaRepositoryJpaSpecificationExecutor

      2.提供相应的泛型

    CustomerDao.java

      1 package cn.itcast.dao;
      2 
      3 import cn.itcast.domain.Customer;
      4 import org.springframework.data.jpa.repository.JpaRepository;
      5 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
      6 import org.springframework.data.jpa.repository.Modifying;
      7 import org.springframework.data.jpa.repository.Query;
      8 import org.springframework.data.repository.query.Param;
      9 
     10 import java.util.List;
     11 
     12 /**
     13  * 符合SpringDataJpa的dao层接口规范
     14  *      JpaRepository<操作的实体类类型,实体类中主键属性的类型>
     15  *          * 封装了基本CRUD操作
     16  *      JpaSpecificationExecutor<操作的实体类类型>
     17  *          * 封装了复杂查询(如分页)
     18  */
     19 //该写法已经具备了基本的增删改查
     20 public interface CustomerDao extends JpaRepository<Customer, Long>, JpaSpecificationExecutor<Customer> {
     21 
     22     /**
     23      * 案例:根据客户名称查询客户
     24      *      使用jpql的形式查询
     25      *  jpql:from Customer where custName = ?
     26      *
     27      *  配置jpql语句,使用的@Query注解
     28      */
     29     @Query(value="from Customer where custName = ?")
     30     public Customer findJpql(String custName);
     31 
     32     //返回多条
     33     @Query(value="from Customer where custName = ?")
     34     public List<Customer> findAllByCustName(String custName);
     35 
     36     /**
     37      * 案例:根据客户名称和客户id查询客户
     38      *      jpql: from Customer where custName = ? and custId = ?
     39      *
     40      *  对于多个占位符参数
     41      *      赋值的时候,默认的情况下,占位符的位置需要和方法参数中的位置保持一致
     42      *
     43      *  可以指定占位符参数的位置
     44      *      ? 索引的方式,指定此占位的取值来源
     45      */
     46     @Query(value = "from Customer where custName = ?2 and custId = ?1")
     47     public Customer findCustNameAndId(Long id,String name);
     48 
     49     //@Query(value = "from Customer where custName = ? and custId = ?")
     50     //public Customer findCustNameAndId(String name,Long id);
     51 
     52     //@Query(value = "from Customer where custName = :name and custId = :id")
     53     //public Customer findCustNameAndId(@Param("id") Long id, @Param("name") String name);
     54 
     55     /**
     56      * 使用jpql完成更新操作
     57      *      案例 : 根据id更新,客户的名称
     58      *          更新4号客户的名称,将名称改为“黑马程序员”
     59      *
     60      *  sql  :update cst_customer set cust_name = ? where cust_id = ?
     61      *  jpql : update Customer set custName = ? where custId = ?
     62      *
     63      *  @Query : 代表的是进行查询
     64      *      * 声明此方法是用来进行更新操作
     65      *  @Modifying
     66      *      * 当前执行的是一个更新操作
     67      *
     68      */
     69     @Query(value = " update Customer set custName = ?2 where custId = ?1 ")
     70     @Modifying
     71     public void updateCustomer(long custId,String custName);
     72 
     73     /**
     74      * 使用sql的形式查询:
     75      *     查询全部的客户
     76      *  sql : select * from cst_customer;
     77      *  Query : 配置sql查询
     78      *      value : sql语句
     79      *      nativeQuery : 查询方式
     80      *          true : 本地sql查询
     81      *          false:jpql查询
     82      *
     83      */
     84     //@Query(value = " select * from cst_customer" ,nativeQuery = true)
     85     @Query(value="select * from cst_customer where cust_name like ?1",nativeQuery = true)
     86     public List<Object [] > findSql(String name);
     87     //@Query(value="select * from cst_customer where cust_name like :name",nativeQuery = true)
     88     //public List<Object [] > findSql(@Param("name") String name);
     89 
     90 
     91     /**
     92      * 方法名的约定:
     93      *      findBy : 查询
     94      *            对象中的属性名(首字母大写) : 查询的条件
     95      *            CustName
     96      *            * 默认情况 : 使用 等于的方式查询
     97      *                  特殊的查询方式
     98      *
     99      *  findByCustName   --   根据客户名称查询
    100      *
    101      *  再springdataJpa的运行阶段
    102      *          会根据方法名称进行解析  findBy    from  xxx(实体类)
    103      *                                      属性名称      where  custName =
    104      *
    105      *      1.findBy  + 属性名称 (根据属性名称进行完成匹配的查询=)
    106      *      2.findBy  + 属性名称 + “查询方式(Like | isnull)”
    107      *          findByCustNameLike
    108      *      3.多条件查询
    109      *          findBy + 属性名 + “查询方式”   + “多条件的连接符(and|or)”  + 属性名 + “查询方式”
    110      */
    111     //public Customer findByCustName(String custName);
    112     public List<Customer> findByCustName(String custName);
    113 
    114     public List<Customer> findByCustNameLike(String custName);
    115 
    116     //使用客户名称模糊匹配和客户所属行业精准匹配的查询(参数顺序必须正确)
    117     public Customer findByCustNameLikeAndCustIndustry(String custName,String custIndustry);
    118 }

    2.3.2     完成基本CRUD操作

    完成了Spring Data JPA的环境搭建,并且编写了符合Spring Data JPA 规范的Dao层接口之后,就可以使用定义好的Dao层接口进行客户的基本CRUD操作

    CustomerDaoTest.java

      1 package cn.itcast.test;
      2 
      3 import cn.itcast.dao.CustomerDao;
      4 import cn.itcast.domain.Customer;
      5 import org.junit.Test;
      6 import org.junit.runner.RunWith;
      7 import org.springframework.beans.factory.annotation.Autowired;
      8 import org.springframework.test.context.ContextConfiguration;
      9 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
     10 import org.springframework.transaction.annotation.Transactional;
     11 
     12 import java.util.List;
     13 
     14 @RunWith(SpringJUnit4ClassRunner.class) //声明spring提供的单元测试环境
     15 @ContextConfiguration(locations = "classpath:applicationContext.xml")//指定spring容器的配置信息
     16 public class CustomerDaoTest {
     17 
     18     @Autowired
     19     private CustomerDao customerDao;
     20     /**
     21      * 根据id查询
     22      */
     23     @Test
     24     public void testFindOne() {
     25         Customer customer = customerDao.findOne(4l);
     26         System.out.println(customer);
     27     }
     28 
     29     /**
     30      * save : 保存或者更新
     31      *      根据传递的对象是否存在主键id,
     32      *      如果没有id主键属性:保存
     33      *      存在id主键属性,根据id查询数据,(查到数据后)更新数据
     34      */
     35     @Test
     36     public void testSave() {
     37         Customer customer  = new Customer();
     38         customer.setCustName("黑马程序员");
     39         customer.setCustLevel("vip");
     40         customer.setCustIndustry("it教育");
     41         customerDao.save(customer);
     42     }
     43 
     44     @Test
     45     public void testUpdate() {
     46         Customer customer  = new Customer();
     47         customer.setCustId(4l);
     48         customer.setCustName("黑马程序员很厉害");
     49         customerDao.save(customer);
     50     }
     51 
     52     /**
     53      * 删除
     54      */
     55     @Test
     56     public void testDelete () {
     57         customerDao.delete(3l);
     58     }
     59 
     60     /**
     61      * 查询所有
     62      */
     63     @Test
     64     public void testFindAll() {
     65         List<Customer> list = customerDao.findAll();
     66         for(Customer customer : list) {
     67             System.out.println(customer);
     68         }
     69     }
     70 
     71     /**
     72      * 测试统计查询:查询客户的总数量
     73      *      count:统计总条数
     74      */
     75     @Test
     76     public void testCount() {
     77         long count = customerDao.count();//查询全部的客户数量
     78         System.out.println(count);
     79     }
     80 
     81     /**
     82      * 测试:判断id为4的客户是否存在
     83      *      1. 可以查询以下id为4的客户
     84      *          如果值为空,代表不存在,如果不为空,代表存在
     85      *      2. 判断数据库中id为4的客户的数量
     86      *          如果数量为0,代表不存在,如果大于0,代表存在
     87      */
     88     @Test
     89     public void  testExists() {
     90         boolean exists = customerDao.exists(4l);
     91         System.out.println("id为4的客户 是否存在:"+exists);
     92     }
     93 
     94 
     95     /**
     96      * 根据id从数据库查询
     97      *      @Transactional : 保证getOne正常运行
     98      *
     99      *  findOne:
    100      *      em.find()           :立即加载
    101      *  getOne:
    102      *      em.getReference     :延迟加载
    103      *      * 返回的是一个客户的动态代理对象
    104      *      * 什么时候用,什么时候查询
    105      */
    106     @Test
    107     @Transactional
    108     public void  testGetOne() {
    109         Customer customer = customerDao.getOne(4l);
    110         System.out.println(customer);
    111     }
    112 }

    第3章     Spring Data JPA的内部原理剖析

    3.1    Spring Data JPA的常用接口分析

    在客户的案例中,我们发现在自定义的CustomerDao中,并没有提供任何方法就可以使用其中的很多方法,那么这些方法究竟是怎么来的呢?答案很简单,对于我们自定义的Dao接口,由于继承了JpaRepository和JpaSpecificationExecutor,所以我们可以使用这两个接口的所有方法。

    在使用Spring Data JPA时,一般实现JpaRepository和JpaSpecificationExecutor接口,这样就可以使用这些接口中定义的方法,但是这些方法都只是一些声明,没有具体的实现方式,那么在 Spring Data JPA中它又是怎么实现的呢?

    3.2    Spring Data JPA的实现过程

    通过对客户案例,以debug断点调试的方式,通过分析Spring Data JPA的原来来分析程序的执行过程

    我们以findOne方法为例进行分析

    • 代理子类的实现过程

    断点执行到方法上时,我们可以发现注入的customerDao对象,本质上是通过JdkDynamicAopProxy生成的一个代理对象

    • 代理对象中方法调用的分析

      当程序执行的时候,会通过JdkDynamicAopProxy的invoke方法,对customerDao对象生成动态代理对象。根据对Spring Data JPA介绍而知,要想进行findOne查询方法,最终还是会出现JPA规范的API完成操作,那么这些底层代码存在于何处呢?答案很简单,都隐藏在通过JdkDynamicAopProxy生成的动态代理对象当中,而这个动态代理对象就是SimpleJpaRepository

     通过SimpleJpaRepository的源码分析,定位到了findOne方法,在此方法中,返回em.find()的返回结果,那么em又是什么呢?

    带着问题继续查找em对象,我们发现em就是EntityManager对象,而他是JPA原生的实现方式,所以我们得到结论Spring Data JPA只是对标准JPA操作进行了进一步封装,简化了Dao层代码的开发

    3.3    Spring Data JPA完整的调用过程分析

    第4章     Spring Data JPA的查询方式

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

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

    • 继承JpaRepository后的方法列表

    •  继承JpaSpecificationExecutor的方法列表

    4.2    使用JPQL的方式查询

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

    @Query 注解的使用非常简单,只需在方法上面标注该注解,同时提供一个JPQL查询语句即可

    JpqlTest.java

     1 package cn.itcast.test;
     2 
     3 import cn.itcast.dao.CustomerDao;
     4 import cn.itcast.domain.Customer;
     5 import org.junit.Test;
     6 import org.junit.runner.RunWith;
     7 import org.springframework.beans.factory.annotation.Autowired;
     8 import org.springframework.test.annotation.Rollback;
     9 import org.springframework.test.context.ContextConfiguration;
    10 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    11 import org.springframework.transaction.annotation.Transactional;
    12 
    13 import java.util.Arrays;
    14 import java.util.List;
    15 
    16 @RunWith(SpringJUnit4ClassRunner.class) //声明spring提供的单元测试环境
    17 @ContextConfiguration(locations = "classpath:applicationContext.xml")//指定spring容器的配置信息
    18 public class JpqlTest {
    19 
    20     @Autowired
    21     private CustomerDao customerDao;
    22 
    23     @Test
    24     public void  testFindJPQL() {
    25         Customer customer = customerDao.findJpql("传智播客");
    26         System.out.println(customer);
    27     }
    28 
    29     @Test
    30     public void  testFindAllJPQL() {
    31         List<Customer> customerList = customerDao.findAllByCustName("传智播客");
    32         for(Customer c : customerList){
    33             System.out.println(c);
    34         }
    35         //System.out.println(customer);
    36     }
    37 
    38     @Test
    39     public void testFindCustNameAndId() {
    40         // Customer customer =  customerDao.findCustNameAndId("传智播客",1l);
    41         Customer customer =  customerDao.findCustNameAndId(1l,"传智播客");
    42         System.out.println(customer);
    43     }
    44 
    45     /**
    46      * 测试jpql的更新操作
    47      *  * springDataJpa中使用jpql完成 更新/删除操作
    48      *         * 需要手动添加事务的支持
    49      *         * 默认会执行结束之后,回滚事务
    50      *   @Rollback : 设置是否自动回滚
    51      *          false | true
    52      */
    53     @Test
    54     @Transactional //添加事务的支持
    55     @Rollback(value = false)
    56     public void testUpdateCustomer() {
    57         customerDao.updateCustomer(4l,"黑马程序员");
    58     }
    59 
    60     //测试sql查询
    61     @Test
    62     public void testFindSql() {
    63         List<Object[]> list = customerDao.findSql("传智播客%");
    64         for(Object [] obj : list) {
    65             System.out.println(Arrays.toString(obj));
    66         }
    67     }
    68 
    69     //测试方法命名规则的查询
    70     @Test
    71     public void testNaming() {
    72         //Customer customer = customerDao.findByCustName("传智播客");
    73         //System.out.println(customer);
    74         List<Customer> list = customerDao.findByCustName("传智播客");
    75         System.out.println(list);
    76     }
    77 
    78     //测试方法命名规则的查询
    79     @Test
    80     public void testFindByCustNameLike() {
    81         List<Customer> list = customerDao.findByCustNameLike("传智播客%");
    82         for (Customer customer : list) {
    83             System.out.println(customer);
    84         }
    85     }
    86 
    87     //测试方法命名规则的查询
    88     @Test
    89     public void testFindByCustNameLikeAndCustIndustry() {
    90         Customer customer = customerDao.findByCustNameLikeAndCustIndustry("传智播客1%", "it教育");
    91         System.out.println(customer);
    92     }
    93 
    94 
    95 }

    4.3    使用SQL语句查询

    Spring Data JPA同样也支持sql语句的查询,如下:

     1 /**
     2      * 使用sql的形式查询:
     3      *     查询全部的客户
     4      *  sql : select * from cst_customer;
     5      *  Query : 配置sql查询
     6      *      value : sql语句
     7      *      nativeQuery : 查询方式
     8      *          true : 本地sql查询
     9      *          false:jpql查询
    10      *
    11 */
    12 @Query(value="select * from cst_customer",nativeQuery=true)
    13     public void findSql();

    4.4    方法命名规则查询

    顾名思义,方法命名规则查询就是根据方法的名字,就能创建查询。只需要按照Spring Data JPA提供的方法命名规则定义方法的名称,就可以完成查询工作。Spring Data JPA在程序执行的时候会根据方法名称进行解析,并自动生成查询语句进行查询

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

        //方法命名方式查询(根据客户名称查询客户)
        public Customer findByCustName(String custName);

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

     

  • 相关阅读:
    怎么认Destsoon标签条件
    PHP将图片转base64格式函数
    修改Discuz!X系列开启防CC攻击,不影响搜索引擎收录
    discuz x3.2简化的搜索框代码
    让Discuz! X3.2 SEO标题里的“-”支持空格
    javascript的常用操作(二)
    Spring MVC中注解的简介
    Spring MVC + Thymeleaf
    Maven建立spring-web项目
    Spring @Autowired使用介绍
  • 原文地址:https://www.cnblogs.com/116970u/p/11606799.html
Copyright © 2011-2022 走看看