首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Hibernate 屬性查詢(Projection)入門:精準查詢所需欄位,提升效能

     編輯:Java 相關知識

HQL 預設查詢整個實體物件,但實際往往只需部分欄位。屬性查詢(Projection) 讓你僅選取必要欄位,減少資料傳輸與物件建構開銷,提升查詢效能。本文介紹兩種寫法:陣列回傳與建構子封裝。

基本語法:選取特定屬性

List list = session.createQuery(
  "select user.name, user.age from TUser user").list();

Iterator it = list.iterator();
while (it.hasNext()) {
  Object[] results = (Object[]) it.next();
  System.out.println(results[0]); // name
  System.out.println(results[1]); // age
}

回傳 List,每筆為 Object[],順序對應 SELECT 子句。

進階:建構子封裝為領域物件

若偏好物件導向風格,可使用 new ClassName(prop1, prop2) 語法:

List list = session.createQuery(
  "select new TUser(user.name, user.age) from TUser user").list();

Iterator it = list.iterator();
while (it.hasNext()) {
  TUser user = (TUser) it.next();
  System.out.println(user.getName());
}

TUser 需提供對應建構子

public class TUser {
  private String name;
  private int age;
  // 必須有此建構子
  public TUser(String name, int age) {
    this.name = name;
    this.age = age;
  }
  // getter/setter...
}

關鍵限制:查詢出的物件為「瞬態」

透過建構子產生的 TUser 物件:

  • 僅包含建構子賦值的屬性,其他屬性為 null/預設值
  • 不在 Session 管理範圍內(非持久化狀態)
  • 不可直接 saveOrUpdate()**:會導致 INSERT** 而非 UPDATE
// 錯誤示範
while (it.hasNext()) {
  TUser user = (TUser) it.next();
  user.setName("test");
  session.saveOrUpdate(user); // 產生 INSERT,非預期 UPDATE
}

支援彙總函數

可直接使用 SQL 風格彙總函數:

select count(*), min(user.age) from TUser user
select upper(user.name) from TUser user
select distinct user.name from TUser user

效能效益

查詢方式資料傳輸量物件建構適用場景
完整實體查詢所有欄位完整物件(含關聯)需完整物件圖、後續修改持久化
屬性查詢(陣列)僅所需欄位Object[]唯讀報表、列表頁、DTO 組裝
屬性查詢(建構子)僅所需欄位自訂 DTO/VO傳遞給 View/前端、報表物件

Criteria API 寫法

Criteria criteria = session.createCriteria(TUser.class);
criteria.setProjection(Projections.projectionList()
  .add(Projections.property("name"), "name")
  .add(Projections.property("age"), "age"));
criteria.setResultTransformer(Transformers.aliasToBean(TUserDTO.class));
List results = criteria.list();

總結

屬性查詢是優化 Hibernate 讀取效能的關鍵技巧。報表、列表、唯讀場景務必使用。建構子封裝雖好用,但記住:產出的物件為瞬態,不可直接持久化操作。搭配 ResultTransformer 可無縫映射至 DTO,維持乾淨架構。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved