JAP20学习笔记.docx
- 文档编号:7362485
- 上传时间:2023-05-11
- 格式:DOCX
- 页数:16
- 大小:30.13KB
JAP20学习笔记.docx
《JAP20学习笔记.docx》由会员分享,可在线阅读,更多相关《JAP20学习笔记.docx(16页珍藏版)》请在冰点文库上搜索。
JAP20学习笔记
JavaEE5平台引入了Java持久化API(JavaPersistenceAPI,JPA),它为JavaEE和JavaSE应用程序提供了一个基于POJO的持久化模块。
JPA处理关系数据与Java对象之间的映射,它使对象/关系(O/R)映射标准化,JPA已经被广泛采用并且成为O/R持久化企业标准。
JavaEE6平台带来了JPA最新版本;Java持久化2.0,JPA2.0带来了许多新特性和增强。
主要包括:
引用
1.对象/关系映射增强
2.Java持久化查询语言增强
3.一种新的基于标准的查询API
4.支持悲观锁定
对象/关系映射增强
JPA1.0支持集合的映射,但是这些集合只能包含实体,JPA2.0增加了集合映射的基础数据类型,以及嵌入式对象的集合。
JPA中的嵌入式对象是一个不能存在于它自身的对象,而是作为父对象的一部分存在,即它的数据不是存在于它自己的表中,而是嵌入在父对象的表中。
JPA2.0增加了两个支持新的集合映射的注解:
@ElementCollection和@CollectionTable.使用@ElementCollection注解指定集合的嵌入式对象,这些集合是独立存储在集合表中,使用@CollectionTable注解指定集合表的相信信息。
例如:
下面是一个嵌入式类,表示了车辆的访问服务,它存储了访问的日期,描述和费用,此外,车辆可以配备一或多个可选功能,每个功能是FeatureType类型的一个枚举值.
Java代码
1.public enum FeatureType{AC,CRUISE,PWR,BLUETOOTH,TV,...}
2.
3.@Embeddable
4.public class ServiceVisit{
5. @Temporal(DATE)
6. @Column(name="SVC_DATE")
7. Date serviceDate;
8. String workDesc;
9. int cost;
10. }
publicenumFeatureType{AC,CRUISE,PWR,BLUETOOTH,TV,...}
@Embeddable
publicclassServiceVisit{
@Temporal(DATE)
@Column(name="SVC_DATE")
DateserviceDate;
StringworkDesc;
intcost;
}
枚举值和嵌入对象可以在一个表示车辆服务历史的实体中使用,如
Java代码
1.@Entity
2.public class Vehicle{
3. @Id int vin;
4. @ElementCollection
5. @CollectionTable(name="VEH_OPTNS")
6. @Column(name="FEAT")
7. Set
8. @ElementCollection
9. @CollectionTable(name="VEH_SVC")
10. @OrderBy("serviceDate")
11. List
12. ...
13. }
@Entity
publicclassVehicle{
@Idintvin;
@ElementCollection
@CollectionTable(name="VEH_OPTNS")
@Column(name="FEAT")
Set
@ElementCollection
@CollectionTable(name="VEH_SVC")
@OrderBy("serviceDate")
List
...
}
Vehicle实体中的第一对注解@ElementCollection和@CollectionTable指定FeatureType值存储在VEH_OPTNS集合表中,第二对注解@ElementCollection和@CollectionTable指定ServiceVisit嵌入式对象存储在VEH_SVC集合表中。
虽然在例子中没有显示,@ElementCollection注解有两个属性:
targetClass和fetch。
targetClass属性指定基础类或嵌入式类的类名,如果字段或属性是使用泛型定义的,那这两个属性是可选的,上面这个例子就是这样。
Fetch属性是可选的,它指定集合是延后检索还是立即检索,使用javax.persistence.FetchType常量,值分别用LAZY和EAGER,默认情况下,集合是延后匹配的。
JPA2.0中还有其它许多关于对象/关系映射的增强,例如,JPA2.0支持嵌套式嵌入,关系嵌入和有序列表,也增加了新的注解增强映射功能,通过@Access注解更灵活地支持特定的访问类型,更多用于实体关系的映射选项,如对单向一对多关系的外键映射支持,通过@MapsId注解支持派生身份,支持孤体删除。
Java持久化查询语言增强
JPA1.0定义了一个广泛的Java持久化查询语言,使用它你可以查询实体和它们的持久化状态。
JPA2.0对JPQL做了大量改进,如现在可以在查询中使用case表达式。
在下面的查询中,如果雇员的评分为1,则通过乘以1.1对雇员的薪水进行了增长,如果评分为2,则乘以1.05,其它评分则乘以1.01。
引用
UPDATEEmployeee
SETe.salary=
CASEWHENe.rating=1THENe.salary*1.1
WHENe.rating=2THENe.salary*1.05
ELSEe.salary*1.01
END
JPA2.0也为JPQL增加了大量新的运算符,如NULLIF和COALESCE,当数据库使用其它非空数据解码时,NULLIF运算符是非常有用的,使用NULLIF,你可以在查询中将这些值转换为空值,如果参数等于NULLIF,NULLIF会返回空值,否则返回第一个参数的值。
假设薪水数据保存在employee表中,数据类型为整数,却掉的薪水解码为-9999,下面的查询返回薪水的平均值,为了正确地忽略却掉的薪水,查询使用NULLIF将-9999转换为空值。
引用
SELECTAVG(NULLIF(e.salary,-99999))FROMEmployeee
COALESCE运算符接收一串参数,从列表中返回第一个非空值,相当于下面的case表达式:
引用
CASEWHENvalue1ISNOTNULLTHENvalue1
WHENvalue2ISNOTNULLTHENvalue2
WHENvalue3ISNOTNULLTHENvalue3
...
ELSENULL END
COALESCE运算符接收一串参数,从列表中返回第一个非空值,相当于下面的case表达式:
引用
SELECTName,COALESCE(e.work_phone,e.home_phone)phoneFROMEmployeee
假设employee表包括一个办公电话号码和家庭电话号码列,无电话号码的列使用空值表示。
下面的查询返回每个雇员的姓名和电话号码,COALESCE运算符指定查询返回办公电话号码,但如果为空,则返回家庭电话号码,如果两者都为空,则返回一个空值。
JPA2.0向JPQL增加的其它运算符是INDEX,TYPE,KEY,VALUE和ENTRY。
INDEX运算符指定查询时的排序顺序,TYPE运算符选择一个实体的类型,将查询限制到一或多个实体类型,KEY,VALUE和ENTRY运算符是JPA2.0中的泛化映射功能的一部分。
使用KEY运算符提取映射键,VALUE运算符提取映射值,ENTRY运算符选择一个映射实体。
此外,JPA2.0增加了选择列表、以及集合值参数和非多态查询中运算符的支持。
标准的API
JPA2.0中引入的另一个重要特性是标准的API,利用这个API可以动态地构建基于对象的查询,本质上,这个标准API等价于面向对象的JPQL,使用它,你可以使用基于对象的方法创建查询,不再需要JPQL使用的字符串操作。
标准API是基于元模型的,元模型是一个提供了架构级关于持久化单元托管类的元数据的抽象模型,元模型让你构建强类型的查询,它也允许你浏览持久化单元的逻辑结构。
通常,一个注解处理器使用元模型生成静态元模型类,这些类提供持久化状态和持久化单元托管类的关系,但你可以对静态元模型类编码。
下面是一个实体实例:
Java代码
1.@Entity
2.public class Employee{
3. @Id Long Id;
4. String firstName;
5. String lastName;
6. Departement dept;
7. //setter or getter
8. .....
9.}
@Entity
publicclassEmployee{
@IdLongId;
StringfirstName;
StringlastName;
Departementdept;
//setterorgetter
.....
}
对应的静态元模型类
Java代码
1.import javax.persistence.meta.model.SingularAttribute
2.import javax.persistence.meta.model.StaticMetamodel;
3. @Generated("EclipseLink JPA 2.0 Canonical Model Generation"
4. @StaticMetamodel(Employee.class)
5.public class Employee_ {
6. public static volatile SingularAttribute
7. public static volatile SingularAttribute
8. public static volatile SingularAttribute
9. }
importjavax.persistence.meta.model.SingularAttribute
importjavax.persistence.meta.model.StaticMetamodel;
@Generated("EclipseLinkJPA2.0CanonicalModelGeneration"
@StaticMetamodel(Employee.class)
publicclassEmployee_{
publicstaticvolatileSingularAttribute
publicstaticvolatileSingularAttribute
publicstaticvolatileSingularAttribute
}
此外,JPA2.0元模型API允许你动态访问元模型,因此当你使用标准API时,既可以静态访问元模型类,也可以动态访问元模型类。
标准API提供了更好的灵活性,既可以使用基于对象的方法,又可以使用基于字符串的方法导航元模型,这意味着你有四种使用标准API的方法:
引用
1、静态使用元模型类
2、静态使用字符串
3、动态使用元模型
4、动态使用字符串
无论你使用哪种方法,通过构造一个CriteriaQuery对象定义一个基于标准API的查询时,使用一个工厂对象CriteriaBuilder构造CriteriaQuery,可以从EntityManager或EntityManagerFactory类中获得CriteriaBuilder。
下面的代码构造一个CriteriaQuery对象:
Java代码
1.EntityManager em = ....;
2. CriteriaBuilder cb = em.getCriteriaBuilder();
3. CriteriaQuery
4....
EntityManagerem=....;
CriteriaBuildercb=em.getCriteriaBuilder();
CriteriaQuery
...
注意CriteriaQuery对象是泛型类型,使用CriteriaBuilder的createQuery方法创建一个CriteriaQuery,并为查询结果指定类型。
在这个例子中,createQuery方法的Employee.class参数指定查询结果类型是Employee。
CriteriaQuery对象和创建它们的方法是强类型的。
接下来,为CriteriaQuery对象指定一个或多个查询源,查询源表示查询基于的实体。
你创建一个查询源,然后使用AbstractQuery接口的from()方法将其添加到查询。
AbstractQuery接口是众多接口中的一员,如CriteriaQuery,From和root,它们都定义在标准API中。
CriteriaQuery接口继承AbstractQuery接口的属性。
from()方法的参数是实体类或EntityType实体的实例,from()方法的结果是一个Root对象,Root接口扩展From接口,它表示某个查询的from子句中可能出现的对象。
下面的代码增加一个查询源到CriteriaQuery对象:
Java代码
1.CriteriaBuilder cb = em.getCriteriaBuilder();
2. CriteriaQuery
3. Root
CriteriaBuildercb=em.getCriteriaBuilder();
CriteriaQuery
Root
当你向CriteriaQuery对象添加一个或多个查询源后,你访问元模型,然后构造一个查询表达式,你如何做取决于你是以静态方式提交查询还是以动态方式提交查询,以及是使用元模型还是字符串导航元模型。
下面是一个使用元模型类静态查询的例子:
引用
cq.select(emp);
cq.where(cb.equal(emp.get(Employee_.lastName),"Smith"));
TypedQuery
List
CriteriaQuery接口的select()和where()方法指定查询结果返回的选择项目。
注意,你使用EntityManager创建查询时,可以在输入中指定一个CriteriaQuery对象,它返回一个TypedQuery,它是JPA2.0引入javax.persistence.Query接口的一个扩展,TypedQuery接口知道它返回的类型。
在元模型术语中,Employee_是对应于Employee实体类的规范化元模型类,一个规范化元模型类遵循JPA2.0规范中描述的某些规则。
例如,元模型类的名字来源于托管类,一般都是在托管类名字后面追加一个下划线“_”。
一个规范化元模型是一个包含静态元模型类的元模型,这个静态元模型对应于实体,映射的超类,以及持久化单元中的嵌入式类。
实际上,这个查询使用了规范化元模型。
下面是一个完整的查询:
Java代码
1.EntityManager em = ... ;
2. CriteriaBuilder cb = em.getCriteriaBuilder();
3. CriteriaQuery
4. cq.select(emp);
5. cq.where(cb.equal(emp.get(Employee_.lastName), "Smith"));
6. TypedQuery
7. List
EntityManagerem=...;
CriteriaBuildercb=em.getCriteriaBuilder();
CriteriaQuery
cq.select(emp);
cq.where(cb.equal(emp.get(Employee_.lastName),"Smith"));
TypedQuery
List
下面是使用元模型API查询的动态版本:
Java代码
1.EntityManager em = ... ;
2. CriteriaBuilder cb = em.getCriteriaBuilder();
3. CriteriaQuery
4. Root
5. EntityType
6. cq.select(emp);
7. cq.where(cb.equal(emp.get(emp_.getSingularAttribute("lastName", String.class)),"Smith"));
8. TypedQuery
9. List
EntityManagerem=...;
CriteriaBuildercb=em.getCriteriaBuilder();
CriteriaQuery
Root
EntityType
cq.select(emp);
cq.where(cb.equal(emp.get(emp_.getSingularAttribute("lastName",String.class)),"Smith"));
TypedQuery
List
使用元模型API的标准查询提供了与使用规范化元模型相同的类型,但它比基于规范化元模型的查询更冗长。
Root的getModel()方法返回根对应的元模型实体,它也允许运行时访问在Employee实体中声明的持久化属性。
getSingularAttribute()方法是一个元模型API方法,它返回一个持久化的单值属性或字段,在这个例子中,它返回值为Smith的lastName属性。
下面是使用字符串的元数据导航查询的静态版本:
JavaEE5平台引入了Java持久化API(JavaPersistenceAPI,JPA),它为JavaEE和JavaSE应用程序
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- JAP20 学习 笔记