JPA使用规范说明书20.docx
- 文档编号:10945163
- 上传时间:2023-05-28
- 格式:DOCX
- 页数:18
- 大小:279.70KB
JPA使用规范说明书20.docx
《JPA使用规范说明书20.docx》由会员分享,可在线阅读,更多相关《JPA使用规范说明书20.docx(18页珍藏版)》请在冰点文库上搜索。
JPA使用规范说明书20
JPA
使用规范说明书
科大讯飞股份有限公司
2017年10月26日
版本记录
序号
版本
更改时间
更改内容描述
作者
1
1.0
2017-10-26
新建
吴海林
2
2.0
2017-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.2JPA原理实现
我们知道JPA只是一个规范,下面的JPAProvider可以由不同的ORM框架提供。
ORM框架可以根据映射关系,操作PO对象,自动生成增查改删的SQL
JPA包括以下3方面的技术:
1.ORM映射元数据,JPA支持XML和JDK5.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依赖:
配置文件(MATA-INF>下的persistence.xml)
怎么去掉persistence.xml的实体类配置?
使用了 persistence配置文件,去掉“persistenceUnitName”属性,添加“packagesToScan”属性,persistence.xml配置文件中的persistence-unit名字照样保留,但是 persistence配置文件中不需要对实体类进行配置,会自动识别。
2.1.2SpringDataJPA+hibernate(使用最多)
Maven依赖:
(除spring核心相关包之外)
配置文件(定义EntityManagerFactory实体类管理)
2.1.3SpringBoot+JPA
SpringBoot通过@EnableAutoConfiguration 入口可以实现自动配置,具体配置文件key参考springBoot配置参数说明----
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters=@Filter(type=FilterType.CUSTOM,classes=TypeExcludeFilter.class))
public@interfaceSpringBootApplication{}
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.2JPA的API
单元
描述
EntityManagerFactory
这是一个EntityManager的工厂类。
它创建并管理多个EntityManager实例。
EntityManager
这是一个接口,它管理的持久化操作的对象。
它的工作原理类似工厂的查询实例。
Entity
实体是持久性对象是存储在数据库中的记录。
EntityTransaction
它与EntityManager是一对一的关系。
对于每一个EntityManager,操作是由EntityTransaction类维护。
Persistence
这个类包含静态方法来获取EntityManagerFactory实例。
Query
该接口由每个JPA供应商,能够获得符合标准的关系对象。
上述的类和接口用于存储实体到数据库的一个记录。
帮助程序员通过减少自己编写代码将数据存储
EntityManagerFactoryfactory=Persistence.createEntityManagerFactory("JPAService");
EntityManagerem=factory.createEntityManager();
Queryquery=em.createQuery("selectpfromCourtInfopwherep.id=:
Id");
query.setParameter("Id",newInteger
(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的包装类型,例如IntegerLong等
@GeneratedValue
标注有以两个属性:
(1)strategy 属性表示生成主键的策略 ,有4种类型,分别定义在枚举型GenerationType中,其中JPA提供了以下几种ID生成策略
GeneratorType.AUTO,由JPA自动生成
GenerationType.IDENTITY,使用数据库的自增长字段,需要数据库的支持(如SQLServer、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.2Dao-Repository层
基础的Repository提供了最基本的数据访问功能,单表的CRUD基本操作可以继承这些接口,其几个子接口则扩展了一些功能。
它们的继承关系如下:
Repository:
仅仅是一个标识,表明任何继承它的均为仓库接口类
(1)CrudRepository:
继承Repository,实现了一组CRUD相关的方法
(2)PagingAndSortingRepository:
继承CrudRepository,实现了一组分页排序相关的方法
(3)JpaRepository:
继承PagingAndSortingRepository,实现一组JPA规范相关的方法
2.2.3JPQL语法
JPQL是EJBQL的一种扩展,它是针对实体面向对象的一种查询语言,操作对象是实体,而不是关系数据库的表,而且能够支持批量更新和修改、JOIN、GROUPBY、HAVING等通常只有SQL才能够提供的高级查询特性,甚至还能够支持子查询。
JPQL就是一种查询语言,具有与SQL 相类似的特征,JPQL是完全面向对象的,具备继承、多态和关联等特性,和hibernateHQL很相似。
2.2.3.1、sql,hql,jpql之间的区别;
sql是关系数据库查询语言,面对的数据库;而hql是Hibernate这样的数据库持久化框架提供的内置查询语言,虽然他们的目的都是为了从数据库查询需要的数据,但sql操作的是数据库表和字段,而作为面向对象的hql操作的则是持久化类及其属性
jpql:
基于首次在EJB2.0中引入的EJB查询语言(EJBQL),Java持久化查询语言(JPQL)是一种可移植的查询语言,旨在以面向对象表达式语言的表达式,将SQL语法和简单查询语义绑定在一起.使用这种语言编写的查询是可移植的,可以被编译成所有主流数据库服务器上的SQL.
JPQL是面向对象查询,格式:
from+类名+类对象+where+对象的属性
需要注意的是:
A、大小写敏感
因为jpql是面向对象的,而对象类的名称和属性都是大小写敏感的,所以jpql也是大小写敏感的。
因此,在编写jpql语句的时候,一定要注意大小写。
B、from子句
from子句的形式和sql基本类似,不过一般会给类名起一个别名(如fromDogd,其中d就是Dog类的对象)
对于多表查询的连接,则和sql完全一样(如fromDogd,Catc)
2.2.3.2、通过解析方法名创建查询
JpaRepository会对Repository层所有未加@Query的方法名进行校验不符合规范会报错,除非添加@Query注解
查询方法以find|read|get 开头—建议统一用find开头;
格式findBy**And/Or**;findBy**NotLike等,具体参考下图:
List
UserfindByUserNameAndPassword(Stringusername,Stringpassword);
注:
按方法名解析的查询方法通常只适用于单表的查询,且建议where条件参数不多于三条的情况下,返回值通常上对应表的实体Bean,通常用实体类List类型;具体要看返回结果,当返回值与类型不匹配时会造成查询错误;
2.2.3.3、使用@Query创建自定义查询
@Query注解的使用非常简单,只需在声明的方法上面标注该注解,同时提供一个JPQL查询语句即可
查询策略:
repositories>提供了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="selectnewpers.zhuch.model.MyModel(u.userName,ui.name,ui.gender,ui.description)fromUserInfoui,Useruwhereu.id=ui.userId") publicList 返回Map @Query("selectnewmap(i.userAddress,u.userName,u.password)fromUseru,UserInfoiwhereu.id=i.userIdandi.userId=? 1") List 2.2.3.3.2、如何实现分页,多条件排序? 分页: 分页参数入参实现Pageable接口 Page (自定义复杂查询分页案例: ) @Query(value="selectufromUseruwhereu.userName=? 1") Page 排序: Sort排序类 List 2.2.3.3.3、复杂查询复合函数的使用; --GroupBy @Query("selectu.userNamefromUserugroupbyu.userName") List --AVG/SUM等 @Query("selectAVG(u.age)fromuser_infouWHEREu.userDept=? 1") intfindAvgAgeByDept(Stringdept); --多表复杂联合查询 @Query("selectnewcom.iflytek.jpa.domain(u.id,i.userAddress,u.userName,i.userDept,u.password)fromUseru,UserInfoiwhereu.id=i.userIdandu.userName=? 1andi.userDept=? 2") List 2.2.3.4、使用@Modifying创建update,insert,delete语句 @Modifying @Query(value="insertintot_sys_org_user(org_id,user_id)values(? 1,? 2)",nativeQuery=true) intaddUserToOrg(LongorgId,LonguserId); Table-update操作 @Modifying @Query("updateUserusetu.password=? 1whereu.userName=? 2") intupdateByName(Stringpassword,Stringname); 表的插入和删除方法一般不需要自定义方法,CRUD和JpaRepository方法里都有单条和批量的插入、删除方法。 2.2.3.5、参数传递 JPQL支持命名参数和位置参数两种参数,但是在一条JPQL语句中所有的参数只能使用同一种类型。 举例如下: ∙命名参数 Queryquery=em.createQuery("selectpfromPersonpwherep.personid=: Id");query.setParameter("Id",newInteger (1)); ∙位置参数 Queryquery=em.createQuery("selectpfromPersonpwherep.personid=? 1");query.setParameter(1,newInteger (1)); 3、JPA延伸拓展 3.1JP
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- JPA 使用 规范 说明书 20