hibernate in 查询

在hibernate 查询in 查询中不能使用testQuery1方法查询

public void testQuery1(){
SessionFactory factory = null;
Session session = null;
factory = (SessionFactory) HibernateSessionFactory.getSessionFactory();
session = factory.openSession();
Integer id[] = new Integer[]{1,2,3,4};

[color=blue] String hql = "from Group as p where p.id in (?)";
Query query = session.createQuery(hql);
query.setParameter(1, id);[/color]

List list = query.list();
System.out.println(list.size());
session.close();
}

应该使用如下方法:

public void testQuery2(){
SessionFactory factory = null;
Session session = null;
factory = (SessionFactory) HibernateSessionFactory.getSessionFactory();
session = factory.openSession();
Integer id[] = new Integer[]{1,2,3,4};

[color=blue]String hql = "from Group as p where p.id in (:test)";
Query query = session.createQuery(hql);
query.setParameterList("test", id);[/color]

List list = query.list();
System.out.println(list.size());
session.close();
}
两者的区别之处在蓝色字体部分。

另外也可以用hibernateTemplate的executeFind方法调用hibernate api查询数据,如下:
//service层
public List getProvideCertifyUser(String userIdParam) throws Exception{
String hqlString = "select e from Employee e where e.id in (:eId)";
return commonDaoImpl.getProvideCertifyUser(hqlString, userIdParam.split(","));
}


//dao层
public List getProvideCertifyUser(final String queryHql,final String [] params) throws Exception{
return generalDAO.getHibernateTemplate().executeFind(new HibernateCallback(){
public Object doInHibernate(Session session) throws HibernateException, SQLException {
Query query = session.createQuery(queryHql);
query.setCacheable(false);
query.setParameterList("eId", params);
List list = query.list();
return list;
}
});
}


另外这是其他网友写的,觉得也相当有用,粘一下备用

这篇觉得封装的可以学一学
[url]http://blessht.iteye.com/blog/1051421[/url]
最近遇到两次在hql的in中传递参数的问题,最初让我纠结万千。

在dao层已经封装好了一个使用hql获取数据的方法:


public List<?> findByHql(String hql, Map<String, Object> map, int pageSize,int pageNo) {
return this.getQuery(hql, map, pageSize, pageNo).list();
}

private Query getQuery(String hql, Map<String, Object> 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<String, Object> map) {
if (map != null) {
Set<String> 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<String,Object> map = new HashMap<String,Object>();
Integer[] ids = new Integer[]{1,2,3};
map.put("ids",ids);
List<Login> lstLogin = (List<Login>)xxxDao.findByHql(hql,map,0,0);

最后运行的时候,发生异常:java.lang.Integer cannot be cast to java.lang.Integer

也就是说hibernate把ids这个参数当做一个Integer对象了而不是一个集合。

后来在网上找了下答案,原来对hibernate中setParameter这个方法还不熟悉:Query接口提供了多种传递参数的方法,可以是传单独参数,也可以传集合,如下图
[img]http://dl2.iteye.com/upload/attachment/0086/5079/192c4b47-f025-397d-b25f-77fefecd89a5.jpg[/img]

也就是说,前面使用数组集合的话则必须调用setParameterList方法。

那么改一下Dao层的setParameter方法即可达到通用了:

private Query setParameter(Query query, Map<String, Object> map) {   
if (map != null) {
Set<String> 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不够智能化,原来是自己没学好,项目经验相当重要呀...

//这篇直接
[url]http://charyle.iteye.com/blog/1021356[/url]
平时经常用Hibernate,由于习惯表间不建立关联,所以HQL查询时候经常要用in语句。
我最常用的情况有2种:
1、in后是个子查询,如 FROM A WHERE A.ID IN (SELECT B.AID FROM B WHERE ...),这样是没问题的,如果A.ID 和B.AID是相同的数据类型。
2、in的参数如果已知了,可以直接拼接在后面 如FROM A WHERE A.ID IN (1,2,3,4...)。
3、上面的情况下,通常(1,2,3,4...)都是作为参数传递过来的,可能是数组或者List。
假设List<Integer> a;a里面已经有数据了,则HQL查询条件可以为:
String hql="FROM A WHERE A.ID IN (:alist)";  
Query query = getSession().createQuery(hql);
query.setParameterList("alist", a);

另外,query.setParameterList中的第二个参数,还可以是数组类型,如int[] a,不要被方法名称迷惑。我也是最近刚学会的这种in参数设置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值