Hibernate支持SQLQuery(特定數據庫平臺有關的sql語句)和Query(hql)查詢方式,當然還有Criteria對象查詢方式;本文介紹SQLQuery和Query的幾種傳參的方式和注意事項;
SQLQuery
1、查詢結果映射到map,:param傳參
public List<Map<String, Object>> findMapBySql(String sql, Map<String, Object> params) {
SQLQuery sqlQuery = this.getCurrentSession().createSQLQuery(sql);
sqlQuery=getSqlQueryByMap(sqlQuery,params);
return sqlQuery.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
}
public SQLQuery getSqlQueryByMap(SQLQuery sqlQuery,Map<String,Object> params){
if (params != null && !params.isEmpty()) {
for (String key : params.keySet()) {
Object obj = params.get(key);
if (obj instanceof Collection<?>)
sqlQuery.setParameterList(key, (Collection<?>) obj);
else if (obj instanceof Object[])
sqlQuery.setParameterList(key, (Object[]) obj);
else
sqlQuery.setParameter(key, obj);
}
}
return sqlQuery;
}
返回的數據是一個map類型的列表,參數通過map傳遞,參數類型爲:param;
調用示例:
String sql="select id,user_name,create_date_time from tbl_user where code=:code"
Map<String,Object> params=new HashMap<>();
params.put("code","test");
List<Map<String,Object>> users=this.findMapBySql(sql,params);
如果需要轉化爲實體的集合,需要自己處理
2、查詢結果映射到實體,:param傳參
public <T> List<T> find(String sql, Map<String,Object> params, Class<T> clazz) {
SQLQuery query = this.getCurrentSession().createSQLQuery(sql);
query=getSqlQueryByMap(query,params);
query.setResultTransformer(Transformers.aliasToBean(clazz));
return query.list();
}
返回的數據是一個實體的列表,參數通過map傳遞,參數類型爲:param,需要注意的是,數據庫字段必須和映射的實體字段一一對應,而且存在getter/setter方法,不然會報錯。
調用示例:
String sql="select id,user_name,create_date_time from tbl_user where code=:code"
Map<String,Object> params=new HashMap<>();
params.put("code","test");
List<User> users=this.find(sql,params,User.class);
則需要User實體中有user_name,create_date_time的屬性定義,而不是userName,createDateTime,當然可以通過制定別名解決這個問題;
還有如下的一種方式,也可以獲取實體列表
public <T> List<T> findBySql(String sql, Class<T> clazz) {
SQLQuery sqlQuery = this.getCurrentSession().createSQLQuery(sql);
sqlQuery.addEntity(clazz);
return sqlQuery.list();
}
同樣是獲取實體列表,下面的方式是將找到數據庫字段名對應的實體屬性名,比如sql->user_name會映射到entity->userName,
注意:
@Transient的實體是不會賦值的,對應的查詢結果不會注入到entity;
3、查詢結果映射到map或實體,?傳參
public List findMapBySql(String sql, Object[] params, Type[] types, Class clazz) {
SQLQuery query = this.getCurrentSession().createSQLQuery(sql);
if (clazz != null) {
query.setResultTransformer(Transformers.aliasToBean(clazz));
} else {
query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
}
query.setParameters(params, types);
return query.list();
}
返回的數據是一個列表,根據clazz參數判斷返回的map類型的列表還是實體列表,參數使用了?
佔位符,在集合參數中比如in
,需要用多個?
代替;
調用示例:
String sql="select id,user_name,create_date_time from tbl_user where code like ? and id in (?,?,?)"
Object[] params=new Object[]{"%test%",1,3,5};
Type[] types=new Type[]{Hibernate.String,Hibernate,Integer,Hibernate.Integer,Hibernate.Integer};
List<Map<String,Object>> users=this.findMapBySql(sql,params,types,null);
Query
通過HQL語句查詢數據,查詢結果也同SQLQuery類型:
- 支持setResultTransformer把查詢結果映射到實體列表或者map列表
- 支持通過setParameters(?傳參)
- setParameter/setParameterList(:param傳參)
- 不支持addEntity映射到實體(因爲hql本文是和實體綁定的)
此外,Hiberante查詢還支持Criteria和Example兩種方式;