我正在开发一个使用JSF2和JPA2框架的Web应用程序。 我开始在netbeans7.0上使用向导和“来自实体类的新JSF页面”创建了一个classAbstractFacade“包含这个有用的方法:
public List<T> findRange(int[] range) {
javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
cq.select(cq.from(entityClass));
javax.persistence.Query q = getEntityManager().createQuery(cq);
q.setMaxResults(range[1] - range[0]);
q.setFirstResult(range[0]);
return q.getResultList();
}
其中T是包含表的数据库结构的实体类,范围变量包含两个用于检索结果子列表的数字! 现在我修改它以设置order by子句并检查用户是否有范围而新代码是:
public List<T> findRangeOrdered(int[] range, String orderBy) {
javax.persistence.criteria.CriteriaQuery<T> cq = (javax.persistence.criteria.CriteriaQuery<T>)getEntityManager().getCriteriaBuilder().createQuery();
cq.select(cq.from(entityClass));
javax.persistence.criteria.Root<T> r = cq.from(entityClass);
if(orderBy!=null && !orderBy.equals("")){
if(orderBy.ebdsWith(" desc"))
cq.orderBy(getEntityManager().getCriteriaBuilder().desc(r.get(orderBy.substring(0,orderBy.indexOf(" ")))));
else
cq.orderBy(getEntityManager().getCriteriaBuilder().desc(r.get(orderBy.substring(0,orderBy.indexOf(" ")))));
}
javax.persistence.Query q = getEntityManager().createQuery(cq);
if(range!=null)
{
q.setMaxResults(range[1] - range[0]);
q.setFirstResult(range[0]);
}
return q.getResultList();
}
现在我要添加一些选项。 我正在考虑添加一个List变量,该变量可以包含带有这些键的HashMap - &gt;值:
现在我有些疑惑:
1)这个想法是个好主意吗?
2)做一个已实现此功能的框架退出?
3)如果前面问题的答案是:是的,这是个好主意;不,没有任何框架已经做到了,我发现这些新问题: 这个新方法返回了一些编译器错误:
public List<T> findAllFiltered(int[] range, String orderBy, List<HashMap<String,Object>> whereList) {
List<Predicate> predicateList = new ArrayList<Predicate>();
String buf;
HashMap<String,Object> where;
int i=0;
javax.persistence.criteria.CriteriaQuery<T> cq = (javax.persistence.criteria.CriteriaQuery<T>)getEntityManager().getCriteriaBuilder().createQuery();
cq.select(cq.from(entityClass));
javax.persistence.criteria.Root<T> r = cq.from(entityClass);
javax.persistence.criteria.Path<T> path = cq.from(entityClass);
if(whereList!= null && whereList.size()>0){
Iterator iter=whereList.iterator();
Predicate p;
while (iter.hasNext())
{
where=(HashMap<String,Object>)iter.next();
if(where.get("where").toString().equals("like"))
p = getEntityManager().getCriteriaBuilder().like(getEntityManager().getCriteriaBuilder().upper(r.<String>get(where.get("name").toString())), "%"+where.get("value0").toString().toUpperCase()+"%");
else if(where.get("where").toString().equals("equal"))
p = getEntityManager().getCriteriaBuilder().equal(r.get(where.get("name").toString()), where.get("value0").toString());
else if(where.get("where").toString().equals("in"))
p = getEntityManager().getCriteriaBuilder().and(r.get(where.get("name").toString()).in(where.get("value0").toString().replaceAll("#",",")));
else if(where.get("where").toString().equals("between"))
{
java.util.Date value0=(java.util.Date)where.get("value0");
java.util.Date value1=(java.util.Date)where.get("value1");
p = getEntityManager().getCriteriaBuilder().between(r.<java.util.Date>get(where.get("name").toString()),value0,value1);
}
else if(where.get("where").toString().equals("greatest"))
p = getEntityManager().getCriteriaBuilder().and(getEntityManager().getCriteriaBuilder().greatest(r.<Long>get(where.get("name").toString())));
else if(where.get("where").toString().equals("greaterThanOrEqualTo"))
{
java.util.Date value0=(java.util.Date)where.get("value0");
p = getEntityManager().getCriteriaBuilder().greaterThanOrEqualTo(r.<java.util.Date>get(where.get("name").toString()),value0);
}
else if(where.get("where").toString().equals("lessThanOrEqualTo"))
{
java.util.Date value0=(java.util.Date)where.get("value0");
p = getEntityManager().getCriteriaBuilder().lessThanOrEqualTo(r.<java.util.Date>get(where.get("name").toString()),value0);
}
}
}
Predicate[] predicates = new Predicate[predicateList.size()];
predicateList.toArray(predicates);
cq.where(predicates);
if(orderBy!= null&& !orderBy.equals("")){
if(orderBy.endsWith("desc"))
cq.orderBy(getEntityManager().getCriteriaBuilder().desc(r.get(orderBy.substring(0,orderBy.indexOf(" ")))));
else
cq.orderBy(getEntityManager().getCriteriaBuilder().asc(r.get(orderBy.substring(0,orderBy.indexOf(" ")))));
}
javax.persistence.Query q = getEntityManager().createQuery(cq);
if(range!=null){
q.setMaxResults(range[1] - range[0]);
q.setFirstResult(range[0]);
}
return q.getResultList();
}
1)“最大”方法返回此错误:
p = getEntityManager().getCriteriaBuilder().and(getEntityManager().getCriteriaBuilder().greatest(r.<Long>get(where.get("name").toString())));
method CriteriaBuilder.and(Expression<Boolean>,Expression<Boolean>) is not applicable
(actual and formal argument lists differ in length)
method CriteriaBuilder.and(Predicate...) is not applicable
(argument type Expression<Long> does not conform to vararg element type Predicate)
我搜索了这个方法的一个例子,但我找不到任何有用的东西;
2)正如我写的,我的HashMapp还包含了我想要过滤的字段类,现在我将使用这些信息来重写between,greaterThanOrEqualTo,lessThanOrEqualTo所以,如果我愿意,我可以过滤除java以外的其他类型.util.Date! 你对这个长期问题有什么看法? 谢谢你的帮助!
P.S。:对不起我不完美的英语,但我是意大利人。
PS2:对不起,对于我的代码结构......我是盲目的,我不会一直控制缩进...这个网站控制它但是我不确定我是否缩进所有代码正确!答案 0 :(得分:2)
所以问题的答案是
答案 1 :(得分:1)
我不认为使用Criteria API创建一个使用字符串进行构建查询的方法是一个好主意,我绝对建议使用JPQL,或者如果您更喜欢其他一些帮助您以最智能的方式构建查询的工具,您可以使用:ObjectQuery或Query Dsl或Torpedo Query,如果您希望将代码与实际实现隔离,则可以将查询隐藏在某个DAO或Repository对象中,或者至少创建一个包装器在一些查询构建器上!