最近遇到两次在hql的in中传递参数的问题,最初让我纠结万千。
在dao层已经封装好了一个使用hql获取数据的方法:
- public List> findByHql(String hql, Map map, int pageSize,int pageNo) {
- return this.getQuery(hql, map, pageSize, pageNo).list();
- }
-
-
- private Query getQuery(String hql, Map map, int pageSize,int pageNo) {
- Query query = this.createQuery(hql);
- query = this.setParameter(query, map);
- query = this.setPageProperty(query, pageSize, pageNo);
- return query;
- }
-
- private Query createQuery(String hql) {
- return getSession().createQuery(hql);
- }
-
- private Query setParameter(Query query, Map map) {
- if (map != null) {
- Set keySet = map.keySet();
- for (String string : keySet) {
- Object obj = map.get(string);
- query.setParameter(string, map.get(string));
- }
- }
- return query;
- }
-
- private Query setPageProperty(Query query, int pageSize, int pageNo) {
- if (pageNo != 0 && pageSize != 0) {
- query.setFirstResult((pageNo - 1) * pageSize);
- query.setMaxResults(pageSize);
- }
- return query;
- }
通常在业务层只需要写相应的hql,然后把对应参数封装到map中,即可查询出自己需要的数据。
然后我有这样一句查询语句:
- String hql = "FROM Login login WHERE login.id in(:ids)";
- Map map = new HashMap();
- Integer[] ids = new Integer[]{1,2,3};
- map.put("ids",ids);
- List lstLogin = (List)xxxDao.findByHql(hql,map,0,0);
最后运行的时候,发生异常:ljava.lang.Integer cannot be cast to java.lang.Integer
也就是说hibernate把ids这个参数当做一个Integer对象了而不是一个集合。
后来在网上找了下答案,原来对hibernate中setParameter这个方法还不熟悉:Query接口提供了多种传递参数的方法,可以是传单独参数,也可以传集合,如下图
也就是说,前面使用数组集合的话则必须调用setParameterList方法。
那么改一下Dao层的setParameter方法即可达到通用了:
- private Query setParameter(Query query, Map map) {
- if (map != null) {
- Set keySet = map.keySet();
- for (String string : keySet) {
- Object obj = map.get(string);
-
- if(obj instanceof Collection>){
- query.setParameterList(string, (Collection>)obj);
- }else if(obj instanceof Object[]){
- query.setParameterList(string, (Object[])obj);
- }else{
- query.setParameter(string, obj);
- }
- }
- }
- return query;
- }
最初还以为是hibernate不够智能化,原来是自己没学好,项目经验相当重要呀...