@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` 的圖片記錄數。
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();
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();
@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()` 直接獲取,無需額外查詢代碼。
原問題:`fn:length(images)` 返回含 `filepath=null` 的總數。
**原因**:`fn:length` 只統計集合大小,不檢查屬性值。
**修正**:
原最佳回答「最後還是加了個字段並且新建了個方法」屬於臨時方案。上文提供三種標準 ORM 級解決方案,`@Formula` 最優雅且性能可控 (可加緩存)。