Stories

Detail Return Return

記錄 Hibernate 創建和執行查詢學習 - Stories Detail

Hibernate

Hibernate是一個開源的對象關係映射框架(ORM),將Java應用程序中的對象與關係型數據庫之間的數據存儲和檢索進行映射。
Hibernate還提供了一種稱為Hibernate Query Language(HQL)的查詢語言,這提供了一定程度的數據庫獨立性。
image.png
以user表為例,通過ORM即可將類中的字段映射為數據庫中的表。

查詢

數據庫查詢分為三個步驟:

  1. 創建查詢語句
  2. 準備查詢語句
  3. 執行查詢語句

創建查詢語句

先介紹幾個縮寫:

  • SQL: 結構化查詢語言。用來查詢數據用的,通過代碼指令來實現個性化的數據處理。
  • JPQL:Java Persistence Query Language,Java持久性查詢語言
  • HQL: Hibernate Query Language,Hibernate查詢語言。跟JPQL一樣是面向對象的查詢語言,允許開發人員以對象模型而非數據庫模型來編寫查詢。因為Hibernate實現了JPA規範,其中包括JPQL,所以在很大程度上與JPQL相似。

JPA 查詢接口

JPA(Java Persistence API)是Java平台上的一種ORM(對象關係映射)規範,而Hibernate是它的一種實現;
JPA使用Query和TypedQuery實例來表示一個查詢。

創建查詢
  1. 使用JPQL,從數據庫中檢索所有的Item實體實例

    Query query = em.createQuery("select i from Item i");

    JPQL的使用與SQL很類似。
    其中em是EntityManager的實例,EntityManager是Java Persistence API(JPA)中的一個接口,用於管理實體對象的生命週期和執行與這些對象相關的持久性操作。它是JPA的核心接口之一,提供了一種將實體對象與數據庫進行交互的機制。

  2. 使用CriteriaBuilder 和 CriteriaQuery API創建查詢

    CriteriaBuilder cb = em.getCriteriaBuilder();
    // CriteriaBuilder cb = entityManagerFactory.getCriteriaBuilder();
    
    CriteriaQuery criteria = cb.createQuery();
    criteria.select(criteria.from(Item.class));
    
    Query query = em.createQuery(criteria);

    使用這種方式創建的CriteriaQuery不帶有字符串,這意味着查詢將是安全的並且包含在重構操作中的。

  3. 使用原生SQL

    Query query = em.createNativeQuery(
     "select * from ITEM", Item.class
    );
類型化查詢結果:

如果使用Query,在查出結果後需要進行類型轉換。

Query query = em.createQuery(
    "select i from Item i where i.id = :id"
).setParameter("id", ITEM_ID);
Item result = (Item) query.getSingleResult();

使用TypedQuery

TypedQuery<Item> query = em.createQuery(
    "select i from Item i where i.id = :id"
).setParameter("id", ITEM_ID);
Item result = query.getSingleResult();
Hibernate的查詢結果

Hibernate的查詢表達式形式就是org.hibernate.Query和org.hibernate.SQLquery。因為Hibernate是JPA的實現,所以Hibernate提供的接口更多,當然移植性會相應變差。

  1. Hibernate 獨有的SQL結果映射工具:

    Session session = em.unwrap(Session.class);
    org.hibernate.SQLQuery query = session.createSQLQuery(
     "select {i.*} from ITEM {i}"
    ).addEntity("i", Item.class);

    該例中,通過SQL的佔位符將java.sql.ResultSet的列映射到實體屬性。

在 Hibernate 中,Session 對象是核心的數據訪問對象,用於執行數據庫操作。unwrap 方法用於獲取底層的實現對象,以便執行特定於實現的操作。

  1. 較老的專有查詢API

    org.hibernate.Criteria query = session.createCriteria(Item.class);
    query.add(org.hibernate.criterion.Restrictions.eq("id", ITEM_ID));
  2. 類型轉換(JPA.Query => Hibernate.Query)
    給定一個專有的 javax.persistence.Query,可以通過解包一個org.hibernate.jpa.HibernateQuery 來訪問Hibernate專有的API

    javax.persistence.Query query = em.createQuery(
     // ...
    );
    
    org.hibernate.Query HibernateQuery = query.unwrap(org.hibernate.jpa.HibernateQuery.class).getHibernateQuery();
    
    hibernateQuery.getQueryString();
    hibernateQuery.getResultAliases();
    // ...

    參考

    《Hibernate 實戰》

Add a new Comments

Some HTML is okay.