直接進入正題
假設有一個實體類
/**
* 產品分類
*/
public class ProductType{
@Id
private String no;//編號
private String name;//名稱
}
/**
* 產品
*/
public class Product{
@Id
private String no;//編號
private String name;//名稱
private ProductType productType;
//...省略setter和getter方法
}
假設:ProductType 有如下數據:
no name
1 產品分類1
2 產品分類2
3 產品分類3
假設:Product 有如下數據:
no name productTypeNo
1000 產品一 1
1001 產品一 1
1003 產品二 2
1004 產品二 2
1005 產品三 3
使用場景:需要產品編號按連號顯示:
1000-1002 產品一 產品分類1
1003-1004 產品二 產品分類2
1005-1005 產品三 產品分類3
以下是Criteria查詢實現
Criteria criteria = session.createCriteria(Product.class,"p");
ProjectionList plist = Projections.projectionList();
plist.add(Projections.sqlProjection("min(no) || '-' || max(no)",new String[]{"no"},new Type[]{StringType.INSTANCE}))
.add(Projections.groupProperty("name"))
.add(Projections.groupProperty("ptype.name").as("productTypeName"));
criteria.setProjection(plist);
criteria.list();
注意事項如下:
1、由於需要獲取productType中的屬性,也就是需要聯合查詢,所以必須執行criteria查詢是必須指定criteria.createAlias("productType","ptype");
2、由於執行SQL語句,而該查詢中兩個實體中都含有相同的屬性no,所以必須指定no所屬實例,上面紅色部分必須更改為"min({alias}.no) || '-' || max({alias}.no)"
程序最終實現應該如下:
Criteria criteria = session.createCriteria(Product.class,"p");
ProjectionList plist = Projections.projectionList();
criteria.createAlias("productType","ptype");
plist.add(Projections.sqlProjection("min({alias}.no) || '-' || max({alias}.no)",new String[]{"no"},new Type[]{StringType.INSTANCE}))
.add(Projections.groupProperty("name"))
.add(Projections.groupProperty("ptype.name").as("productTypeName"));
criteria.setProjection(plist);
criteria.list();
總結:
1、Criteria 查詢,需要獲取非關聯字段信息時,必須創建關聯表criteria.createAlias("productType","ptype");
2、Criteria 查詢,主表和關聯表有相同數據庫字段,且需要使用原始SQL語句時,必須指定別名,否則將無法找到指定列,而報“未明確指定列”的錯誤
min({alias}.no) || '-' || max({alias}.no)中{alias}會在運行時由Hibernate自動指定。