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

Hibernate IN 查詢參數列表為空時的解決方案與最佳實踐

     編輯:Java 相關知識

問題場景

使用 Hibernate HQL 執行 IN (:agentIds) 查詢時,若參數列表 ids 為空集合,直接呼叫 query.setParameterList("agentIds", ids) 會拋出異常。

原始碼片段

StringBuffer buf = new StringBuffer();
if (!forObject) { buf.append("select count(*) "); }
buf.append("from Agent agent where 1=1 ");

String gradeId = (String) conditions.get("gradeId");
if (gradeId != null && !gradeId.equals("")) {
    buf.append(" and agent.gradeId=").append(gradeId);
}

buf.append(" and agent.agentId in (:agentIds) ");

Query query = sess.createQuery(buf.toString());
List ids = CommisionInfoDelegateExt.findAgentIdList(conditions);
System.out.println("ids.length=" + ids.size());
query.setParameterList("agentIds", ids);  // ids 為空時拋異常

臨時解法(不推薦)

在列表塞入一個絕不存在的 ID(如 "-1"):

if (ids.isEmpty()) ids.add("-1");

缺點:汙染查詢邏輯、潛在效能影響、非語意正確。

推薦解法:動態構建 HQL

List ids = CommisionInfoDelegateExt.findAgentIdList(conditions);
StringBuffer buf = new StringBuffer();
if (!forObject) buf.append("select count(*) ");
buf.append("from Agent agent where 1=1 ");

String gradeId = (String) conditions.get("gradeId");
if (gradeId != null && !gradeId.equals("")) {
    buf.append(" and agent.gradeId = :gradeId");
}

if (ids != null && !ids.isEmpty()) {
    buf.append(" and agent.agentId in (:agentIds) ");
}

Query query = sess.createQuery(buf.toString());
if (gradeId != null && !gradeId.equals("")) {
    query.setParameter("gradeId", gradeId);
}
if (ids != null && !ids.isEmpty()) {
    query.setParameterList("agentIds", ids);
}

替代方案:Criteria API

Criteria crit = sess.createCriteria(Agent.class);
if (gradeId != null && !gradeId.equals("")) {
    crit.add(Restrictions.eq("gradeId", gradeId));
}
if (ids != null && !ids.isEmpty()) {
    crit.add(Restrictions.in("agentId", ids));
}
// 若 ids 為空,不加入 in 條件,等同查詢全部(視業務而定)
List results = crit.list();

最佳實踐總結

  1. 檢查集合是否為空,動態決定是否加入 IN 子句。
  2. 優先使用 Criteria API 或 JPA Metamodel 進行型別安全的動態查詢構建。
  3. 避免字串拼接 SQL/HQL,防止注入風險與語法錯誤。
  4. 若業務允許「空列表查無資料」,可在 Service 層預先判斷回傳空結果,省去資料庫查詢。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved