JPA 2.1 早期草案解釋

fmms 12年前發布 | 10K 次閱讀 JPA

Java Persistence API 2.1 Early Draft 已經發布了一個月左右,JPA2 是 Java EE 7 的首個 JSR。

下面是 JPA 2.1 主要的新特性:

  • 支持存儲過程: Java 持久化查詢語言支持預定義的數據庫函數和用戶自定義函數

    There are different variants of EntityManager.createXXXStoredProcedureQuery methods that return a StoredProcedureQuery 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 in EntityManager.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 client

    StoredProcedreQuery 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, refactored AbstractQuery 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 < 10000

    This 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 between Order and Product but name and ISBN are attributes of the Book class which is a subclass of the Product class. Another example is:

      SELECT e FROM Employee e
      WHERE TREAT(e AS Exempt).vacationDays > 10
      OR TREAT(e AS Contractor).hours > 100


      Here again vacationDays are attributes for Exempt employees only and hours only for Contractor.

    • 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


      The s.id = p.supplierId condition is generated becase of the LEFT JOIN. The additional JOIN condition of p.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 to Fetch, Join, CollectionJoin, SetJoin, ListJoin, and MapJoin interfaces to support the ON clause.
  • 透過 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 中。

 本文由用戶 fmms 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!