zoukankan      html  css  js  c++  java
  • JPA02 -- Spring Data JPA01

    关于JPA总共写了三篇内容,下面附上链接:

    JPA01:https://www.cnblogs.com/buwei/p/9979794.html
    JPA02:https://www.cnblogs.com/buwei/p/9985287.html
    JPA03:https://www.cnblogs.com/buwei/p/9985941.html

    一、Spring Data JPA的概述

      1.1 Spring Data JPA概述

      Spring Data JPA是Spring基于ORM框架、JPA规范的基础上封装的一套JPA应用框架。他提供了包括增删改查在内的常用功能,且易于扩展。

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

      1.2 Spring Data JPA的特性

      使用Spring Data JPA,我们的DAO层只需要写接口,就自动具有了增删改查、分页查询等方法。

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

      JPA是一套规范,内部是由接口和抽象内组成,Hibernate是一套乘数的ORM框架,而且Hibernate实现了JPA规范,所以也可以称Hibernate是JPA的一种实现方式,我们使用JPA的API编程,是一种面向接口编程的思想。

    二、Spring Data JPA的快速入门

      2.1 需求说明

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

      2.2 搭建Spring Data JPA的开发环境

      1. 引入Spring Data JPA的坐标

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

      1     <properties>
      2         <spring.version>4.2.4.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     <dependencies>
     10         <!-- junit单元测试 -->
     11         <dependency>
     12             <groupId>junit</groupId>
     13             <artifactId>junit</artifactId>
     14             <version>4.9</version>
     15             <scope>test</scope>
     16         </dependency>
     17 
     18         <!-- spring beg -->
     19         <dependency>
     20             <groupId>org.aspectj</groupId>
     21             <artifactId>aspectjweaver</artifactId>
     22             <version>1.6.8</version>
     23         </dependency>
     24 
     25         <dependency>
     26             <groupId>org.springframework</groupId>
     27             <artifactId>spring-aop</artifactId>
     28             <version>${spring.version}</version>
     29         </dependency>
     30 
     31         <dependency>
     32             <groupId>org.springframework</groupId>
     33             <artifactId>spring-context</artifactId>
     34             <version>${spring.version}</version>
     35         </dependency>
     36 
     37         <dependency>
     38             <groupId>org.springframework</groupId>
     39             <artifactId>spring-context-support</artifactId>
     40             <version>${spring.version}</version>
     41         </dependency>
     42 
     43         <dependency>
     44             <groupId>org.springframework</groupId>
     45             <artifactId>spring-orm</artifactId>
     46             <version>${spring.version}</version>
     47         </dependency>
     48 
     49         <dependency>
     50             <groupId>org.springframework</groupId>
     51             <artifactId>spring-beans</artifactId>
     52             <version>${spring.version}</version>
     53         </dependency>
     54 
     55         <dependency>
     56             <groupId>org.springframework</groupId>
     57             <artifactId>spring-core</artifactId>
     58             <version>${spring.version}</version>
     59         </dependency>
     60         <!-- spring end -->
     61 
     62         <!-- hibernate beg -->
     63         <dependency>
     64             <groupId>org.hibernate</groupId>
     65             <artifactId>hibernate-core</artifactId>
     66             <version>${hibernate.version}</version>
     67         </dependency>
     68         <dependency>
     69             <groupId>org.hibernate</groupId>
     70             <artifactId>hibernate-entitymanager</artifactId>
     71             <version>${hibernate.version}</version>
     72         </dependency>
     73         <dependency>
     74             <groupId>org.hibernate</groupId>
     75             <artifactId>hibernate-validator</artifactId>
     76             <version>5.2.1.Final</version>
     77         </dependency>
     78         <!-- hibernate end -->
     79 
     80         <!-- c3p0 beg -->
     81         <dependency>
     82             <groupId>c3p0</groupId>
     83             <artifactId>c3p0</artifactId>
     84             <version>${c3p0.version}</version>
     85         </dependency>
     86         <!-- c3p0 end -->
     87 
     88         <!-- log end -->
     89         <dependency>
     90             <groupId>log4j</groupId>
     91             <artifactId>log4j</artifactId>
     92             <version>${log4j.version}</version>
     93         </dependency>
     94 
     95         <dependency>
     96             <groupId>org.slf4j</groupId>
     97             <artifactId>slf4j-api</artifactId>
     98             <version>${slf4j.version}</version>
     99         </dependency>
    100 
    101         <dependency>
    102             <groupId>org.slf4j</groupId>
    103             <artifactId>slf4j-log4j12</artifactId>
    104             <version>${slf4j.version}</version>
    105         </dependency>
    106         <!-- log end -->
    107 
    108 
    109         <dependency>
    110             <groupId>mysql</groupId>
    111             <artifactId>mysql-connector-java</artifactId>
    112             <version>${mysql.version}</version>
    113         </dependency>
    114 
    115         <dependency>
    116             <groupId>org.springframework.data</groupId>
    117             <artifactId>spring-data-jpa</artifactId>
    118             <version>1.9.0.RELEASE</version>
    119         </dependency>
    120 
    121         <dependency>
    122             <groupId>org.springframework</groupId>
    123             <artifactId>spring-test</artifactId>
    124             <version>4.2.4.RELEASE</version>
    125         </dependency>
    126 
    127         <!-- el beg 使用spring data jpa 必须引入 -->
    128         <dependency>
    129             <groupId>javax.el</groupId>
    130             <artifactId>javax.el-api</artifactId>
    131             <version>2.2.4</version>
    132         </dependency>
    133 
    134         <dependency>
    135             <groupId>org.glassfish.web</groupId>
    136             <artifactId>javax.el</artifactId>
    137             <version>2.2.4</version>
    138         </dependency>
    139         <!-- el end -->
    140     </dependencies>

      2. 整合Spring Data JPA与JPA

      创建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     <!-- 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/spring_jpa" />
     20         <property name="user" value="root" />
     21         <property name="password" value="root" />
     22     </bean>
     23 
     24     <!-- spring和spring data jpa的配置 -->
     25     <!-- 2.配置entityManagerFactory对象交个spring容器管理 -->
     26     <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
     27         <property name="dataSource" ref="dataSource" />
     28         <!-- 配置要扫描的包(实体类所在的包)-->
     29         <property name="packagesToScan" value="com.buwei.domain" />
     30         <!-- jpa的实现厂商 -->
     31         <property name="persistenceProvider">
     32             <bean class="org.hibernate.jpa.HibernatePersistenceProvider" />
     33         </property>
     34         <!--JPA的供应商适配器-->
     35         <property name="jpaVendorAdapter">
     36             <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
     37                 <!-- 配置是否自动创建数据库表 -->
     38                 <property name="generateDdl" value="false" />
     39                 <!-- 指定数据库类型 -->
     40                 <property name="database" value="MYSQL" />
     41                 <!-- 数据库方言,支持的特有语法 -->
     42                 <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
     43                 <!-- 是否显示sql-->
     44                 <property name="showSql" value="true" />
     45             </bean>
     46         </property>
     47 
     48         <!-- jpa的方言:高级特性 -->
     49         <property name="jpaDialect">
     50             <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
     51         </property>
     52 
     53         <!--注入jpa的配置信息
     54             加载jpa的基本配置信息和jpa实现方式(hibernate)的配置信息
     55             hibernate.hbm2ddl.auto : 自动创建数据库表
     56                 create : 每次都会重新创建数据库表
     57                 update:有表不会重新创建,没有表会重新创建表
     58                 none:不创建表
     59         -->
     60         <property name="jpaProperties" >
     61             <props>
     62                 <prop key="hibernate.hbm2ddl.auto">update</prop>
     63             </props>
     64         </property>
     65 
     66     </bean>
     67     <!-- 3.事务管理器-->
     68     <!-- JPA事务管理器  -->
     69     <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
     70         <property name="entityManagerFactory" ref="entityManagerFactory" />
     71     </bean>
     72 
     73     <!-- 整合spring data jpa-->
     74     <jpa:repositories base-package="com.buwei.mapper" transaction-manager-ref="transactionManager"
     75                       entity-manager-factory-ref="entityManagerFactory"></jpa:repositories>
     76 
     77     <!-- 4.txAdvice-->
     78     <tx:advice id="txAdvice" transaction-manager="transactionManager">
     79         <tx:attributes>
     80             <tx:method name="save*" propagation="REQUIRED"/>
     81             <tx:method name="insert*" propagation="REQUIRED"/>
     82             <tx:method name="update*" propagation="REQUIRED"/>
     83             <tx:method name="delete*" propagation="REQUIRED"/>
     84             <tx:method name="get*" read-only="true"/>
     85             <tx:method name="find*" read-only="true"/>
     86             <tx:method name="*" propagation="REQUIRED"/>
     87         </tx:attributes>
     88     </tx:advice>
     89 
     90     <!-- 5.aop-->
     91     <aop:config>
     92         <aop:pointcut id="pointcut" expression="execution(* com.buwei.service.*.*(..))" />
     93         <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut" />
     94     </aop:config>
     95 
     96     <!-- 6.配置包扫描 -->
     97     <context:component-scan base-package="com.buwei"></context:component-scan>
     98 
     99     <!--组装其它 配置文件-->
    100 
    101 </beans>

      3. 使用JPA注解配置映射关系

     1 /**
     2  * 所有的注解都是使用JPA的规范提供的注解,
     3  * 所以在导入注解包的时候,一定要导入javax.persistence下的
     4  */
     5 @Entity //声明实体类
     6 @Table(name="cst_customer") //建立实体类和表的映射关系
     7 public class Customer implements Serializable {
     8     @Id//声明当前私有属性为主键
     9     @GeneratedValue(strategy= GenerationType.IDENTITY) //配置主键的生成策略
    10     @Column(name="cust_id") //指定和表中cust_id字段的映射关系
    11     private Long custId;
    12 
    13     @Column(name="cust_name") //指定和表中cust_name字段的映射关系
    14     private String custName;
    15 
    16     @Column(name="cust_source")//指定和表中cust_source字段的映射关系
    17     private String custSource;
    18 
    19     @Column(name="cust_industry")//指定和表中cust_industry字段的映射关系
    20     private String custIndustry;
    21 
    22     @Column(name="cust_level")//指定和表中cust_level字段的映射关系
    23     private String custLevel;
    24 
    25     @Column(name="cust_address")//指定和表中cust_address字段的映射关系
    26     private String custAddress;
    27 
    28     @Column(name="cust_phone")//指定和表中cust_phone字段的映射关系
    29     private String custPhone;
    30 
    31     //省略getter和setter方法
    32 }

      2.3 使用Spring Data JPA完成需求

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

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

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

      1.创建一个DAO层接口,并实现JapReponsitory和JpaSpecificationExecutor

      2.提供相应的泛型

    1 /**
    2  * JpaRepository<实体类类型,主键类型>:用来完成基本CRUD操作
    3  * JpaSpecificationExecutor<实体类类型>:用于复杂查询(分页等查询操作)
    4  */
    5 public interface CustomerDAO extends
    6         JpaRepository<Customer, Long>,JpaSpecificationExecutor<Customer> {
    7 
    8 }

      2.编写测试类完成基本CRUD操作

     1 @RunWith(SpringJUnit4ClassRunner.class)
     2 @ContextConfiguration(locations = "classpath:applicationContext.xml")
     3 public class CustomerDaoTest {
     4     @Autowired
     5     private CustomerDAO customerDao;
     6 
     7     /**
     8      * 保存:调用save(obj)方法
     9      * 对于save方法,当执行此方法的对象中id无值,及为新增操作
    10      */
    11     @Test
    12     public void testInsert(){
    13         // 创建一个新的用户
    14         Customer customer = new Customer();
    15         customer.setCustName("不为");
    16         // 新增
    17         customerDao.save(customer);
    18     }
    19 
    20     /**
    21      * 根据ID查询:调用findOne方法
    22      */
    23     @Test
    24     public void testFindById(){
    25         Customer customer = customerDao.findOne(1L);
    26         System.out.println(customer);
    27     }
    28 
    29     /**
    30      * 修改:调用save(obj)方法
    31      * 对于save方法,当执行此方法的对象中id有值,及为更新操作
    32      */
    33     @Test
    34     public void testUpdate(){
    35         // 查询id为1的用户
    36         Customer customer = customerDao.findOne(1L);
    37         // 修改客户名称
    38         customer.setCustName("不为——为");
    39         // 更新
    40         customerDao.save(customer);
    41     }
    42 
    43     /**
    44      * 根据id删除:调用delete(id)方法
    45      */
    46     @Test
    47     public void testDelete(){
    48         customerDao.delete(1L);
    49     }
    50 }

    三、Spring Data JPA的内部原理剖析

      3.1 Spring Data JPA的常用接口分析

      在上面的案例中,我们发现对于customerDao,我们并没有提供任何方法就可以调用增删改查方法,是因为接口继承了JpaReponsitory和JpaSpecificationExecutor,我们使用的方法就是上面两个接口中的方法。

      3.2 Spring Data JPA的实现过程

      等理解清楚了再来作补充。。。。也欢迎大家留言。。。。

    四、Spring Data JPA的查询方式

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

      上面用到的方法直接使用了JpaReponsitory与JpaSpecificationExecutor接口中的方法,源码如下:

     1 @NoRepositoryBean
     2 public interface JpaRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID> {
     3     List<T> findAll();
     4 
     5     List<T> findAll(Sort var1);
     6 
     7     List<T> findAll(Iterable<ID> var1);
     8 
     9     <S extends T> List<S> save(Iterable<S> var1);
    10 
    11     void flush();
    12 
    13     <S extends T> S saveAndFlush(S var1);
    14 
    15     void deleteInBatch(Iterable<T> var1);
    16 
    17     void deleteAllInBatch();
    18 
    19     T getOne(ID var1);
    20 }
     1 public interface JpaSpecificationExecutor<T> {
     2     T findOne(Specification<T> var1);
     3 
     4     List<T> findAll(Specification<T> var1);
     5 
     6     Page<T> findAll(Specification<T> var1, Pageable var2);
     7 
     8     List<T> findAll(Specification<T> var1, Sort var2);
     9 
    10     long count(Specification<T> var1);
    11 }

      4.2 使用JPQL的方式查询

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

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

     1 public interface CustomerDAO extends
     2         JpaRepository<Customer, Long>,JpaSpecificationExecutor<Customer> {
     3 
     4     /**
     5      *  @Query 使用jpql的方式查询。
     6      */
     7     @Query(value="from Customer")
     8     public List<Customer> findAllCustomer();
     9 
    10     /**
    11      * @Query 使用jpql的方式查询。?1代表参数的占位符,其中1对应方法中的参数索引
    12      * @param custName
    13      * @return
    14      */
    15     @Query(value="from Customer where custName = ?1")
    16     public Customer findCustomer(String custName);
    17 
    18     /**
    19      * @Modifying是标识该操作为修改查询操作
    20      * @param custName
    21      * @param custId
    22      */
    23     @Query(value="update Customer set custName = ?1 where custId = ?2")
    24     @Modifying
    25     public void updateCustomer(String custName,Long custId);
    26 }

      4.3 使用SQL语句查询

      使用SQL语句查询如下:

    1     /**
    2      * nativeQuery : 标识使用本地sql的方式查询
    3      */
    4     @Query(value="select * from cst_customer",nativeQuery=true)
    5     public void findBySql();

      4.4 方法命名规则查询

      按照Spring Data JPA定义的规则,查询方法一FindBy开头,设计条件查询时,条件的属性用条件关键词连接,方法名命名需符合小驼峰规则,框架会自动对方法名进行解析。

    1     /**
    2      * 方法命名方式查询(根据客户名称查询客户)
    3      * @param custName
    4      * @return
    5      */
    6     public Customer findByCustName(String custName);

      对应的具体的关键字适用方法和对应的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)

    如发现有错误欢迎指正,欢迎交流,接受反驳。 -- by不为 :)
  • 相关阅读:
    解决sqlite3 dos下显示中文乱码
    毕业两年
    成就感
    重构html的下拉框select
    ie6 select不兼容处理(转)
    全选删除确认改进
    GridView移动行变色
    gridview固定列的宽度并且能换行
    分页控件结合分页存储过程
    网页滚动条向下拉动奇慢的原因
  • 原文地址:https://www.cnblogs.com/buwei/p/9985287.html
Copyright © 2011-2022 走看看