最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 正文

JPA使用规范说明书2.0

来源:动视网 责编:小OO 时间:2025-09-26 23:34:06
文档

JPA使用规范说明书2.0

JPA使用规范说明书科大讯飞股份有限公司2017年10月26日版本记录序号版本更改时间更改内容描述作者11.02017-10-26新建吴海林22.02017-11-10评审后修改吴海林1、JPA概述1.1什么是JPA规范JPA规范(java持久化API)JPA和Hibernate等框架一样,都是java持久化解决方案,负责把数据保存到数据库。不同的是,JPA只是一种标注,规范,而不是框架。JPA自己没有具体的实现。使用JPA后,程序不在依赖于某种ORM框架。具体实现有TopLink,Eclip
推荐度:
导读JPA使用规范说明书科大讯飞股份有限公司2017年10月26日版本记录序号版本更改时间更改内容描述作者11.02017-10-26新建吴海林22.02017-11-10评审后修改吴海林1、JPA概述1.1什么是JPA规范JPA规范(java持久化API)JPA和Hibernate等框架一样,都是java持久化解决方案,负责把数据保存到数据库。不同的是,JPA只是一种标注,规范,而不是框架。JPA自己没有具体的实现。使用JPA后,程序不在依赖于某种ORM框架。具体实现有TopLink,Eclip
 

JPA

使用规范说明书

科大讯飞股份有限公司

2017年10月26日

版本记录

序号版本更改时间更改内容描述作者
11.02017-10-26新建吴海林
22.02017-11-10评审后修改吴海林

1、JPA概述

1.1 什么是JPA规范

    JPA规范(java持久化API)JPA和Hibernate等框架一样,都是java持久化解决方案,负责把数据保存到数据库。不同的是,JPA只是一种标注,规范,而不是框架。JPA自己没有具体的实现。使用JPA后,程序不在依赖于某种ORM框架。具体实现有TopLink,Eclipselink, OpenJPA等。

随着ibatis,hibernate等优秀的ORM管理框架的出现,相比以上供应商,使得JPA性能有了很大的提升。

1.2 JPA原理实现

我们知道JPA 只是一个规范,下面的 JPA Provider 可以由不同的 ORM 框架提供。ORM 框架可以根据映射关系,操作PO对象,自动生成增查改删的 SQL

JPA包括以下3方面的技术: 

  1. ORM映射元数据,JPA支持XML和JDK 5.0注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中; 

  2. JPA的API,用来操作实体对象,执行CRUD操作,框架在后台替我们完成所有的事情,开发者从繁琐的JDBC和SQL代码中解脱出来。 

  3. 查询语言,这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合。

使用JPA的优点也是有很多:继承Repository接口,在注解中书写JPQL语句即可访问数据库;支持方法名解析方式访问数据库;使用Predicate支持动态查询

JPA当访问数据库主要工作

1.得到JDBC驱动程序

2.得到持久性提供者相关类库和配置文件

3.提供实体类

4.使用Persistence、EntityManagerFactory和Entity等接口。

2、JPA使用

2.1 使用前的准备及配置

2.1.1 原生配置方式java-persistence

Maven依赖:

  

        org.eclipse.persistence  

        javax.persistence  

        2.0.0  

        

      

        org.eclipse.persistence  

        eclipselink  

        2.0.0  

 

配置文件(MATA-INF>下的persistence.xml)

怎么去掉persistence.xml的实体类配置?

使用了 persistence 配置文件,去掉“persistenceUnitName”属性,添加“packagesToScan”属性,persistence.xml配置文件中的persistence-unit名字照样保留,但是 persistence 配置文件中不需要对实体类进行配置,会自动识别。

2.1.2 SpringDataJPA+hibernate(使用最多)

Maven依赖:(除spring核心相关包之外)

            org.springframework.data

            spring-data-jpa

            org.hibernate

            hibernate-entitymanager

            org.hibernate.javax.persistence

            hibernate-jpa-2.0-api

配置文件(定义EntityManagerFactory实体类管理)

2.1.3 SpringBoot+JPA

org.springframework.boot
spring-boot-starter-data-jpa
SpringBoot通过@EnableAutoConfiguration 入口可以实现自动配置,具体配置文件key参考springBoot配置参数说明----

@SpringBootConfiguration

@EnableAutoConfiguration

@ComponentScan(excludeFilters = @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class))

public @interface SpringBootApplication {}

Application.properties(resources下面即可)

spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver

spring.datasource.url=jdbc:mysql://192.168.1.12:3306/jeeboot?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC

spring.datasource.username=root

spring.datasource.password=123456

…….

spring.jpa.hibernate.ddl-auto=none

spring.jpa.show-sql=true

spring.jackson.serialization.indent_output=true

spring.jpa.properties.hibernate.hbm2ddl.auto=update

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect

spring.jpa.properties.hibernate.show_sql=false

spring.jpa.properties.hibernate.format_sql=false

spring.jpa.properties.hibernate.use_sql_comments=true

spring.jpa.properties.hibernate.jdbc.batch_size=25

spring.jpa.properties.hibernate.jdbc.fetch_size=50

spring.jpa.properties.hibernate.auto_quote_keyword=true

spring.jpa.properties.hibernate.current_session_context_class=thread

spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true

2.2 JPA的API

单元描述
EntityManagerFactory这是一个EntityManager的工厂类。它创建并管理多个EntityManager实例。

EntityManager这是一个接口,它管理的持久化操作的对象。它的工作原理类似工厂的查询实例。
Entity实体是持久性对象是存储在数据库中的记录。
EntityTransaction它与EntityManager是一对一的关系。对于每一个EntityManager,操作是由EntityTransaction类维护。

Persistence这个类包含静态方法来获取EntityManagerFactory实例。

Query该接口由每个JPA供应商,能够获得符合标准的关系对象。

上述的类和接口用于存储实体到数据库的一个记录。帮助程序员通过减少自己编写代码将数据存储

EntityManagerFactory factory = Persistence.createEntityManagerFactory("JPAService");

EntityManager em = factory.createEntityManager();

Query query = em.createQuery("select p from CourtInfo p where p.id=:Id"); 

query.setParameter("Id",new Integer(1));        

query.getSingleResult();

query.getResultList();

2.2.1 实体类Entity

表对象entity可手写亦可工具生成(建议手写)

实体类用java注解来配置也相当的简单。实体bean必须序列化。

@Entity

持久化实体类的声明-该声明是必须的,name属性可选

@Table

对表和实体类的声明,当名称不一致时必须注解声明

  name 属性表示实体所对应表的名称,默认表名为实体名称。

无论表名与实体名是否一致,建议添加name属性;

  catalog 和schema 属性表示实体指定的目录名或数据库名,这个根据不同的数据类型有所不同。

   uniqueConstraints 唯一约束条件

@NamedQuery中的属性name指定命名查询的名称,query属性指定命名查询的语句。

       如果要定义多个命名查询,需要使用@NamedQueries。

定义好命名查询后,可以使用EntityManager的createNamedQuery方法传入命名查询的名称创建查询。例如:createNamedQuery("findAllUser");--建议不用@NamedQuery该注解

@Id

主键声明

有一点需要注意的是实体类主键最好使用可以为null的包装类型,例如Integer Long等

@GeneratedValue 

标注有以两个属性:

       (1)strategy 属性表示生成主键的策略 ,有4种类型,分别定义在枚举型GenerationType中,其中JPA提供了以下几种ID生成策略

GeneratorType.AUTO ,由JPA自动生成

GenerationType.IDENTITY,使用数据库的自增长字段,需要数据库的支持(如SQL Server、MySQL、DB2、Derby等)

GenerationType.SEQUENCE,使用数据库的序列号,需要数据库的支持(如Oracle)

GenerationType.TABLE,使用指定的数据库表记录ID的增长 需要定义一个TableGenerator,在@GeneratedValue中引用。

       (2)generator 为不同策略类型所对应的生成规则名,它的值根据不同的策略有不同的设置。

@Column-对表字段和实体字段的声明,当名称不一致时必须注解声明

标记可以标注在Getter方法或属性前。

无论字段名与变量是否一致,建议添加name属性,且放置在属性前;

 unique 属性表示该字段是否为唯一标识,默认为false。如果表中有一个字段需要唯一标识,则既可以使用@Column标记也可以使用@Table标记中的

 nullable 属性表示该字段是否可以为null值,默认为true(允许为null值)。

insertable 属性表示在使用“INSERT” SQL语脚本插入数据时,是否需要插入该字段的值。

updatable 属性表示在使用“UPDATE”脚本插入数据时,是否需要更新该字段的值。insertable和updatable属性一般多用于只读属性,例如主键和外键等。这些字段值通常是自动生成的。

length 属性表示该字段的长度,当字段的类型为varchar时,该属性才有效,默认为255个字符。

precision 属性和scale 属性表示精度,当字段类型为double时,precision表示数值的总长度,scale表示小数点所占的位数

@Temporal设置为日期Date类型的字段

@Enumerated,如果想要将该字段映射为String(枚举表示的String),可以将其value设置为EnumType.String。

@Basic标记可以指定实体属性的加载方式LAZY和EAGER

@Transient 批注指定实体的非持久字段或属性

一些一对多,多对多等对象映射关系的注解,这里不做介绍了,实际数据库设计应避免这种映射关系设计。每张表都有独属于自己的主键Id。

JPA实体生命周期:

 JPA实体生命周期分为4种状态,分为:新建,受管(托管),分离(游离),删除。其实跟HIBERNATE的映射实体差不多,大致对应了hibernate中的生命周期:自由状态(Transient)——不受管,持久状态(Persistent)——托管,游离状态(Detached)——分离,只是粒度上有差别。

2.2.2 Dao-Repository层

基础的 Repository 提供了最基本的数据访问功能,单表的CRUD基本操作可以继承这些接口,其几个子接口则扩展了一些功能。它们的继承关系如下: 

Repository: 仅仅是一个标识,表明任何继承它的均为仓库接口类 

(1)CrudRepository: 继承 Repository,实现了一组 CRUD 相关的方法 

(2)PagingAndSortingRepository: 继承 CrudRepository,实现了一组分页排序相关的方法 

(3)JpaRepository: 继承 PagingAndSortingRepository,实现一组 JPA 规范相关的方法

2.2.3 JPQL语法

JPQL是EJB QL的一种扩展,它是针对实体面向对象的一种查询语言,操作对象是实体,而不是关系数据库的表,而且能够支持批量更新和修改、JOIN、GROUP BY、HAVING 等通常只有 SQL 才能够提供的高级查询特性,甚至还能够支持子查询。

JPQL就是一种查询语言,具有与SQL 相类似的特征,JPQL是完全面向对象的,具备继承、多态和关联等特性,和hibernate HQL很相似。

2.2.3.1、sql,hql,jpql之间的区别;

sql是关系数据库查询语言,面对的数据库;而hql是Hibernate这样的数据库持久化框架提供的内置查询语言,虽然他们的目的都是为了从数据库查询需要的数据,但sql操作的是数据库表和字段,而作为面向对象的hql操作的则是持久化类及其属性

jpql:基于首次在EJB2.0中引入的EJB查询语言(EJB QL),Java持久化查询语言(JPQL)是一种可移植的查询语言,旨在以面向对象表达式语言的表达式,将SQL语法和简单查询语义绑定在一起.使用这种语言编写的查询是可移植的,可以被编译成所有主流数据库服务器上的SQL.

JPQL是面向对象查询,格式:from + 类名 + 类对象 + where + 对象的属性

需要注意的是:

A、大小写敏感

因为jpql是面向对象的,而对象类的名称和属性都是大小写敏感的,所以jpql也是大小写敏感的。因此,在编写jpql语句的时候,一定要注意大小写。

B、from子句

from子句的形式和sql基本类似,不过一般会给类名起一个别名(如from Dog d,其中d就是Dog类的对象)

对于多表查询的连接,则和sql完全一样(如from Dog d,Cat c)

2.2.3.2、通过解析方法名创建查询

JpaRepository会对Repository层所有未加@Query的方法名进行校验 不符合规范会报错,除非添加@Query注解

查询方法以find | read | get 开头—建议统一用find开头;

格式findBy**And/Or**;findBy**NotLike等,具体参考下图:

List findByUserName(String username);

User findByUserNameAndPassword(String username,String password);

注:按方法名解析的查询方法通常只适用于单表的查询,且建议where条件参数不多于三条的情况下,返回值通常上对应表的实体Bean,通常用实体类List类型;具体要看返回结果,当返回值与类型不匹配时会造成查询错误;

2.2.3.3、使用 @Query 创建自定义查询

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

查询策略:

 提供了 query-lookup-strategy 属性,用以指定查找的顺序。它有如下三个取值:

1:create-if-not-found:如果方法通过@Query指定了查询语句,则使用该语句实现查询;如果没有,则查找是否定义了符合条件的命名查询,如果找到,则使用该命名查询;如果两者都没有找到,则通过解析方法名字来创建查询。这是 query-lookup-strategy 属性的默认值

2:create:通过解析方法名字来创建查询。即使有符合的命名查询,或者方法通过 @Query指定的查询语句,都将会被忽略

3:use-declared-query:如果方法通过@Query指定了查询语句,则使用该语句实现查询;如果没有,则查找是否定义了符合条件的命名查询,如果找到,则使用该命名查询;如果两者都没有找到,则抛出异常

2.2.3.3.1、如何多表查询?并返回自定义值?

返回对象VO

@Query(value = "select new pers.zhuch.model.MyModel(u.userName, ui.name, ui.gender, ui.description) from UserInfo ui, User u where u.id = ui.userId")

public List getAllRecord();

返回Map

@Query("select new map(i.userAddress,u.userName,u.password) from User u,UserInfo i where u.id = i.userId and i.userId=?1")

List> getUserInfo(long userId);

2.2.3.3.2、如何实现分页,多条件排序?

分页:分页参数入参实现Pageable接口

Page findByUserName(String name,Pageable pageable);

(自定义复杂查询分页案例:)

@Query(value = "select u from User u where u.userName =?1")

Page findByNamePage(String name, Pageable pageable);

排序:Sort排序类

List usersort = repository.findByUserDept("平嵌事业部",new Sort(Sort.Direction.DESC, "userAddress"));

2.2.3.3.3、复杂查询复合函数的使用;

--GroupBy

@Query("select u.userName from User u group by u.userName")

List findAllUserName();

--AVG/SUM等

@Query("select AVG(u.age) from user_info u WHERE u.userDept=?1")

int findAvgAgeByDept(String dept);

--多表复杂联合查询

@Query("select new com.iflytek.jpa.domain(u.id,i.userAddress,u.userName,i.userDept,u.password) from User u,UserInfo i where u.id = i.userId and u.userName=?1 and i.userDept=?2")

List getUserDetailInfo(long userName,String dept);

2.2.3.4、使用 @Modifying 创建update,insert,delete语句

@Modifying

    @Query(value = "insert into t_sys_org_user(org_id,user_id) values(?1,?2)",nativeQuery = true)

int addUserToOrg(Long orgId,Long userId);

Table-update操作

@Modifying

@Query("update User u set u.password=?1 where u.userName=?2")

int updateByName(String password, String name);

表的插入和删除方法一般不需要自定义方法,CRUD和JpaRepository方法里都有单条和批量的插入、删除方法。

2.2.3.5、参数传递 

JPQL支持命名参数和位置参数两种参数,但是在一条JPQL语句中所有的参数只能使用同一种类型。

举例如下:

∙命名参数

Query query = em.createQuery("select p from Person p where p.personid=:Id"); query.setParameter("Id",new Integer(1));

∙位置参数

Query query = em.createQuery("select p from Person p where p.personid=?1"); query.setParameter(1,new Integer(1));

3、JPA延伸拓展

3.1 JPA的事务

JPA框架中支持大数据集、事务、并发等容器级事务:

    

    

        

    

    

    

JPA支持本地事务管理(RESOURCELOCAL)和容器事务管理(JTA),容器事务管理只能用在EJB/Web容器环境中。

事务管理的类型可以在persistence.xml文件中的“transaction-type”元素配置。

JPA中通过EntityManager的getTransaction()方法获取事务的实例(EntityTransaction),之后可以调用事务的begin()、commit()、rollback()方法。

JPA对每个查询方法默认使用事务的,采用默认配置的事务类型。

复杂性的事务建议还是用Spring的@Transactional用于显式事务管理。

3.2 JPA的动态查询

如果查询条件是动态的,需要dao接口继承JpaSpecificationExecutor

public interface CustomerRepository extends CrudRepository, JpaSpecificationExecutor {

List findAll(Specification var1);

 …

}

调用案例:

List userss = repository.findAll(new Specification(

                ) {

                    @Override

                    public Predicate toPredicate(Root root,

                            CriteriaQuery query, CriteriaBuilder cb) {

                        query.where(cb.and(cb.like(root.get("userAddress").as(String.class), "%"+"蜀山国家"+"%")));

                        return null;

                    }

        });

3.3 JPA的缓存

http://blog.csdn.net/chenjianandiyi/article/details/522615

4、参考文献

JPA相关介绍

1、http://www.cnblogs.com/holbrook/archive/2012/12/30/2839842.html

2、http://sishuok.com/forum/blogPost/list/7000.html

3、http://www.yiibai.com/jpa/jpa_criteria_api.html

JPQL语法

4、https://docs.oracle.com/cd/E11035_01/kodo41/full/html/ejb3_langref.html

具体使用案例:

1、http://www.cnblogs.com/dreamroute/p/51736.html

文档

JPA使用规范说明书2.0

JPA使用规范说明书科大讯飞股份有限公司2017年10月26日版本记录序号版本更改时间更改内容描述作者11.02017-10-26新建吴海林22.02017-11-10评审后修改吴海林1、JPA概述1.1什么是JPA规范JPA规范(java持久化API)JPA和Hibernate等框架一样,都是java持久化解决方案,负责把数据保存到数据库。不同的是,JPA只是一种标注,规范,而不是框架。JPA自己没有具体的实现。使用JPA后,程序不在依赖于某种ORM框架。具体实现有TopLink,Eclip
推荐度:
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top