# SpringDataJPA **Repository Path**: jmstart/SpringDataJPA ## Basic Information - **Project Name**: SpringDataJPA - **Description**: Spring Data JPA简介 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-05-30 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # SpringData JPA简介 一. ORM介绍 1.1 ORM概述 ORM(Object-Relational Mapping)表示对象关系映射。在面向对象的软件开发中,通过ORM,就可以把对象映射到关系型数据库中。 只要有一套程序能够做到建立对象与数据库的关联,操作对象就可以直接操作数据库数据,就可以说这套程序实现了ORM对象关系映射 简单的说:ORM就是建立实体类和数据库表之间的关系,从而达到操作实体类就相当于操作数据库表的目的。 1.2 为什么使用ORM 当实现一个应用程序时(不使用O/R Mapping),我们可能会写特别多数据访问层的代码,从数据库保存数据、修改数据、删除数据, 而这些代码都是重复的。而使用ORM则会大大减少重复性代码。对象关系映射(Object Relational Mapping,简称ORM), 主要实现程序对象到关系数据库数据的映射。 1.3 常见ORM框架 Mybatis(ibatis)、Hibernate、Jpa 二. Hibernate与JPA的概述 2.1 Hibernate概述 Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系, 是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 2.2 JPA概述 JPA的全称是Java Persistence API, 即Java持久化API,是SUN公司推出的一套基于ORM的规范,内部是由一系列的接口和抽象类构成。 JPA通过JDK 5.0注解描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。 2.3 JPA的优势 1. 标准化 JPA 是 JCP 组织发布的Java EE标准之一,因此任何声称符合JPA标准的框架都遵循同样的架构,提供相同的访问API, 这保证了基于JPA开发的企业应用能够经过少量的修改就能够在不同的JPA框架下运行。 2. 容器级特性的支持 JPA框架中支持大数据集、事务、并发等容器级事务,这使得 JPA 超越了简单持久化框架的局限,在企业应用发挥更大的作用。 3. 简单方便 JPA的主要目标之一就是提供更加简单的编程模型:在JPA框架下创建实体和创建Java类一样简单,没有任何的约束和限制, 只需要使javax.persistence.Entity进行注释,JPA的框架和接口也都非常简单,没有太多特别的规则和设计模式的要求,开发者可以很容易的掌握。 JPA基于非侵入式原则设计,因此可以很容易的和其它框架或者容器集成 4. 查询能力 JPA的查询语言是面向对象而非面向数据库的,它以面向对象的自然语法构造查询语句,可以看成是Hibernate HQL的等价物。 JPA定义了独特的JPQL(Java Persistence Query Language),JPQL是EJB QL的一种扩展,它是针对实体的一种查询语言, 操作对象是实体,而不是关系数据库的表,而且能够支持批量更新和修改、JOIN、GROUP BY、HAVING 等 通常只有SQL才能够提供的高级查询特性,甚至还能够支持子查询。 5. 高级特性 JPA 中能够支持面向对象的高级特性,如类之间的继承、多态和类之间的复杂关系,这样的支持能够让开发者最大限度的使用面向对象的模型设计企业应用, 而不需要自行处理这些特性在关系数据库的持久化。 2.4 JPA与hibernate的关系 JPA规范本质上就是一种ORM规范,注意不是ORM框架——因为JPA并未提供ORM实现,它只是制订了一些规范, 提供了一些编程的API接口,但具体实现则由服务厂商来提供实现。      JPA和Hibernate的关系就像JDBC和JDBC驱动的关系,JPA是规范,Hibernate除了作为ORM框架之外,它也是一种JPA实现。 JPA怎么取代Hibernate呢?JDBC规范可以驱动底层数据库吗?答案是否定的,也就是说, 如果使用JPA规范进行数据库操作,底层需要hibernate作为其实现类完成数据持久化工作。 三. JPA的入门案例 3.1 搭建开发环境 maven工程导入坐标: UTF-8 5.0.7.Final junit junit 4.12 test org.hibernate hibernate-entitymanager ${project.hibernate.version} org.hibernate hibernate-c3p0 ${project.hibernate.version} log4j log4j 1.2.17 mysql mysql-connector-java 5.1.6 3.2 创建客户的数据库表和客户的实体类 创建客户的数据库表 创建客户的实体类 3.3 编写实体类和数据库表的映射配置 使用的注解: @Entity 作用:指定当前类是实体类 @Table 作用:指定实体类和表之间的对应关系 属性: name:指定数据库表的名称 @Id 作用:指定当前字段是主键 @GeneratedValue 作用:指定主键的生成方式 属性: strategy :指定主键生成策略 例:@GeneratedValue(strategy=GenerationType.IDENTITY) @Column 作用:指定实体类属性和数据库表之间的对应关系 属性: name:指定数据库表的列名称。 unique:是否唯一 nullable:是否可以为空 inserttable:是否可以插入 updateable:是否可以更新 columnDefinition: 定义建表时创建此列的DDL secondaryTable: 从表名。如果此列不建在主表上(默认建在主表),该属性定义该列所在从表的名字搭建开发环境 3.4 配置JPA的核心配置文件 在java工程的src路径下创建一个名为META-INF的文件夹,在此文件夹下创建一个名为persistence.xml的配置文件 org.hibernate.jpa.HibernatePersistenceProvider 3.4 实现保存操作(最原始的例子) @Test public void test() { /** * 创建实体管理类工厂,借助Persistence的静态方法获取 * 其中传递的参数为持久化单元名称,需要jpa配置文件中指定 */ EntityManagerFactory factory = Persistence.createEntityManagerFactory("myJpa"); //创建实体管理类 EntityManager em = factory.createEntityManager(); //获取事务对象 EntityTransaction tx = em.getTransaction(); //开启事务 tx.begin(); Customer c = new Customer(); c.setCustName("张三"); //保存操作 em.persist(c); //提交事务 tx.commit(); //释放资源 em.close(); factory.close(); } 四. JPA中的复杂查询 4.1 JPQL简介 JPQL全称Java Persistence Query Language 基于首次在EJB2.0中引入的EJB查询语言(EJB QL),Java持久化查询语言(JPQL)是一种可移植的查询语言,旨在以面向对象表达式语言的表达式, 将SQL语法和简单查询语义绑定在一起·使用这种语言编写的查询是可移植的,可以被编译成所有主流数据库服务器上的SQL。 其特征与原生SQL语句类似,并且完全面向对象,通过"类名和属性"访问,而不是表名和表的属性。 五. SpringData JPA的概述 5.1 SpringData JPA的简介 SpringData JPA 是 Spring 基于ORM框架、JPA 规范的基础上封装的一套JPA应用框架,可使开发者用极简的代码即可实现对数据库的访问和操作。 它提供了包括增删改查等在内的常用功能,且易于扩展!学习并使用 Spring Data JPA 可以极大提高开发效率! SpringData JPA 让我们解脱了DAO层的操作,基本上所有CRUD都可以依赖于它来实现, 在实际的工作工程中,推荐使用SpringData JPA + ORM(如:hibernate)完成操作, 这样在切换不同的ORM框架时提供了极大的方便,同时也使数据库层操作更加简单,方便解耦。 5.2 SpringData JPA的特性 SpringData Jpa 极大简化了数据库访问层代码。 如何简化的呢? 使用了SpringDataJpa,我们的dao层中只需要写接口,就自动具有了增删改查、分页查询等方法。 5.3 SpringData JPA与JPA和hibernate之间的关系 JPA是一套规范,内部是有接口和抽象类组成的。 hibernate是一套成熟的ORM框架,而且Hibernate实现了JPA规范,所以也可以称hibernate为JPA的一种实现方式, 我们使用JPA的API编程,意味着站在更高的角度上看待问题(面向接口编程) SpringData JPA是Spring提供的一套对JPA操作更加高级的封装,是在JPA规范下的专门用来进行数据持久化的解决方案。 六. SpringData JPA的快速入门 6.1 需求说明 SpringData JPA完成客户的基本CRUD操作 6.2 搭建SpringData JPA的开发环境 使用Spring Data JPA,需要整合Spring与Spring Data JPA,并且需要提供JPA的服务提供者hibernate, 所以需要导入spring相关坐标,hibernate坐标,数据库驱动坐标等 6.3 maven坐标 4.2.4.RELEASE 5.0.7.Final 1.6.6 1.2.12 0.9.1.2 5.1.6 junit junit 4.9 test org.aspectj aspectjweaver 1.6.8 org.springframework spring-aop ${spring.version} org.springframework spring-context ${spring.version} org.springframework spring-context-support ${spring.version} org.springframework spring-orm ${spring.version} org.springframework spring-beans ${spring.version} org.springframework spring-core ${spring.version} org.hibernate hibernate-core ${hibernate.version} org.hibernate hibernate-entitymanager ${hibernate.version} org.hibernate hibernate-validator 5.2.1.Final c3p0 c3p0 ${c3p0.version} log4j log4j ${log4j.version} org.slf4j slf4j-api ${slf4j.version} org.slf4j slf4j-log4j12 ${slf4j.version} mysql mysql-connector-java ${mysql.version} org.springframework.data spring-data-jpa 1.9.0.RELEASE org.springframework spring-test 4.2.4.RELEASE javax.el javax.el-api 2.2.4 org.glassfish.web javax.el 2.2.4 6.4 整合SpringData JPA与Spring的配置文件 6.5 编写符合SpringData JPA规范的Dao层接口 在Spring Data JPA中,对于定义符合规范的Dao层接口,我们只需要遵循以下几点就可以了: 1.创建一个Dao层接口,并实现JpaRepository和JpaSpecificationExecutor 2.提供相应的泛型 JpaRepository<实体类类型,主键类型>:用来完成基本CRUD操作 JpaSpecificationExecutor<实体类类型>:用于复杂查询(分页等查询操作) 6.6 方法命名规则查询 顾名思义,方法命名规则查询就是根据方法的名字,就能创建查询。 只需要按照SpringData JPA提供的方法命名规则定义方法的名称,就可以完成查询工作。 SpringData JPA在程序执行的时候会根据方法名称进行解析,并自动生成查询语句进行查询 按照SpringData JPA 定义的规则,查询方法以findBy开头,涉及条件查询时,条件的属性用条件关键字连接, 要注意的是:条件属性首字母需大写。框架在进行方法名解析时,会先把方法名多余的前缀截取掉,然后对剩下部分进行解析。 七. Specifications动态查询 7.1 JpaSpecificationExecutor接口简介 有时我们在查询某个实体的时候,给定的条件是不固定的,这时就需要动态构建相应的查询语句, 在SpringData JPA中可以通过JpaSpecificationExecutor接口查询。相比JPQL,其优势是类型安全,更加的面向对象。 对于JpaSpecificationExecutor,这个接口基本是围绕着Specification接口来定义的。我们可以简单的理解为,Specification构造的就是查询条件。 Specification接口中只定义了如下一个方法: //构造查询条件 /** * root :Root接口,代表查询的根对象,可以通过root获取实体中的属性 * query :代表一个顶层查询对象,用来自定义查询 * cb :用来构建查询,此对象里有很多条件方法 **/ public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb); 八. JPA中的一对多和多对多 8.1 映射的注解说明 @OneToMany: 作用:建立一对多的关系映射 属性: targetEntityClass:指定多的多方的类的字节码 mappedBy:指定从表实体类中引用主表对象的名称。 cascade:指定要使用的级联操作 fetch:指定是否采用延迟加载 orphanRemoval:是否使用孤儿删除 @ManyToOne 作用:建立多对一的关系 属性: targetEntityClass:指定一的一方实体类字节码 cascade:指定要使用的级联操作 fetch:指定是否采用延迟加载 optional:关联是否可选。如果设置为false,则必须始终存在非空关系。 @JoinColumn 作用:用于定义主键字段和外键字段的对应关系。 属性: name:指定外键字段的名称 referencedColumnName:指定引用主表的主键字段名称 unique:是否唯一。默认值不唯一 nullable:是否允许为空。默认值允许。 insertable:是否允许插入。默认值允许。 updatable:是否允许更新。默认值允许。 columnDefinition:列的定义信息。 8.2 放弃主键维护 /** *放弃外键维护权的配置将如下配置改为 */ //@OneToMany(targetEntity=LinkMan.class) //@JoinColumn(name="lkm_cust_id",referencedColumnName="cust_id") //设置为 @OneToMany(mappedBy="customer") 8.3 删除 删除操作的说明如下: 删除从表数据:可以随时任意删除。 删除主表数据: 有从表数据 1、在默认情况下,它会把外键字段置为null,然后删除主表数据。如果在数据库的表结构上,外键字段有非空约束,默认情况就会报错了。 2、如果配置了放弃主键维护关联关系的权利,则不能删除(与外键字段是否允许为null没有关系)因为在删除时,它根本不会去更新从表的外键字段了。 3、如果还想删除,使用级联删除引用 没有从表数据引用:随便删 在实际开发中,级联删除请慎用!(在一对多的情况下) 8.4 级联操作 使用方法:只需要在操作主体的注解上配置cascade /** * cascade:配置级联操作 * CascadeType.MERGE 级联更新 * CascadeType.PERSIST 级联保存: * CascadeType.REFRESH 级联刷新: * CascadeType.REMOVE 级联删除: * CascadeType.ALL 包含所有 */ @OneToMany(mappedBy="customer",cascade=CascadeType.ALL) 8.5 立即加载与延迟加载 配置方式: /** * 在客户对象的@OneToMany注解中添加fetch属性 * FetchType.EAGER :立即加载 * FetchType.LAZY :延迟加载 */ @OneToMany(mappedBy="customer",fetch=FetchType.EAGER) private Set linkMans = new HashSet<>(0); 如一方查询多方,推荐使用延迟加载!!! 如多方查询一方,使用立即加载和延迟加载都可以