- 浏览: 443832 次
- 性别:
- 来自: 深圳
文章分类
- 全部博客 (354)
- 面向对象分析设计/系统架构 (12)
- Mysql/Orcal11g (13)
- JSP/Java//Python/Xharbour (66)
- 软件测试 (21)
- 信息安全小知识 (1)
- Android (5)
- IT生活/哲学/兵法 (23)
- 软件工程/UML/需求分析学习与实践 (6)
- 操作系统/网络/组成原理 (9)
- 持续集成Maven/Hudson/自动化测试 (9)
- eBay /Paypal developer (10)
- Hadoop/HBase/Solr (0)
- 重构分析及其思考 (2)
- 企业架构 (7)
- 分析模式/设计模式 (4)
- SSH学习笔记 (1)
- Quartz及其JWatch监控 (0)
- Linux服务器 (0)
- ExtJs学习笔记 (1)
- 重读java编程思想 (3)
- ESB/SOA/WebServices (0)
- SpringMVC/Struts/Hibernate/Spring (7)
- Xharbour/Pelles C/ SQLite3 (0)
- Magento 电商 (1)
- Object C (1)
- note/redis (0)
- SpringBoot (0)
最新评论
-
snow8261:
太粗略了。
企业架构之数据架构 -
haithink:
面试成功没?
JVM 加载Class文件的原理及其机制 -
feisi0003731843:
不好意思我没有重启,重启后好多了,可有的地方回放还是不成功的。 ...
Selenium IDE测试ExtJs一种测试解决办法 -
feisi0003731843:
这个好像不行吧,我试过了不好使啊。还是用id来做的。不能用啊。 ...
Selenium IDE测试ExtJs一种测试解决办法 -
yuchensuifeng:
您好,静态页面是可以的,但是,我指定error-page为js ...
JSP创建错误处理页面
Java EE 5平台引入了Java持久化API(Java Persistence API, JPA),它为Java EE和Java SE应用程序提供了一个基于POJO的持久化模块。JPA处理关系数据与Java对象之间的映射,它使对象/关系(O/R)映射标准化,JPA已经被广泛采用并且成为O/R持久化企业标准。
Java EE 6平台带来了JPA最新版本;Java 持久化2.0,JPA2.0带来了许多新特性和增强。主要包括:
1. 对象/关系映射增强
2. Java持久化查询语言增强
3. 一种新的基于标准的查询API
4. 支持悲观锁定
对象/关系映射增强
JPA 1.0 支持集合的映射,但是这些集合只能包含实体,JPA2.0增加了集合映射的基础数据类型,以及嵌入式对象的集合。JPA中的嵌入式对象是一个不能存在于它自身的对象,而是作为父对象的一部分存在,即它的数据不是存在于它自己的表中,而是嵌入在父对象的表中。
JPA2.0 增加了两个支持新的集合映射的注解:@ElementCollection和@CollectionTable.使用@ElementCollection注解指定集合的嵌入式对象,这些集合是独立存储在集合表中,使用@CollectionTable注解指定集合表的相信信息。
例如:
下面是一个嵌入式类,表示了车辆的访问服务,它存储了访问的日期,描述和费用,此外,车辆可以配备一或多个可选功能,每个功能是FeatureType类型的一个枚举值.
枚举值和嵌入对象可以在一个表示车辆服务历史的实体中使用,如
Vehicle实体中的第一对注解@ElementCollection 和@CollectionTable指定FeatureType值存储在VEH_OPTNS集合表中,第二对注解@ElementCollection 和@CollectionTable指定ServiceVisit嵌入式对象存储在VEH_SVC集合表中。
虽然在例子中没有显示,@ElementCollection注解有两个属性:targetClass 和 fetch。targetClass属性指定基础类或嵌入式类的类名,如果字段或属性是使用泛型定义的,那这两个属性是可选的,上面这个例子就是这样。Fetch属性是可选的,它指定集合是延后检索还是立即检索,使用javax.persistence.FetchType常量,值分别用LAZY和EAGER,默认情况下,集合是延后匹配的。
JPA 2.0中还有其它许多关于对象/关系映射的增强,例如,JPA 2.0支持嵌套式嵌入,关系嵌入和有序列表,也增加了新的注解增强映射功能,通过@Access注解更灵活地支持特定的访问类型,更多用于实体关系的映射选项,如对单向一对多关系的外键映射支持,通过@MapsId注解支持派生身份,支持孤体删除。
Java持久化查询语言增强
JPA 1.0定义了一个广泛的Java持久化查询语言,使用它你可以查询实体和它们的持久化状态。JPA 2.0对JPQL做了大量改进,如现在可以在查询中使用case表达式。在下面的查询中,如果雇员的评分为1,则通过乘以1.1对雇员的薪水进行了增长,如果评分为2,则乘以1.05,其它评分则乘以1.01。
UPDATE Employeee
SET e.salary =
CASE WHEN e.rating = 1 THEN e.salary * 1.1
WHEN e.rating = 2 THEN e.salary * 1.05
ELSE e.salary * 1.01
END
JPA 2.0也为JPQL增加了大量新的运算符,如NULLIF和COALESCE,当数据库使用其它非空数据解码时,NULLIF运算符是非常有用的,使用NULLIF,你可以在查询中将这些值转换为空值,如果参数等于NULLIF,NULLIF会返回空值,否则返回第一个参数的值。
假设薪水数据保存在employee表中,数据类型为整数,却掉的薪水解码为-9999,下面的查询返回薪水的平均值,为了正确地忽略却掉的薪水,查询使用NULLIF将-9999转换为空值。
SELECT AVG(NULLIF(e.salary, -99999))FROM Employeee
COALESCE运算符接收一串参数,从列表中返回第一个非空值,相当于下面的case表达式:
CASE WHEN value1 IS NOT NULL THEN value1
WHEN value2 IS NOT NULL THEN value2
WHEN value3 IS NOT NULL THEN value3
...
ELSE NULL END
COALESCE运算符接收一串参数,从列表中返回第一个非空值,相当于下面的case表达式:
SELECT Name, COALESCE(e.work_phone, e.home_phone) phone FROM Employeee
假设employee表包括一个办公电话号码和家庭电话号码列,无电话号码的列使用空值表示。下面的查询返回每个雇员的姓名和电话号码,COALESCE运算符指定查询返回办公电话号码,但如果为空,则返回家庭电话号码,如果两者都为空,则返回一个空值。
JPA 2.0向JPQL增加的其它运算符是INDEX,TYPE,KEY,VALUE和ENTRY。INDEX运算符指定查询时的排序顺序,TYPE运算符选择一个实体的类型,将查询限制到一或多个实体类型,KEY,VALUE和ENTRY运算符是JPA 2.0中的泛化映射功能的一部分。使用KEY运算符提取映射键,VALUE运算符提取映射值,ENTRY运算符选择一个映射实体。
此外,JPA 2.0增加了选择列表、以及集合值参数和非多态查询中运算符的支持。
标准的API
JPA 2.0中引入的另一个重要特性是标准的API,利用这个API可以动态地构建基于对象的查询,本质上,这个标准API等价于面向对象的JPQL,使用它,你可以使用基于对象的方法创建查询,不再需要JPQL使用的字符串操作。
标准API是基于元模型的,元模型是一个提供了架构级关于持久化单元托管类的元数据的抽象模型, 元模型让你构建强类型的查询,它也允许你浏览持久化单元的逻辑结构。
通常,一个注解处理器使用元模型生成静态元模型类,这些类提供持久化状态和持久化单元托管类的关系,但你可以对静态元模型类编码。下面是一个实体实例:
对应的静态元模型类
此外,JPA 2.0元模型API允许你动态访问元模型,因此当你使用标准API时,既可以静态访问元模型类,也可以动态访问元模型类。标准API提供了更好的灵活性,既可以使用基于对象的方法,又可以使用基于字符串的方法导航元模型,这意味着你有四种使用标准API的方法:
1、静态使用元模型类
2、静态使用字符串
3、动态使用元模型
4、动态使用字符串
无论你使用哪种方法,通过构造一个CriteriaQuery对象定义一个基于标准API的查询时,使用一个工厂对象CriteriaBuilder构造CriteriaQuery,可以从EntityManager 或 EntityManagerFactory类中获得CriteriaBuilder。下面的代码构造一个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对象:
当你向CriteriaQuery对象添加一个或多个查询源后,你访问元模型,然后构造一个查询表达式,你如何做取决于你是以静态方式提交查询还是以动态方式提交查询,以及是使用元模型还是字符串导航元模型。下面是一个使用元模型类静态查询的例子:
cq.select(emp);
cq.where(cb.equal(emp.get(Employee_.lastName), "Smith"));
TypedQuery<Employee> query = em.createQuery(cq);
List<Employee> rows = query.getResultList();
CriteriaQuery接口的select() 和 where()方法指定查询结果返回的选择项目。
注意,你使用EntityManager创建查询时,可以在输入中指定一个CriteriaQuery对象,它返回一个TypedQuery,它是JPA 2.0引入javax.persistence.Query接口的一个扩展,TypedQuery接口知道它返回的类型。
在元模型术语中,Employee_是对应于Employee实体类的规范化元模型类,一个规范化元模型类遵循JPA 2.0规范中描述的某些规则。例如,元模型类的名字来源于托管类,一般都是在托管类名字后面追加一个下划线“_”。一个规范化元模型是一个包含静态元模型类的元模型,这个静态元模型对应于实体,映射的超类,以及持久化单元中的嵌入式类。实际上,这个查询使用了规范化元模型。下面是一个完整的查询:
下面是使用元模型API查询的动态版本:
使用元模型API的标准查询提供了与使用规范化元模型相同的类型,但它比基于规范化元模型的查询更冗长。
Root的getModel()方法返回根对应的元模型实体,它也允许运行时访问在Employee实体中声明的持久化属性。
getSingularAttribute()方法是一个元模型API方法,它返回一个持久化的单值属性或字段,在这个例子中,它返回值为Smith 的lastName属性。下面是使用字符串的元数据导航查询的静态版本:
Java EE 5平台引入了Java持久化API(Java Persistence API, JPA),它为Java EE和Java SE应用程序提供了一个基于POJO的持久化模块。JPA处理关系数据与Java对象之间的映射,它使对象/关系(O/R)映射标准化,JPA已经被广泛采用并且成为O/R持久化企业标准。
Java持久化查询语言增强
JPA 1.0定义了一个广泛的Java持久化查询语言,使用它你可以查询实体和它们的持久化状态。JPA 2.0对JPQL做了大量改进,如现在可以在查询中使用case表达式。在下面的查询中,如果雇员的评分为1,则通过乘以1.1对雇员的薪水进行了增长,如果评分为2,则乘以1.05,其它评分则乘以1.01。
UPDATE Employeee
SET e.salary =
CASE WHEN e.rating = 1 THEN e.salary * 1.1
WHEN e.rating = 2 THEN e.salary * 1.05
ELSE e.salary * 1.01
END
JPA 2.0也为JPQL增加了大量新的运算符,如NULLIF和COALESCE,当数据库使用其它非空数据解码时,NULLIF运算符是非常有用的,使用NULLIF,你可以在查询中将这些值转换为空值,如果参数等于NULLIF,NULLIF会返回空值,否则返回第一个参数的值。
假设薪水数据保存在employee表中,数据类型为整数,却掉的薪水解码为-9999,下面的查询返回薪水的平均值,为了正确地忽略却掉的薪水,查询使用NULLIF将-9999转换为空值。
SELECT AVG(NULLIF(e.salary, -99999))FROM Employeee
COALESCE运算符接收一串参数,从列表中返回第一个非空值,相当于下面的case表达式:
CASE WHEN value1 IS NOT NULL THEN value1
WHEN value2 IS NOT NULL THEN value2
WHEN value3 IS NOT NULL THEN value3
...
ELSE NULL END
COALESCE运算符接收一串参数,从列表中返回第一个非空值,相当于下面的case表达式:
SELECT Name, COALESCE(e.work_phone, e.home_phone) phone FROM Employeee
假设employee表包括一个办公电话号码和家庭电话号码列,无电话号码的列使用空值表示。下面的查询返回每个雇员的姓名和电话号码,COALESCE运算符指定查询返回办公电话号码,但如果为空,则返回家庭电话号码,如果两者都为空,则返回一个空值。
JPA 2.0向JPQL增加的其它运算符是INDEX,TYPE,KEY,VALUE和ENTRY。INDEX运算符指定查询时的排序顺序,TYPE运算符选择一个实体的类型,将查询限制到一或多个实体类型,KEY,VALUE和ENTRY运算符是JPA 2.0中的泛化映射功能的一部分。使用KEY运算符提取映射键,VALUE运算符提取映射值,ENTRY运算符选择一个映射实体。
此外,JPA 2.0增加了选择列表、以及集合值参数和非多态查询中运算符的支持。
标准的API
JPA 2.0中引入的另一个重要特性是标准的API,利用这个API可以动态地构建基于对象的查询,本质上,这个标准API等价于面向对象的JPQL,使用它,你可以使用基于对象的方法创建查询,不再需要JPQL使用的字符串操作。
标准API是基于元模型的,元模型是一个提供了架构级关于持久化单元托管类的元数据的抽象模型, 元模型让你构建强类型的查询,它也允许你浏览持久化单元的逻辑结构。
通常,一个注解处理器使用元模型生成静态元模型类,这些类提供持久化状态和持久化单元托管类的关系,但你可以对静态元模型类编码。下面是一个实体实例:
对应的静态元模型类
此外,JPA 2.0元模型API允许你动态访问元模型,因此当你使用标准API时,既可以静态访问元模型类,也可以动态访问元模型类。标准API提供了更好的灵活性,既可以使用基于对象的方法,又可以使用基于字符串的方法导航元模型,这意味着你有四种使用标准API的方法:
1、静态使用元模型类
2、静态使用字符串
3、动态使用元模型
4、动态使用字符串
无论你使用哪种方法,通过构造一个CriteriaQuery对象定义一个基于标准API的查询时,使用一个工厂对象CriteriaBuilder构造CriteriaQuery,可以从EntityManager 或 EntityManagerFactory类中获得CriteriaBuilder。下面的代码构造一个CriteriaQuery对象:
这个基于字符串的方法要相对容易使用些,但却失去了元模型具有的类型安全.
支持悲观锁
锁是处理数据库事务并发的一种技术,当两个或更多数据库事务并发地访问相同数据时,锁可以保证同一时间只有一个事务可以修改数据。
锁的方法通常有两种:乐观锁和悲观锁。乐观锁认为多个并发事务之间很少出现冲突,也就是说不会经常出现同一时间读取或修改相同数据,在乐观锁中,其目标是让并发事务自由地同时得到处理,而不是发现或预防冲突。两个事务在同一时刻可以访问相同的数据,但为了预防冲突,需要对数据执行一次检查,检查自上次读取数据以来发生的任何变化。
悲观锁认为事务会经常发生冲突,在悲观锁中,读取数据的事务会锁定数据,在前面的事务提交之前,其它事务都不能修改数据。
JPA 1.0只支持乐观锁,你可以使用EntityManager类的lock()方法指定锁模式的值,可以是READ或WRITE,如:
EntityManager em = ... ;
em.lock (p1, READ);
对于READ锁模式,JPA实体管理器在事务提交前都会锁定实体,检查实体的版本属性确定实体自上次被读取以来是否有更新,如果版本属性被更新了,实体管理器会抛出一个OptimisticLockException异常,并回滚事务。
对于WRITE锁模式,实体管理器执行和READ锁模式相同的乐观锁操作,但它也会更新实体的版本列。
JPA 2.0增加了6种新的锁模式,其中两个是乐观锁。JPA 2.0也允许悲观锁,并增加了3种悲观锁,第6种锁模式是无锁。
下面是新增的两个乐观锁模式:
1、OPTIMISTIC:它和READ锁模式相同,JPA 2.0仍然支持READ锁模式,但明确指出在新应用程序中推荐使用OPTIMISTIC。
2、OPTIMISTIC_FORCE_INCREMENT:它和WRITE锁模式相同,JPA 2.0仍然支持WRITE锁模式,但明确指出在新应用程序中推荐使用OPTIMISTIC_FORCE_INCREMENT。
下面是新增的三个悲观锁模式:
1、PESSIMISTIC_READ:只要事务读实体,实体管理器就锁定实体,直到事务完成锁才会解开,当你想使用重复读语义查询数据时使用这种锁模式,换句话说就是,当你想确保数据在连续读期间不被修改,这种锁模式不会阻碍其它事务读取数据。
2、PESSIMISTIC_WRITE:只要事务更新实体,实体管理器就会锁定实体,这种锁模式强制尝试修改实体数据的事务串行化,当多个并发更新事务出现更新失败几率较高时使用这种锁模式。
3、PESSIMISTIC_FORCE_INCREMENT:当事务读实体时,实体管理器就锁定实体,当事务结束时会增加实体的版本属性,即使实体没有修改。
你也可以指定新的锁模式NONE,在这种情况下表示没有锁发生。
JPA 2.0也提供了多种方法为实体指定锁模式,你可以使用EntityManager的lock() 和 find()方法指定锁模式。此外,EntityManager.refresh()方法可以恢复实体实例的状态。
下面的代码显示了使用PESSIMISTIC_WRITE锁模式的悲观锁:
// read
Part p = em.find(Part.class, pId);
// lock and refresh before update
em.refresh(p, PESSIMISTIC_WRITE);
int pAmount = p.getAmount();
p.setAmount(pAmount - uCount);
在这个例子中,它首先读取一些数据,然后应用PESSIMISTIC_WRITE锁,在更新数据之前调用EntityManager.refresh()方法,当事务更新实体时,PESSIMISTIC_WRITE锁锁定实体,其它事务就不能更新相同的实体,直到前面的事务提交。
Java EE 6平台带来了JPA最新版本;Java 持久化2.0,JPA2.0带来了许多新特性和增强。主要包括:
引用
1. 对象/关系映射增强
2. Java持久化查询语言增强
3. 一种新的基于标准的查询API
4. 支持悲观锁定
对象/关系映射增强
JPA 1.0 支持集合的映射,但是这些集合只能包含实体,JPA2.0增加了集合映射的基础数据类型,以及嵌入式对象的集合。JPA中的嵌入式对象是一个不能存在于它自身的对象,而是作为父对象的一部分存在,即它的数据不是存在于它自己的表中,而是嵌入在父对象的表中。
JPA2.0 增加了两个支持新的集合映射的注解:@ElementCollection和@CollectionTable.使用@ElementCollection注解指定集合的嵌入式对象,这些集合是独立存储在集合表中,使用@CollectionTable注解指定集合表的相信信息。
例如:
下面是一个嵌入式类,表示了车辆的访问服务,它存储了访问的日期,描述和费用,此外,车辆可以配备一或多个可选功能,每个功能是FeatureType类型的一个枚举值.
public enum FeatureType{AC,CRUISE,PWR,BLUETOOTH,TV,...} @Embeddable public class ServiceVisit{ @Temporal(DATE) @Column(name="SVC_DATE") Date serviceDate; String workDesc; int cost; }
枚举值和嵌入对象可以在一个表示车辆服务历史的实体中使用,如
@Entity public class Vehicle{ @Id int vin; @ElementCollection @CollectionTable(name="VEH_OPTNS") @Column(name="FEAT") Set<FeatureType>optionalFeatures; @ElementCollection @CollectionTable(name="VEH_SVC") @OrderBy("serviceDate") List<ServiceVisit> serviceHistory; ... }
Vehicle实体中的第一对注解@ElementCollection 和@CollectionTable指定FeatureType值存储在VEH_OPTNS集合表中,第二对注解@ElementCollection 和@CollectionTable指定ServiceVisit嵌入式对象存储在VEH_SVC集合表中。
虽然在例子中没有显示,@ElementCollection注解有两个属性:targetClass 和 fetch。targetClass属性指定基础类或嵌入式类的类名,如果字段或属性是使用泛型定义的,那这两个属性是可选的,上面这个例子就是这样。Fetch属性是可选的,它指定集合是延后检索还是立即检索,使用javax.persistence.FetchType常量,值分别用LAZY和EAGER,默认情况下,集合是延后匹配的。
JPA 2.0中还有其它许多关于对象/关系映射的增强,例如,JPA 2.0支持嵌套式嵌入,关系嵌入和有序列表,也增加了新的注解增强映射功能,通过@Access注解更灵活地支持特定的访问类型,更多用于实体关系的映射选项,如对单向一对多关系的外键映射支持,通过@MapsId注解支持派生身份,支持孤体删除。
Java持久化查询语言增强
JPA 1.0定义了一个广泛的Java持久化查询语言,使用它你可以查询实体和它们的持久化状态。JPA 2.0对JPQL做了大量改进,如现在可以在查询中使用case表达式。在下面的查询中,如果雇员的评分为1,则通过乘以1.1对雇员的薪水进行了增长,如果评分为2,则乘以1.05,其它评分则乘以1.01。
引用
UPDATE Employeee
SET e.salary =
CASE WHEN e.rating = 1 THEN e.salary * 1.1
WHEN e.rating = 2 THEN e.salary * 1.05
ELSE e.salary * 1.01
END
JPA 2.0也为JPQL增加了大量新的运算符,如NULLIF和COALESCE,当数据库使用其它非空数据解码时,NULLIF运算符是非常有用的,使用NULLIF,你可以在查询中将这些值转换为空值,如果参数等于NULLIF,NULLIF会返回空值,否则返回第一个参数的值。
假设薪水数据保存在employee表中,数据类型为整数,却掉的薪水解码为-9999,下面的查询返回薪水的平均值,为了正确地忽略却掉的薪水,查询使用NULLIF将-9999转换为空值。
引用
SELECT AVG(NULLIF(e.salary, -99999))FROM Employeee
COALESCE运算符接收一串参数,从列表中返回第一个非空值,相当于下面的case表达式:
引用
CASE WHEN value1 IS NOT NULL THEN value1
WHEN value2 IS NOT NULL THEN value2
WHEN value3 IS NOT NULL THEN value3
...
ELSE NULL END
COALESCE运算符接收一串参数,从列表中返回第一个非空值,相当于下面的case表达式:
引用
SELECT Name, COALESCE(e.work_phone, e.home_phone) phone FROM Employeee
假设employee表包括一个办公电话号码和家庭电话号码列,无电话号码的列使用空值表示。下面的查询返回每个雇员的姓名和电话号码,COALESCE运算符指定查询返回办公电话号码,但如果为空,则返回家庭电话号码,如果两者都为空,则返回一个空值。
JPA 2.0向JPQL增加的其它运算符是INDEX,TYPE,KEY,VALUE和ENTRY。INDEX运算符指定查询时的排序顺序,TYPE运算符选择一个实体的类型,将查询限制到一或多个实体类型,KEY,VALUE和ENTRY运算符是JPA 2.0中的泛化映射功能的一部分。使用KEY运算符提取映射键,VALUE运算符提取映射值,ENTRY运算符选择一个映射实体。
此外,JPA 2.0增加了选择列表、以及集合值参数和非多态查询中运算符的支持。
标准的API
JPA 2.0中引入的另一个重要特性是标准的API,利用这个API可以动态地构建基于对象的查询,本质上,这个标准API等价于面向对象的JPQL,使用它,你可以使用基于对象的方法创建查询,不再需要JPQL使用的字符串操作。
标准API是基于元模型的,元模型是一个提供了架构级关于持久化单元托管类的元数据的抽象模型, 元模型让你构建强类型的查询,它也允许你浏览持久化单元的逻辑结构。
通常,一个注解处理器使用元模型生成静态元模型类,这些类提供持久化状态和持久化单元托管类的关系,但你可以对静态元模型类编码。下面是一个实体实例:
@Entity public class Employee{ @Id Long Id; String firstName; String lastName; Departement dept; //setter or getter ..... }
对应的静态元模型类
import javax.persistence.meta.model.SingularAttribute import javax.persistence.meta.model.StaticMetamodel; @Generated("EclipseLink JPA 2.0 Canonical Model Generation" @StaticMetamodel(Employee.class) public class Employee_ { public static volatile SingularAttribute<Employee, Long> id; public static volatileSingularAttribute<Employee, String> firstName; public static volatile SingularAttribute<Employee, String> lastName; public static volatile SingularAttribute<Employee, Department> dept; }
此外,JPA 2.0元模型API允许你动态访问元模型,因此当你使用标准API时,既可以静态访问元模型类,也可以动态访问元模型类。标准API提供了更好的灵活性,既可以使用基于对象的方法,又可以使用基于字符串的方法导航元模型,这意味着你有四种使用标准API的方法:
引用
1、静态使用元模型类
2、静态使用字符串
3、动态使用元模型
4、动态使用字符串
无论你使用哪种方法,通过构造一个CriteriaQuery对象定义一个基于标准API的查询时,使用一个工厂对象CriteriaBuilder构造CriteriaQuery,可以从EntityManager 或 EntityManagerFactory类中获得CriteriaBuilder。下面的代码构造一个CriteriaQuery对象:
EntityManager em = ....; CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<Customer> cq = cb.createQuery(Customer.class); ...
注意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对象:
CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<Employee> cq = cb.createQuery(Employee.class); Root<Employee> emp = cq.from(Employee.class);
当你向CriteriaQuery对象添加一个或多个查询源后,你访问元模型,然后构造一个查询表达式,你如何做取决于你是以静态方式提交查询还是以动态方式提交查询,以及是使用元模型还是字符串导航元模型。下面是一个使用元模型类静态查询的例子:
引用
cq.select(emp);
cq.where(cb.equal(emp.get(Employee_.lastName), "Smith"));
TypedQuery<Employee> query = em.createQuery(cq);
List<Employee> rows = query.getResultList();
CriteriaQuery接口的select() 和 where()方法指定查询结果返回的选择项目。
注意,你使用EntityManager创建查询时,可以在输入中指定一个CriteriaQuery对象,它返回一个TypedQuery,它是JPA 2.0引入javax.persistence.Query接口的一个扩展,TypedQuery接口知道它返回的类型。
在元模型术语中,Employee_是对应于Employee实体类的规范化元模型类,一个规范化元模型类遵循JPA 2.0规范中描述的某些规则。例如,元模型类的名字来源于托管类,一般都是在托管类名字后面追加一个下划线“_”。一个规范化元模型是一个包含静态元模型类的元模型,这个静态元模型对应于实体,映射的超类,以及持久化单元中的嵌入式类。实际上,这个查询使用了规范化元模型。下面是一个完整的查询:
EntityManager em = ... ; CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<Employee> cq = cb.createQuery(Employee.class); Root<Employee> emp = cq.from(Employee.class); cq.select(emp); cq.where(cb.equal(emp.get(Employee_.lastName), "Smith")); TypedQuery<Employee> query = em.createQuery(cq); List<Employee> rows = query.getResultList();
下面是使用元模型API查询的动态版本:
EntityManager em = ... ; CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<Employee> cq = cb.createQuery(Employee.class); Root<Employee> emp = cq.from(Employee.class); EntityType<Employee> emp_ = emp.getModel(); cq.select(emp); cq.where(cb.equal(emp.get(emp_.getSingularAttribute("lastName", String.class)),"Smith")); TypedQuery<Employee> query=em.createQuery(cq); List<Employee> rows=query.getResultList();
使用元模型API的标准查询提供了与使用规范化元模型相同的类型,但它比基于规范化元模型的查询更冗长。
Root的getModel()方法返回根对应的元模型实体,它也允许运行时访问在Employee实体中声明的持久化属性。
getSingularAttribute()方法是一个元模型API方法,它返回一个持久化的单值属性或字段,在这个例子中,它返回值为Smith 的lastName属性。下面是使用字符串的元数据导航查询的静态版本:
Java EE 5平台引入了Java持久化API(Java Persistence API, JPA),它为Java EE和Java SE应用程序提供了一个基于POJO的持久化模块。JPA处理关系数据与Java对象之间的映射,它使对象/关系(O/R)映射标准化,JPA已经被广泛采用并且成为O/R持久化企业标准。
Java持久化查询语言增强
JPA 1.0定义了一个广泛的Java持久化查询语言,使用它你可以查询实体和它们的持久化状态。JPA 2.0对JPQL做了大量改进,如现在可以在查询中使用case表达式。在下面的查询中,如果雇员的评分为1,则通过乘以1.1对雇员的薪水进行了增长,如果评分为2,则乘以1.05,其它评分则乘以1.01。
引用
UPDATE Employeee
SET e.salary =
CASE WHEN e.rating = 1 THEN e.salary * 1.1
WHEN e.rating = 2 THEN e.salary * 1.05
ELSE e.salary * 1.01
END
JPA 2.0也为JPQL增加了大量新的运算符,如NULLIF和COALESCE,当数据库使用其它非空数据解码时,NULLIF运算符是非常有用的,使用NULLIF,你可以在查询中将这些值转换为空值,如果参数等于NULLIF,NULLIF会返回空值,否则返回第一个参数的值。
假设薪水数据保存在employee表中,数据类型为整数,却掉的薪水解码为-9999,下面的查询返回薪水的平均值,为了正确地忽略却掉的薪水,查询使用NULLIF将-9999转换为空值。
引用
SELECT AVG(NULLIF(e.salary, -99999))FROM Employeee
COALESCE运算符接收一串参数,从列表中返回第一个非空值,相当于下面的case表达式:
引用
CASE WHEN value1 IS NOT NULL THEN value1
WHEN value2 IS NOT NULL THEN value2
WHEN value3 IS NOT NULL THEN value3
...
ELSE NULL END
COALESCE运算符接收一串参数,从列表中返回第一个非空值,相当于下面的case表达式:
引用
SELECT Name, COALESCE(e.work_phone, e.home_phone) phone FROM Employeee
假设employee表包括一个办公电话号码和家庭电话号码列,无电话号码的列使用空值表示。下面的查询返回每个雇员的姓名和电话号码,COALESCE运算符指定查询返回办公电话号码,但如果为空,则返回家庭电话号码,如果两者都为空,则返回一个空值。
JPA 2.0向JPQL增加的其它运算符是INDEX,TYPE,KEY,VALUE和ENTRY。INDEX运算符指定查询时的排序顺序,TYPE运算符选择一个实体的类型,将查询限制到一或多个实体类型,KEY,VALUE和ENTRY运算符是JPA 2.0中的泛化映射功能的一部分。使用KEY运算符提取映射键,VALUE运算符提取映射值,ENTRY运算符选择一个映射实体。
此外,JPA 2.0增加了选择列表、以及集合值参数和非多态查询中运算符的支持。
标准的API
JPA 2.0中引入的另一个重要特性是标准的API,利用这个API可以动态地构建基于对象的查询,本质上,这个标准API等价于面向对象的JPQL,使用它,你可以使用基于对象的方法创建查询,不再需要JPQL使用的字符串操作。
标准API是基于元模型的,元模型是一个提供了架构级关于持久化单元托管类的元数据的抽象模型, 元模型让你构建强类型的查询,它也允许你浏览持久化单元的逻辑结构。
通常,一个注解处理器使用元模型生成静态元模型类,这些类提供持久化状态和持久化单元托管类的关系,但你可以对静态元模型类编码。下面是一个实体实例:
@Entity public class Employee{ @Id Long Id; String firstName; String lastName; Departement dept; //setter or getter ..... }
对应的静态元模型类
import javax.persistence.meta.model.SingularAttribute import javax.persistence.meta.model.StaticMetamodel; @Generated("EclipseLink JPA 2.0 Canonical Model Generation" @StaticMetamodel(Employee.class) public class Employee_ { public static volatile SingularAttribute<Employee, Long> id; public static volatileSingularAttribute<Employee, String> firstName; public static volatile SingularAttribute<Employee, String> lastName; public static volatile SingularAttribute<Employee, Department> dept; }
此外,JPA 2.0元模型API允许你动态访问元模型,因此当你使用标准API时,既可以静态访问元模型类,也可以动态访问元模型类。标准API提供了更好的灵活性,既可以使用基于对象的方法,又可以使用基于字符串的方法导航元模型,这意味着你有四种使用标准API的方法:
引用
1、静态使用元模型类
2、静态使用字符串
3、动态使用元模型
4、动态使用字符串
无论你使用哪种方法,通过构造一个CriteriaQuery对象定义一个基于标准API的查询时,使用一个工厂对象CriteriaBuilder构造CriteriaQuery,可以从EntityManager 或 EntityManagerFactory类中获得CriteriaBuilder。下面的代码构造一个CriteriaQuery对象:
EntityManager em = ... ; CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<Employee> cq = cb.createQuery(Employee.class); Root<Employee> emp = cq.from(Employee.class); cq.select(emp); cq.where(cb.equal(emp.get("lastName"), "Smith")); TypedQuery query = em.createQuery(cq); List <Employee>rows = query.getResultList();
这个基于字符串的方法要相对容易使用些,但却失去了元模型具有的类型安全.
支持悲观锁
锁是处理数据库事务并发的一种技术,当两个或更多数据库事务并发地访问相同数据时,锁可以保证同一时间只有一个事务可以修改数据。
锁的方法通常有两种:乐观锁和悲观锁。乐观锁认为多个并发事务之间很少出现冲突,也就是说不会经常出现同一时间读取或修改相同数据,在乐观锁中,其目标是让并发事务自由地同时得到处理,而不是发现或预防冲突。两个事务在同一时刻可以访问相同的数据,但为了预防冲突,需要对数据执行一次检查,检查自上次读取数据以来发生的任何变化。
悲观锁认为事务会经常发生冲突,在悲观锁中,读取数据的事务会锁定数据,在前面的事务提交之前,其它事务都不能修改数据。
JPA 1.0只支持乐观锁,你可以使用EntityManager类的lock()方法指定锁模式的值,可以是READ或WRITE,如:
引用
EntityManager em = ... ;
em.lock (p1, READ);
对于READ锁模式,JPA实体管理器在事务提交前都会锁定实体,检查实体的版本属性确定实体自上次被读取以来是否有更新,如果版本属性被更新了,实体管理器会抛出一个OptimisticLockException异常,并回滚事务。
对于WRITE锁模式,实体管理器执行和READ锁模式相同的乐观锁操作,但它也会更新实体的版本列。
JPA 2.0增加了6种新的锁模式,其中两个是乐观锁。JPA 2.0也允许悲观锁,并增加了3种悲观锁,第6种锁模式是无锁。
下面是新增的两个乐观锁模式:
引用
1、OPTIMISTIC:它和READ锁模式相同,JPA 2.0仍然支持READ锁模式,但明确指出在新应用程序中推荐使用OPTIMISTIC。
2、OPTIMISTIC_FORCE_INCREMENT:它和WRITE锁模式相同,JPA 2.0仍然支持WRITE锁模式,但明确指出在新应用程序中推荐使用OPTIMISTIC_FORCE_INCREMENT。
下面是新增的三个悲观锁模式:
引用
1、PESSIMISTIC_READ:只要事务读实体,实体管理器就锁定实体,直到事务完成锁才会解开,当你想使用重复读语义查询数据时使用这种锁模式,换句话说就是,当你想确保数据在连续读期间不被修改,这种锁模式不会阻碍其它事务读取数据。
2、PESSIMISTIC_WRITE:只要事务更新实体,实体管理器就会锁定实体,这种锁模式强制尝试修改实体数据的事务串行化,当多个并发更新事务出现更新失败几率较高时使用这种锁模式。
3、PESSIMISTIC_FORCE_INCREMENT:当事务读实体时,实体管理器就锁定实体,当事务结束时会增加实体的版本属性,即使实体没有修改。
你也可以指定新的锁模式NONE,在这种情况下表示没有锁发生。
JPA 2.0也提供了多种方法为实体指定锁模式,你可以使用EntityManager的lock() 和 find()方法指定锁模式。此外,EntityManager.refresh()方法可以恢复实体实例的状态。
下面的代码显示了使用PESSIMISTIC_WRITE锁模式的悲观锁:
引用
// read
Part p = em.find(Part.class, pId);
// lock and refresh before update
em.refresh(p, PESSIMISTIC_WRITE);
int pAmount = p.getAmount();
p.setAmount(pAmount - uCount);
在这个例子中,它首先读取一些数据,然后应用PESSIMISTIC_WRITE锁,在更新数据之前调用EntityManager.refresh()方法,当事务更新实体时,PESSIMISTIC_WRITE锁锁定实体,其它事务就不能更新相同的实体,直到前面的事务提交。
发表评论
-
java实现读取文件下所有的excel文件
2012-08-10 09:30 2010最近处理一个压缩包,里面有几百上千个excel文件。本来 ... -
在firefox浏览器下出现如果引用外部连接不存在会隐藏红叉
2012-07-23 15:38 960在firefox下引用出错的一些图片会隐藏红叉。而在IE下 ... -
java 字符替换的一些问题值得记录下
2011-09-30 16:40 844最近在处理一些字符串的替换中发生的一些问题。 最近需要临 ... -
ExtJs学习之弹出框,提示框,输入框等框
2011-06-23 22:13 92661.ExtJs之消息框: 语法:Ext.MessageB ... -
FreeMarker学习之概念
2010-08-04 10:12 829FreeMarker概述: 引用 1. ... -
HTML标准属性
2010-07-03 20:35 723核心属性(Core attributes) 以下标签 ... -
HTML标签
2010-07-03 20:14 965HTML 4.01 / XHTML 1.0 参考手册 按字母 ... -
HTML基础
2010-07-03 00:54 736基于Web前端技术是有HTML静态语言向现在的JaveSc ... -
Struts2的开发规范和技巧
2010-05-28 14:56 1199基于Struts2的开发,如果没有足够的经验和规范做支撑,并不 ... -
第一次的Struts2的一个异常记录
2010-05-28 14:22 987在配置正确struts.xml、web.xml、Action类 ... -
Java处理Excel全解一
2010-05-25 10:00 2150在获取客户需求的时候 ... -
Java EE 6 规范之平台概述
2010-05-22 21:28 2179JavaTM平台企业版(Java EETM)的概述 体系结构 ... -
Python3入门学习
2010-05-14 14:51 2193在学习一门计算机语言的时候,首先接触的入门程序基本上都是& ... -
Python3操作文件,目录和路径
2010-05-14 11:48 34651.遍历文件夹和文件 ... -
内存溢出
2010-04-22 14:23 1382java SE应用程序共同的问 ... -
JPA之ManyToMany的处理
2010-04-18 14:17 4475在处理关系中,最为麻烦的可能是多对多的关系处理,因为多对多 ... -
JPA之OneToOne关系处理
2010-04-18 14:05 3906在很早学习关系数据库的时候学过一对多,多对一,一对一,多对多的 ... -
JPA之OneToMany和ManyToOne处理
2010-04-18 13:52 18886前面介绍和总结了JPA ... -
JPA学习之二(入门篇)
2010-04-16 10:48 3721简单总结下,JPA的入门。在学习JPA的时候运用参考Hib ... -
读取Properties文件的一些方法
2010-03-13 22:53 1122读取Properties文件常见的 ...
相关推荐
一步一步学SpringDataJpa——JpaRepository查询功能 - CSDN博客https://blog.csdn.net/ming070423/a
使用 Netbeans 开发JSF 2.0,使用Primefaces 及JPA ,一步一步指导如何开发
spring注解完整版+spring data jpa官方文档中文翻译+JPA2.0官方文档 文档内容齐全 值得参考学习
环境:Window XP Professional, JDK 1.6, Eclipse 3.3 Europa, JBoss 4.2.1, Mysql 5.0 理由:持久层技术从EJB 2.0的实体bean开始,...代码几乎一行一注释,非常详细的说明了使用JPA的步骤,是学习JPA编程的好例子。
1、本示例只是借花献佛,其实网上SpringMVC+Hibernate-JPA的示例代码一大堆,但是有源代码的demo很少,而且大部分介绍不全面,容易造成学习误区。我也是曾经学习网上示例来完成这个demo。本人是参考...
该demo使用springboot2.0建立,然后搭配Security+jsonwebToken实现了不同路径的权限控制访问,里面还实现了根据角色跳转不同页面的功能,里面也结合了mybatis和jpa的相关操作,也是一般大众学员的学习内容
1、本示例只是借花献佛,其实网上SpringMVC+Hibernate-JPA的示例代码一大堆,但是有源代码的demo很少,而且大部分介绍不全面,容易造成学习误区。我也是曾经学习网上示例来完成这个demo。本人是参考...
第三部分提供了一个jsf+ejb 3+ jpa整合开发的项目:电子拍卖系统。这个项目包括5个实体,这5个实体之间具有复杂的关联关系,而且业务逻辑也相对复杂,希望让读者理论联系实际,真正将jsf+ejb 3+jpa整合真正运用到...
hibernate3.jar、hibernate-jpa-2.0-api-1.0.1.Final.jar、antlr-2.7.6.jar、commons-collections-3.1、dom4j-1.6.1.jar、javassist-3.12.0.GA.jar、jta-1.1.jar、slf4j-api-1.6.1.jar、slf4j-nop-1.6.2.jar
万维网中SWE642-软件工程中执行的任务 专注于, 客户端和服务器端软件设计...以实现统一一致的外观和布局,JDBC,Java Persistence API(JPA 2.0),Enterprise JavaBeans(EJB 3),以及允许RESTful Web服务的时间。
该项目的设置允许您使用Spring MVC,JPA 2.0和Bean Validation 1.0创建兼容的Spring 3.1应用程序。 它包括一个持久性单元以及一些示例性持久性和事务代码,以向您介绍企业Java中的数据库访问。 该示例使用由应用...
该项目设置为允许您使用 CDI 1.0、EJB 3.1、JPA 2.0 和 Bean Validation 1.0 创建兼容的 Java EE 7 应用程序。 它包括一个持久性单元和一些示例持久性和事务代码,向您介绍企业 Java 中的数据库访问。 系统要求 ...
本项目使用的是 SpringBoot1.5.9 版本,起初用的是 SpringBoot 2.0,但是觉得还是会遇到很多问题,而且新版本也缺少资料,于是中途修改了版本。 ORM框架用的 Spring Data JPA,权限管理用的是 Spring Security。 以 ...
基于SpringBoot的权限管理...核心技术采用Spring、Security、Oauth2.0、JPA没有任何其它重度依赖。直接运行即可用。资源来源网络以及部分开源社区仅供参考与学习项目不可商用、一切后果由使用者承担若是侵权请联系删除
chapter2-1-2:2.0 新特性(一):配置绑定全解析 chapter2-2-1:2.0 新特性(二):新增事件ApplicationStartedEvent Web开发 chapter3-1-1:构建一个较为复杂的RESTful API以及单元测试 chapter3-1-2:使用...
一、开发struts1应用的基本步骤...283 二、Struts的工作流程......................284 三、struts-config.xml配置文件中主要的元素和属性.........286 四、RequestProccessor.....................287 五、Struts1...
一、 Spring介绍 1 1.1、SpringBoot简介 1 1.2、系统要求: 1 1.3、SpringBoot和SpringMVC区别 1 1.4、SpringBoot和SpringCloud区别 2 1.5常见错误 2 二、快速入门 2 2.1、创建一个Maven工程 2 2.2、pom文件...
springboot2.0+jpa+theamleaf+mysql集成开发demo,供大家学习参考了
JPA 2.0为了弥补JPA1.0的不足,才将这种Query的思想引入为框架中的另一套查询体系——Criteria API。事实上针对单个对象的get/load/persist/save/update/merge/saveOrUpdate API和Criteria API本来就为一体,只不过...
Spring2.5相比Spring 2.0和更低版本来说,虽然核心思想和原理一脉相承,但在使用和功能上都有了很大的升级和改动,Spring 2.5使得应用更加简洁方便,开发效率更高,功能更加强大。 你想了解Spring 2.5吗?你想学习...