最近在改项目中未使用绑定变量传参的SQL,遇到了这个坑(其实还是自己经验不足~),特此记下来。先来看一下原dao中的方法:hibernate HQL语句查询时遇到一个问题,用了绑定变量的方式传参,可是就是查不出结果集。
public List<Map<String, Object>> findCargotypecode(String bnos,String filterCargotypecodes) {
final String sql = "SELECT T.BNO FROM TM_ORIGINAL_DATA T WHERE T.BNO IN ("+bnos+") AND T.CARGOTYPECODE IN ("+filterCargotypecodes+")";
return (List<Map<String, Object>>) getHibernateTemplate().execute(
new HibernateCallback() {
public Object doInHibernate(Session session)throws HibernateException, SQLException {
Query query = session.createSQLQuery(sql).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
return query.list();
}
});
}
其中参数bnos和filterCargotypecodes都是“ ‘a’, ‘b’, ‘c’”类似这种字符串(先别吐槽为毛查一个字段却用Map泛型接收,这都是历史遗留问题,手动滑稽),起初我也没在意,就按照单个传参来传了,于是代码被改成了这样:
public List<Map<String, Object>> findCargotypecode(final String bnos,final String filterCargotypecodes){
final String sql = "SELECT T.BNO FROM TM_ORIGINAL_DATA T WHERE T.BNO IN (:bnos) AND T.CARGOTYPECODE IN (:filterCargotypecodes)";
return (List<Map<String, Object>>) getHibernateTemplate().execute(
new HibernateCallback() {
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
return session.createSQLQuery(sql)
.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP)
.setString("bnos",bnos)
.setString("filterCargotypecodes",filterCargotypecodes)
.list();
}
});
}
本以为这样就完事儿了,殊不知测试的时候就出问题了:倒是没报错,但是查不出数据。数据库有数据,但是hibernate死活查不出数据。
查了半天,原来猫腻在这:setString方法,hibernate会视这为一整个字符串。效果如:
select * from A where a.bno in (“‘a’, ‘b’, ‘c’”)
这种SQL显然不是我们要的,我们要的是下面这种:
select * from A where a.bno in (“a”,”b”,”c”)
那么问题来了,怎么改?其实很简单,有个方法叫
setParameterList(String name,Collection vals)
重载方法有
setParameterList(String name,Object[] vals)
(PS:翻了下源码,推荐用第一个传集合的,因为实际上传了数组hibernate依然会转成集合操作)
估计大家看到方法就明白怎么回事了,就不解释了,直接上代码
public List<Map<String, Object>> findCargotypecode(final String []bnos,final String[] filterCargotypecodes){
final String sql = "SELECT T.BNO FROM TM_ORIGINAL_DATA T WHERE T.BNO IN (:bnos) AND T.CARGOTYPECODE IN (:filterCargotypecodes)";
return (List<Map<String, Object>>) getHibernateTemplate().execute(
new HibernateCallback() {
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
return session.createSQLQuery(sql)
.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP)
.setParameterList("bnos",bnos)
.setParameterList("filterCargotypecodes",filterCargotypecodes)
.list();
}
});
}