问题描述
我的业务场景是这样的,我有一个流程节点,有对应的状态节点1,状态1,状态2,状态3节点2,状态4...所以,我们的ql="selectefromEntityewheree.statusin(:status)";这个in里面的内容,需要动态的决定说是否进行查找,可能是1个参数,可能是3个参数。我在网络上查询,发现jpa可以对集合进行操作引用
“9.JPA的集合查询:我们知道在SQL语句中,查找某元素是否在某个集合中时常用类似:in(a,b,c)的查询语句,在JDBC中我们常常需要将集合元素拼接成以逗号(“,”)分隔的字符串,在JPA中有两种方法可以方便地进行判断元素是否在集合中的查询:(1).设置集合类型的参数:查询对象的setParameter方法支持Object类型,因此可以传入一个集合类型的参数,如数组或者ArrayList等。例如:Queryquery=em.createQuery(“select*fromUserswherenamein(?names)”);query.setParameter(“name”,names);//names是一个name集合(2).使用memberof关键字:例如:SelecttfromTopictwhere:optionmemberoft.options;”
问题是,如果我传入一个String[]statusArr或者List<String>时,都报出异常。请问jpa里的in查询的到底怎么用?member不能查,直接报unexpecttoken当然,如果实在没办法,我只能去用程序去拼接in的部分了。这是最下策了。
解决方案
解决方案二:
我勒个去,参数不是这样传递的。。。你可以先判断List<String>的length(),然后再拼接参数:StringBufferjpql=newStringBuffer();jpql.append("selectefromEntityewheree.statusin(");for(inti=0;i<list.length();i++){jpql.append(":status"+i+",");}if(!list.isEmpty()){jpql.deleteCharAt(jpql.length()-1);}jpql.append(")");得到相应的query之后再setParameter:for(inti=0;i<list.lenght();i++){query.setParameter("status"+i,list.get(i));}然后就去执行就可以了,注意jpql作为StringBuffer要.toString()
解决方案三:
jpa的in查询不能用数组或集合,只能一个一个参数的设置,用这个来解决挺好的list查询条件的参数集合;org.apache.commons.lang.StringUtils;StringBufferjpql=newStringBuffer("SELECToFROMxxasoWHEREo.xxIN(");jpql.append(StringUtils.repeat("?",",",listSize));jpql.append(")");Object[]queryParams=list.toArray();Queryquery=entityManager.createQuery(jpql.toString);if(queryParams!=null&&queryParams.length>0){for(inti=0;i<queryParams.length;i++){query.setParameter(i+1,queryParams[i]);}}returnquery.getResultList();
解决方案四:
引用2楼ZuxiangHuang的回复:
jpa的in查询不能用数组或集合,只能一个一个参数的设置,用这个来解决挺好的list查询条件的参数集合;org.apache.commons.lang.StringUtils;StringBufferjpql=newStringBuffer("SELECToFROMxxasoWHEREo.xxIN(");jpql.append(StringUtils.repeat("?",",",listSize));jpql.append(")");Object[]queryParams=list.toArray();Queryquery=entityManager.createQuery(jpql.toString);if(queryParams!=null&&queryParams.length>0){for(inti=0;i<queryParams.length;i++){query.setParameter(i+1,queryParams[i]);}}returnquery.getResultList();
在Hibernate4.1之后吧(具体哪个版本记不清了),对这种以数字序为参数占位符的查询语句会提示警告,不推荐此方式了。我的项目已经全部升级为命名参数:paramName这种形式了。
解决方案五:
靠,搞个in参数如此麻烦,跟拼原生SQL有何区别,我还要这破框架做什!!!
解决方案六:
直接set无异常这句:Queryquery=em.createQuery(“select*fromUserswherenamein(?names)”);query.setParameter(“name”,names);//names是一个name集合应该改成:Queryquery=em.createQuery(“select*fromUserswherenamein(:names)”);//?改成:query.setParameter(“names”,names);//name改成names,这样才对,否则jpa是无法把namemap到names的引用楼主Eternalc的回复:
我的业务场景是这样的,我有一个流程节点,有对应的状态节点1,状态1,状态2,状态3节点2,状态4...所以,我们的ql="selectefromEntityewheree.statusin(:status)";这个in里面的内容,需要动态的决定说是否进行查找,可能是1个参数,可能是3个参数。我在网络上查询,发现jpa可以对集合进行操作引用
“9.JPA的集合查询:我们知道在SQL语句中,查找某元素是否在某个集合中时常用类似:in(a,b,c)的查询语句,在JDBC中我们常常需要将集合元素拼接成以逗号(“,”)分隔的字符串,在JPA中有两种方法可以方便地进行判断元素是否在集合中的查询:(1).设置集合类型的参数:查询对象的setParameter方法支持Object类型,因此可以传入一个集合类型的参数,如数组或者ArrayList等。例如:Queryquery=em.createQuery(“select*fromUserswherenamein(?names)”);query.setParameter(“name”,names);//names是一个name集合(2).使用memberof关键字:例如:SelecttfromTopictwhere:optionmemberoft.options;”问题是,如果我传入一个String[]statusArr或者List<String>时,都报出异常。请问jpa里的in查询的到底怎么用?member不能查,直接报unexpecttoken当然,如果实在没办法,我只能去用程序去拼接in的部分了。这是最下策了。
解决方案七:
经测试,可以的啊,楼上的正确。
解决方案八:
在相应字段的get方法里把不要的数据过滤掉。这样做虽然效率低一点,但是不依赖具体的JPA实现。通用性好。
解决方案九:
楼主解决了吗?怎么解决的我也碰到这个问题了?