Hibernate的SQLQuery與Query佔位符傳參

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類型:

  1. 支持setResultTransformer把查詢結果映射到實體列表或者map列表
  2. 支持通過setParameters(?傳參)
  3. setParameter/setParameterList(:param傳參)
  4. 不支持addEntity映射到實體(因爲hql本文是和實體綁定的)

此外,Hiberante查詢還支持Criteria和Example兩種方式;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章