任何人都可以帮助我获得下面提到的JPA查询的JPA标准查询。如何使用JPA Criteria查询编写此查询?
SELECT p,l FROM Person p
LEFT JOIN Language l ON (p.language = l.language and l.locale like :locale)
AND p.name like :name
AND p.time BETWEEN :startDate
AND :endDate order by name asc
任何人都可以帮助我获得下面提到的JPA查询的JPA标准查询。如何使用JPA Criteria查询编写此查询?
SELECT p,l FROM Person p
LEFT JOIN Language l ON (p.language = l.language and l.locale like :locale)
AND p.name like :name
AND p.time BETWEEN :startDate
AND :endDate order by name asc
假设人有关系的语言这里就是你会在较老的Hibernate做什么:
Criteria criteria = entityManager.createCriteria(Person.class);
Criteria languageCriteria = criteria.createCriteria("language");
languageCriteria.add(Restrictions.like("locale", locale));
criteria.add(Restrictions.like("name", name));
criteria.add(Restrictions.between("time", startDate, endDate));
criteria.addOrder(Order.asc("name"));
和我第一次尝试在JPA 2.0:
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Person> criteria = builder.createCriteria(Person.class);
Root<Person> pRoot = criteria.from(Person.class);
Join<Person, Language> langJoin = criteria.join("language", JoinType.LEFT);
Predicate conjunction = builder.conjunction();
criteria.where(builder.and(
builder.like(langJoin.get(Language_.locale), locale),
builder.like(pRoot.get(Person_.name), name),
builder.between(pRoot.get(Person_.time), startDate, endDate));
criteria.orderBy(builder.asc(pRoot.get(Person_.name)));
请让我知道如果这对你有用。
编辑:更新后的查询仅使用一个where
调用。
限制不是JPA规范的一部分,它是休眠功能 – perissf 2012-03-29 14:58:56
您是对的,我需要翻译为JPA 2 – 2012-03-29 15:10:13
嘿,首先感谢,我应该把它放在这个问题上。 有没有**关系** b/w实体的人和语言。人员和语言都有一个共同的列(语言(varchar)),我将加入该列。对我造成的问题是,我需要做一个** LEFT OUTER JOIN **,这样如果没有可用于该人的语言数据,我仍然应该能够将语言对象的人员数据作为空值。 – user1300877 2012-03-29 18:21:08
尽管johncarl给出的答案已被接受,但它对我来说并不正确。对于CriteriaQuery.where()的Javadoc说:
修改查询根据 指定布尔表达式来限制查询结果。替换之前添加的 限制(若有)。
据我了解,以下各行(给予限制)将覆盖前面给出的限制:
criteria.where(builder.like(langJoin.get(Language_.locale), locale));
criteria.where(builder.like(pRoot.get(Person_.name), name));
criteria.where(builder.between(pRoot.get(Person_.time), startDate, endDate));
这意味着,在年底开始和结束日期之间只有最后一个限制( )将保持。
我threfore提出以下修改johncarl的回答是:
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Person> criteria = builder.createCriteria(Person.class);
Root<Person> pRoot = criteria.from(Person.class);
Join<Person, Language> langJoin = criteria.join("language", JoinType.LEFT);
Predicate[] restrictions = new Predicate[] {
builder.like(langJoin.get(Language_.locale), locale),
builder.like(pRoot.get(Person_.name), name),
builder.between(pRoot.get(Person_.time), startDate, endDate)
};
criteria.where(builder.and(restrictions));
criteria.orderBy(builder.asc(pRoot.get(Person_.name)));
但是,此代码看起来真难看!请随时编辑,如果它是错误的,并评论它,如果你看到更好的解决方案!我会很优雅!
你可以显示你的人员和语言的实现吗? – 2012-03-29 14:20:43