首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Hibernate 一對多查詢關聯表非空字段記錄數:HQL / Criteria 實現

     編輯:程式設計綜合問答

實體關係


@Entity @Table(name="drp_yp")
public class Drug {
    @Id Long id;
    @OneToMany(mappedBy="drug", fetch=FetchType.LAZY)
    List images; // 多方
}

@Entity @Table(name="drp_tp")
public class DrugImage {
    @Id Long id;
    @ManyToOne @JoinColumn(name="drug_id")
    Drug drug;
    String filepath; // 可為 null
    String category; // 分類,某些記錄 filepath 為 null
}

需求

查詢某藥品下 `filepath IS NOT NULL` 的圖片記錄數。

方案一:HQL (最簡潔)


String hql = "SELECT COUNT(img) FROM DrugImage img WHERE img.drug.id = :drugId AND img.filepath IS NOT NULL";
Long count = (Long) session.createQuery(hql)
    .setParameter("drugId", drugId)
    .uniqueResult();

方案二:Criteria API (類型安全)


CriteriaBuilder cb = session.getCriteriaBuilder();
CriteriaQuery cq = cb.createQuery(Long.class);
Root root = cq.from(DrugImage.class);
cq.select(cb.count(root))
  .where(cb.and(
      cb.equal(root.get("drug").get("id"), drugId),
      cb.isNotNull(root.get("filepath"))
  ));
Long count = session.createQuery(cq).uniqueResult();

方案三:`@Formula` 映射到藥品實體 (若頻繁讀取)


@Entity @Table(name="drp_yp")
public class Drug {
    @Id Long id;
    
    @Formula("(SELECT COUNT(*) FROM drp_tp img WHERE img.drug_id = id AND img.filepath IS NOT NULL)")
    private Integer validImageCount; // 自動查詢,映射為只讀屬性
    
    // Getter
}

使用:`drug.getValidImageCount()` 直接獲取,無需額外查詢代碼。

JSP/前端顯示問題排查

原問題:`fn:length(images)` 返回含 `filepath=null` 的總數。
**原因**:`fn:length` 只統計集合大小,不檢查屬性值。
**修正**:

  • 後台查詢上述 `count` 傳給前端 `${drug.validImageCount}`。
  • 或前端 JSTL 過濾:
    ``
    ` 計數++`
    `
    `

原回答補充

原最佳回答「最後還是加了個字段並且新建了個方法」屬於臨時方案。上文提供三種標準 ORM 級解決方案,`@Formula` 最優雅且性能可控 (可加緩存)。

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