学习Spring Data Jpa

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习Spring Data Jpa相关的知识,希望对你有一定的参考价值。

  首先,抛开Spring,先来谈谈JPA。

       1.JPA是什么?

  JPA全称Java Persistence API.JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。 

    说到底还是一个ORM框架,不过是Sun为了希望整合所有的ORM框架而推出的规范,总的来说没有什么大的区别。依旧是是开发者从复杂的SQL与JDBC中脱离出来。

        2.实际中使用JPA

   首先在数据库中建库与表,mysql中脚本如下

 1 CREATE DATABASE jpa;
 2 USE jpa;
 3 CREATE TABLE `user` (
 4   `id` bigint(20) NOT NULL AUTO_INCREMENT,
 5   `firstName` varchar(45) NOT NULL,
 6   `phoneNo` varchar(45) NOT NULL,
 7   `lastName` varchar(45) NOT NULL,
 8   `birthday` date NOT NULL,
 9   PRIMARY KEY (`id`),
10   UNIQUE KEY `id_UNIQUE` (`id`),
11   UNIQUE KEY `phoneNo_UNIQUE` (`phoneNo`)
12 ) ENGINE=InnoDB DEFAULT CHARSET=UTF-8;

 

  JPA标准配置文件,使用Hibernate实现 含每行注释(注意 一定要放置在src下的META-INF目录下,十分坑爹!!)

技术分享
 1 <?xml version="1.0" encoding="UTF-8"?>  
 2   
 3 <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" 
 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 5 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
 6   
 7 <!--    
 8      Name属性用于定义持久化单元的名字 (name必选,空值也合法);   
 9      transaction-type 指定事务类型(可选)    
10 -->  
11 <persistence-unit name="TestJPAUnit" transaction-type="RESOURCE_LOCAL">  
12   
13    <!-- 描述信息.(可选)
14    <description> </description>  
15    -->  
16    <!-- javax.persistence.PersistenceProvider接口的一个实现类(可选)  
17    <provider>   </provider>  
18   --> 
19    <!-- Jta-data-source和 non-jta-data-source用于分别指定持久化提供商使用的JTA和/或non-JTA数据源的全局JNDI名称(可选)   
20    <jta-data-source>java:/MySqlDS</jta-data-source>  
21    <non-jta-data-source> </non-jta-data-source>  
22   -->
23    <!-- 声明orm.xml所在位置.(可选) 
24    <mapping-file>product.xml</mapping-file>  
25    --> 
26    <!-- 以包含persistence.xml的jar文件为基准的相对路径,添加额外的jar文件.(可选)   
27    <jar-file>../lib/model.jar</jar-file>  
28   -->
29    <!-- 显式列出实体类,在Java SE 环境中应该显式列出.(可选) 
30    <class>com.domain.User</class>  
31    <class>com.domain.Product</class>  
32   -->  
33    <!-- 声明是否扫描jar文件中标注了@Enity类加入到上下文.若不扫描,则如下:(可选)  
34    <exclude-unlisted-classes/>  
35       --> 
36    <!--   厂商专有属性(可选)   -->  
37    <properties>  
38     <!-- hibernate.hbm2ddl.auto= create-drop / create / update -->  
39       <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />  
40     <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />  
41     <property name="hibernate.connection.username" value="remote" />  
42     <property name="hibernate.connection.password" value="feiyue" />  
43     <property name="hibernate.connection.url" value="jdbc:mysql://192.168.182.131:3306/jpa" />  
44     <property name="hibernate.max_fetch_depth" value="3" />  
45     <property name="hibernate.show_sql" value="true" />  
46     <property name="hibernate.hbm2ddl.auto" value="update"/>  
47    </properties>  
48   
49 </persistence-unit>  
50   
51 </persistence>
View Code

  使用Maven搭建一个测试环境,Maven的使用在这里不再赘述,这里显示所依赖的jar包

技术分享
<dependencies>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>4.1.9.Final</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>4.1.9.Final</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.25</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.2</version>
        </dependency>
    </dependencies>
View Code

  搭建一个测试项目 如图

  技术分享

  Entity 实体类 User.java

技术分享
 1 package com.demo.bean;
 2 
 3 // Generated 2016-3-22 17:50:11 by Hibernate Tools 4.0.0
 4 
 5 import java.util.Date;
 6 import javax.persistence.Column;
 7 import javax.persistence.Entity;
 8 import javax.persistence.GeneratedValue;
 9 import static javax.persistence.GenerationType.IDENTITY;
10 import javax.persistence.Id;
11 import javax.persistence.Table;
12 import javax.persistence.Temporal;
13 import javax.persistence.TemporalType;
14 import javax.persistence.UniqueConstraint;
15 
16 /**
17  * User generated by hbm2java
18  */
19 @Entity
20 @Table(name = "user", catalog = "jpa", uniqueConstraints = @UniqueConstraint(columnNames = "phoneNo"))
21 public class User implements java.io.Serializable {
22 
23     /**
24      * 
25      */
26     private static final long serialVersionUID = -2126972038126149900L;
27     private Long id;
28     private String firstName;
29     private String phoneNo;
30     private String lastName;
31     private Date birthday;
32 
33     public User() {
34     }
35 
36     public User(String firstName, String phoneNo, String lastName, Date birthday) {
37         this.firstName = firstName;
38         this.phoneNo = phoneNo;
39         this.lastName = lastName;
40         this.birthday = birthday;
41     }
42 
43     @Id
44     @GeneratedValue(strategy = IDENTITY)
45     @Column(name = "id", unique = true, nullable = false)
46     public Long getId() {
47         return this.id;
48     }
49 
50     public void setId(Long id) {
51         this.id = id;
52     }
53 
54     @Column(name = "firstName", nullable = false, length = 45)
55     public String getFirstName() {
56         return this.firstName;
57     }
58 
59     public void setFirstName(String firstName) {
60         this.firstName = firstName;
61     }
62 
63     @Column(name = "phoneNo", unique = true, nullable = false, length = 45)
64     public String getPhoneNo() {
65         return this.phoneNo;
66     }
67 
68     public void setPhoneNo(String phoneNo) {
69         this.phoneNo = phoneNo;
70     }
71 
72     @Column(name = "lastName", nullable = false, length = 45)
73     public String getLastName() {
74         return this.lastName;
75     }
76 
77     public void setLastName(String lastName) {
78         this.lastName = lastName;
79     }
80 
81     @Temporal(TemporalType.DATE)
82     @Column(name = "birthday", nullable = false, length = 10)
83     public Date getBirthday() {
84         return this.birthday;
85     }
86 
87     public void setBirthday(Date birthday) {
88         this.birthday = birthday;
89     }
90     
91     @Override
92     public String toString(){
93         return "User:"+
94                 "Id:"+id+" Name:"+firstName+" "+lastName+"";
95     }
96 
97 }
View Code

  Junit4 测试客户端,这里只简单的操作了保存与创建简单的HQL查询。JPATest.java

技术分享
 1 package com.demo.client;
 2 
 3 import java.util.Date;
 4 import java.util.List;
 5 
 6 import javax.persistence.EntityManager;
 7 import javax.persistence.EntityManagerFactory;
 8 import javax.persistence.Persistence;
 9 
10 import org.junit.Test;
11 
12 import com.demo.bean.User;
13 
14 public class JPATest {
15 
16     @Test
17     public void testSave(){
18         EntityManagerFactory factory = Persistence.createEntityManagerFactory("TestJPAUnit");  
19         EntityManager em = factory.createEntityManager();  
20         em.getTransaction().begin();  
21         User user = new User(); //user为new状态  
22         user.setBirthday(new Date());
23         user.setFirstName("Khalid");
24         user.setLastName("Khalid");
25         user.setPhoneNo("+8618888888889");
26         em.persist(user);//持久化user实例
27         em.getTransaction().commit();//提交事务  
28         em.close();  
29         factory.close();  
30     }
31     
32     @Test
33     public void testQuery(){
34         EntityManagerFactory factory = Persistence.createEntityManagerFactory("TestJPAUnit");  
35         EntityManager em = factory.createEntityManager();  
36         @SuppressWarnings("unchecked")
37         List<User> user=em.createQuery("from User").getResultList();
38         System.out.println(user);
39     }
40 }
View Code

   运行客户端就可以啦~~其实并没有什么特别的- -。

       3.Spring对JPA的支持

  前人总结的很好,我就不在赘述了

   Spring 框架对 JPA 提供的支持主要体现在如下几个方面:

  • 首先,它使得 JPA 配置变得更加灵活。JPA 规范要求,配置文件必须命名为 persistence.xml,并存在于类路径下的 META-INF 目录中。该文件通常包含了初始化 JPA 引擎所需的全部信息。Spring 提供的 LocalContainerEntityManagerFactoryBean 提供了非常灵活的配置,persistence.xml 中的信息都可以在此以属性注入的方式提供。

  • 其次,Spring 实现了部分在 EJB 容器环境下才具有的功能,比如对 @PersistenceContext、@PersistenceUnit 的容器注入支持。
  • 第三,也是最具意义的,Spring 将 EntityManager 的创建与销毁、事务管理等代码抽取出来,并由其统一管理,开发者不需要关心这些,业务方法中只剩下操作领域对象的代码,事务管理和 EntityManager 创建、销毁的代码都不再需要开发者关心了。

       4.使用SpringDataJPA 让一切变得最为简单

    使用Spring Data JPA框架,它会帮助你简化Spring唯一没有控制到的DAO层,甚至让你完全不用编写DAO层繁琐的业务逻辑,你仅仅需要做的只有声明接口。

    不多说直接上代码!!!

    首先依旧是建库与表    

技术分享
 1   CREATE DATABASE sdjpa;
 2   USE sdjpa;
 3   CREATE TABLE `user` (
 4     `id` bigint(20) NOT NULL AUTO_INCREMENT,
 5     `firstName` varchar(45) NOT NULL,
 6     `phoneNo` varchar(45) NOT NULL,
 7     `lastName` varchar(45) NOT NULL,
 8     `birthday` date NOT NULL,
 9       PRIMARY KEY (`id`),
10       UNIQUE KEY `id_UNIQUE` (`id`),
11       UNIQUE KEY `phoneNo_UNIQUE` (`phoneNo`)
12  ) ENGINE=InnoDB DEFAULT CHARSET=UTF-8;
View Code

   既然是Spring,applicationContext.xml内有关SpringDataJPA的相关配置    

技术分享
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3        xmlns:tx="http://www.springframework.org/schema/tx"
 4        xmlns:context="http://www.springframework.org/schema/context"
 5        xmlns:jpa="http://www.springframework.org/schema/data/jpa"
 6        xmlns:task="http://www.springframework.org/schema/task"
 7        xmlns:aop="http://www.springframework.org/schema/aop"
 8        xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
 9         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
10         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
11         http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd
12         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
13         http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"
14        default-lazy-init="true">
15 
16     
17     <!-- 如果spring用了jpa,并且类型为LocalContainerEntityManagerFactoryBean,则组件注册在此配置文件出现即可,其余配置文件可忽略
18            使用component来替代annotation 自动注册bean, 并保证@Required、@Autowired的属性被注入\ -->
19     <context:component-scan base-package="com.**.client,com.demo.dao"/>
20 
21     <!-- 数据源-->
22     <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
23         <property name="driverClassName" value="com.mysql.jdbc.Driver" />
24         <property name="url" value="jdbc:mysql://192.168.182.131/sdjpa"/>
25         <property name="username" value="root" />
26         <property name="password" value="feiyue" />
27     </bean>
28     
29     <!-- Hibernate对Jpa的实现 -->
30     <bean id="hibernateJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
31 
32     <!-- 定义实体管理器工厂
33          Jpa配置   LocalContainerEntityManagerFactoryBean这个选项Spring扮演了容器的角色。完全掌管JPA -->
34     <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
35            <!-- 指定数据源 -->
36         <property name="dataSource" ref="dataSource"/>
37         <!-- 指定Jpa持久化实现厂商类,这里以Hibernate为例 -->
38         <property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter"/>
39         <!-- 指定Entity实体类包路径 -->
40         <property name="packagesToScan" >
41             <array>
42                 <value>com.**.bean</value>
43             </array>
44         </property>
45         <!-- 指定JPA属性;如Hibernate中指定是否显示SQL的是否显示、方言等 -->
46         <property name="jpaProperties">
47             <props>
48                 <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
49                  <!--  EJB3规范的命名实现 例如 firstName 会被映射为 first_name 建议取消
50                   <prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
51                     -->
52                 <prop key="hibernate.show_sql">true</prop>
53                 <prop key="hibernate.format_sql">true</prop>
54                 <!-- 也可以配置为update 自动生成表 我这里在数据库已经建好了 就设置为validate-->
55                 <prop key="hibernate.hbm2ddl.auto">update</prop>
56             </props>
57         </property>
58     </bean>
59     
60     <!-- 重要配置:启用扫描并自动创建代理的功能  -->
61     <jpa:repositories base-package="com.**.dao" entity-manager-factory-ref="entityManagerFactory" transaction-manager-ref="transactionManager"/> 
62     
63 
64 
65     <!-- Jpa 事务管理器  -->
66     <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
67         <property name="entityManagerFactory" ref="entityManagerFactory"/>
68     </bean>
69 
70     <!-- 开启注解事务 -->
71     <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
72 
73     
74     <!-- 启动对@AspectJ(面向切面)注解的支持 --> 
75     <aop:aspectj-autoproxy />
76     
77 </beans>
View Code

  依旧是Maven,这次的依赖库  

技术分享
  1 <dependencies>
  2         <dependency>
  3             <groupId>log4j</groupId>
  4             <artifactId>log4j</artifactId>
  5             <version>1.2.17</version>
  6         </dependency>
  7 
  8         <dependency>
  9             <groupId>com.fasterxml.jackson.core</groupId>
 10             <artifactId>jackson-databind</artifactId>
 11             <version>2.4.5</version>
 12         </dependency>
 13 
 14         <dependency>
 15             <groupId>com.fasterxml.jackson.core</groupId>
 16             <artifactId>jackson-annotations</artifactId>
 17             <version>2.4.5</version>
 18         </dependency>

以上是关于学习Spring Data Jpa的主要内容,如果未能解决你的问题,请参考以下文章

Spring Data 系列学习Spring Data JPA 基础查询

学习Spring-Data-Jpa(二十)---@EnableJpaRepositories

Spring Data JPA入门

spring-data-jpa

Spring Boot学习进阶笔记-Spring-data-jpa

学习-spring data jpa