Java Persistence API 2.1 Early Draft 已经发布了一个月左右,JPA2 是 Java EE 7 的首个 JSR。
下面是 JPA 2.1 主要的新特性:
- 支持存储过程: Java 持久化查询语言支持预定义的数据库函数和用户自定义函数
There are different variants ofEntityManager.createXXXStoredProcedureQuery
methods that return aStoredProcedureQuery
for executing a stored procedure. Just liked@NamedQuery
, there is@NamedStoredProcedureQuery
that specifies and names a stored procedure, its parameters, and its result type. This annotation can be specified on an entity or mapped superclass. The name specified in the annotation is then used inEntityManager.createNamedStoredProcedureQuery
. The IN, OUT, and INOUT parameters can be set and used to retrieve values passed back from the procedure. For example:@Entity
@NamedStoredProcedureQuery(name="topGiftsStoredProcedure", procedureName="Top10Gifts")
public class Product {
. . .
}
// In your clientStoredProcedreQuery query = EntityManager.createNamedStoredProcedureQuery("topGiftsStoredProcedure");
query.registerStoredProcedureParameter(1, String.class, ParameterMode.INOUT);
query.setParameter(1, "top10");
query.registerStoredProcedureParameter(2, Integer.class, ParameterMode.IN);
query.setParameter(2, 100);
// there are other setParameter methods for defining the temporal type of a parameter
. . .
query.execute();
String response = query.getOutputParameterValue(1);
The section 3.8.6 provide more details. - 可通过 Criteria 批量的更新和删除数据: Added
CriteriaUpdate
,CriteriaDelete
,CommonAbstractQuery
interfaces, refactoredAbstractQuery
interface.
Here is a sample for
CriteriaUpdate
from section 6.5.15:CriteriaUpdate<Customer> q = cb.createCriteriaUpdate(Customer.class);
Root<Customer> c = q.from(Customer.class);
q.set(c.get(Customer_.status), "outstanding")
.where(cb.lt(c.get(Customer_.balance), 10000));with the equivalent JPQL of:
UPDATE Customer c
SET c.status = 'outstanding'
WHERE c.balance < 10000This query can then be executed as:
@PersistenceContext EntityManager em;
Query query = em.createQuery(q);
query.executeUpdate();Here is a sample for
CriteriaDelete
from section 6.5.15:CriteriaDelete<Customer> q = cb.createCriteriaDelete(Customer.class);
Root<Customer> c = q.from(Customer.class);
q.where(cb.equal(c.get(Customer_.status), "inactive"),
cb.isEmpty(c.get(Customer_.orders)));with the equivalent JPQL of:
DELETE FROM Customer c
WHERE c.status = 'inactive'
AND c.orders IS EMPTY
This query can then be executed in similar way as earlier:
@PersistenceContext EntityManager em;
Query query = em.createQuery(q);
query.executeUpdate(); - 新的保留关键字: 包括:
FUNCTION
,ON
,TREAT
.- Pre-defined and user-defined functions using FUNCTION: JPQL provide several in-built functions which may be used in the SELECT, WHERE or HAVING clause of a query such as CONCAT, SUBSTRING, TRIM, LENGTH, ABS, SQRT, and CURRENT_DATE. The section 4.6.17.3 define invocation of predefined and user-defined database functions using the FUNCTION operator. The
FUNCTION
is used to invoke predefined database functions or user-defined database functions. An example from the section is:SELECT c
FROM Customer c
WHERE FUNCTION(‘hasGoodCredit’, c.balance, c.creditLimit) - Downcasting using TREAT:
TREAT
is supported for downcasting within path expressions in the FROM and WHERE clauses. Use of the TREAT operator allows access to subclass-specific state. An example from section 4.4.9 is:
SELECT b.name, b.ISBN
FROM Order o JOIN TREAT(o.product AS Book) b
In this example, the join is performed betweenOrder
andProduct
butname
andISBN
are attributes of theBook
class which is a subclass of theProduct
class. Another example is:SELECT e FROM Employee e
WHERE TREAT(e AS Exempt).vacationDays > 10
OR TREAT(e AS Contractor).hours > 100
Here againvacationDays
are attributes forExempt
employees only andhours
only forContractor
.
- Join condition using ON: The ON clause in SQL is used to specify the relationship between the tables. It is different from the WHERE clause which specifies the criteria for the rows to be picked. An example from the section 4.4.5.2 shows the JPQL as:
SELECT s.name, COUNT(p)
FROM Suppliers s LEFT JOIN s.products p
ON p.status = 'inStock'
GROUP BY s.name
The mapped SQL for this will be:SELECT s.name, COUNT(p.id)
FROM Suppliers s LEFT JOIN Products p
ON s.id = p.supplierId AND p.status = 'inStock'
GROUP BY s.name
Thes.id = p.supplierId
condition is generated becase of the LEFT JOIN. The additional JOIN condition ofp.status = 'inStock'
is also added to the generated SQL because of the ON clause in the JPQL. The result of this query will include all suppliers (with possibly NULL values). This is different from the query below:
SELECT s.name, COUNT(p)
FROM Suppliers s LEFT JOIN s.products p
WHERE p.status = 'inStock'
GROUP BY s.name
The result of this query will not include suppliers that have no products in stock.
Additional methods are also added toFetch
,Join
,CollectionJoin
,SetJoin
,ListJoin
, andMapJoin
interfaces to support the ON clause.
- Pre-defined and user-defined functions using FUNCTION: JPQL provide several in-built functions which may be used in the SELECT, WHERE or HAVING clause of a query such as CONCAT, SUBSTRING, TRIM, LENGTH, ABS, SQRT, and CURRENT_DATE. The section 4.6.17.3 define invocation of predefined and user-defined database functions using the FUNCTION operator. The
- 透过 CDI 实现实体类的侦听器: Entity Listeners allow to handle cross-cutting lifecycle events in a non-persistent listener class. In JPA 2.1, entity listeners will support dependency injection through CDI. The usual lifecycle callback methods of
@PrePersist
,@PostPersist
,@PreUpdate
, and@PreRemove
can be used for entities. The entity listeners can also be annotated with@PostConstruct
and@PreDestroy
for their own lifecycle. The section 3.5.1 provides more details on this.
Read more details on jsr338-experts alias archive and users@jpa-spec. - 持久化上下文的同步: In JPA 2, the persistence context is synchronized with the underlying resource manager. Any updates made to the persistence context are propagated to the resource manager. JPA 2.1 introduces the concept of unsynchronized persistence contenxt. Here is how you can create a container-managed unsynchronized persistence context:
@PersistenceContext(synchronization=SynchronizationType.UNSYNCHRONIZED) EntityManager em;
The section 7.6.1 provide more details. - Several clarifications in text and javadocs
更多相关介绍链接:
JPA 2.1 将包含在 GlassFish 4.0 中。