我使用JPA 2.0的CriteriaBuilder构建动态查询有点困难.
我猜有一个很常见的用例:用户提供任意数量的搜索参数X和/或连接:如:
select e from Foo where (name = X1 or name = X2 .. or name = Xn )
Run Code Online (Sandbox Code Playgroud)
方法或CriteriaBuilder不是动态的:
谓词或(谓词......限制)
想法?样品?
我有grails条件构建器的问题,我想对与父表示例一对多关系的表上的列进行投影:
Car.createCriteria() {
projections {
property('name')
property('wheels.name')// ????
}
join 'wheels'
//or wheels {} ???
}
Run Code Online (Sandbox Code Playgroud)
或类似的东西存在?我认为这是别名的基本问题
此查询用于以一对多关系检索最后的记录(请参阅SQL连接:选择一对多关系中 的最后记录)
SELECT p.*
FROM customer c
INNER JOIN (
SELECT customer_id, MAX(date) MaxDate
FROM purchase
GROUP BY customer_id
) MaxDates ON c.id = MaxDates.customer_id
INNER JOIN purchase p ON MaxDates.customer_id = p.customer_id
AND MaxDates.MaxDate = p.date;
Run Code Online (Sandbox Code Playgroud)
我的问题:如何使用jpa criteria-api的subselect构建此连接?可能吗?如果没有,可以使用jpql吗?
我的代码到目前为止:
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
final CriteriaQuery<Purchase> query = cb.createQuery(Purchase.class);
final Root<CustomerEntity> root = query.from(Customer.class);
// here should come the join with the sub-select
final Path<Purchase> path = root.join(Customer_.purchases);
query.select(path);
final TypedQuery<Purchase> typedQuery = entityManager.createQuery(query);
return typedQuery.getResultList();
Run Code Online (Sandbox Code Playgroud) 我正在尝试编写类似的查询
select * from Table a
where a.parent_id in
(select b.id from Table b
where b.state_cd = ?
and rownum < 100)
Run Code Online (Sandbox Code Playgroud)
使用Criteria API.我可以使用类似的代码/sf/answers/326761081/来实现查询而不使用子查询的rownum限制,但我似乎无法弄清楚如何对Subquery
我正在尝试执行以下查询,并通过一个case语句进行选择,并通过同一case语句进行分组。
Select USER,
(CASE
WHEN value between 0 AND 2 then '0-2'
WHEN value between 3 AND 4 then '3-4'
ELSE '5+'
END) as CASE_STATEMENT ,
SUM(value)
.....
Group by user, CASE_STATEMENT
Run Code Online (Sandbox Code Playgroud)
与Hibernate一起使用JPA 2.0 Criteria API。
我的测试用例看起来像...
CriteriaBuilder cb = em.getCriteriaBuilder()
CriteriaQuery cq = cb.createQuery(Tuple)
def root = cq.from(TestEntity)
def userGet = root.get('user')
def valueGet = root.get('value')
def caseExpr =
cb.selectCase()
.when(cb.between(valueGet, 0, 2), '0-2')
.when(cb.between(valueGet, 3, 4), '3-4')
.otherwise('5+')
def sumExpr = cb.sum(valueGet)
cq.multiselect([userGet, caseExpr, sumExpr])
cq.groupBy([userGet, caseExpr])
log(typedQuery.unwrap(Query).queryString) …Run Code Online (Sandbox Code Playgroud) 我有这样的Bean
Class TestA
{
Map<String,TestB> testBMap;
}
Class TestB
{
String data;
...
}
Run Code Online (Sandbox Code Playgroud)
我想取TestA随着地图数据的testBMap地方key ='test1'.
我怎么能用Hibernate做到这一点.
我有使用Spring数据JPA规范从实体Person获取List的问题(因为分页).我需要逐个获得所有笔记,但这两个实体之间的依赖关系是在人员方面.我不知道如何创建我的谓词因为Note不包含任何与Person相关的属性.
我只能得到List with Persons getter但我不能用这种方式,因为我需要返回数据分页.
@Entity
public class Person implements Serializable {
@Id
private Long personId;
@OneToMany
@JoinColumn(name = "personId")
private List<Note> notes;
}
@Entity
public class Note implements Serializable {
@Id
private Long noteId;
}
Run Code Online (Sandbox Code Playgroud)
通常情况下,我会写这样的东西,但我没有注释中的属性人,数据库在此阶段无法重新映射.
public static Specification<Note> notesByPerson(final Long personId) {
return new Specification<Note>() {
@Override
public Predicate toPredicate(final Root<Note> root, final CriteriaQuery<?> query,
final CriteriaBuilder builder) {
final Path<Person> per = root.<Person> get("person");
return builder.equal(per.<Long> get("personId"), personId);
}
};
}
Run Code Online (Sandbox Code Playgroud)
谢谢你,Zdend
我正面临JPA标准查询的问题.如何在条件查询中使用if else添加多个where子句...
我的要求是:
CriteriaBuilder builder = getEm().getCriteriaBuilder();
CriteriaQuery<Object> query = builder.createQuery(Object.class);
// From
Root<EntityClass> entity= query.from(EntityClass.class);
// Select
query.multiselect(entity.get("id").get("col1"),entity.get("id").get("col2"));
// Where
Predicate p1 = builder.and(builder.equal(entity.get("col3"), value3));
Predicate p2 = builder.and(builder.equal(entity.get("col4"), value4));
Predicate p3 = builder.and(builder.equal(entity.get("col5"), value5));
if(someCondition1){
query.where(p1);
}else if(someCondition2){
query.where(p1);
}
query.where(p3);
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,语句query.where(p3); 替换先前设置的where子句条件p1和p2.我发现的替代品是如下所示
if(someCondition1){
query.where(p1, p3);
}else if(someCondition2){
query.where(p2, p3);
}else{
query.where(p3);
}
Run Code Online (Sandbox Code Playgroud)
但这不是一个好方法,因为当有很多if-else时,编写重复代码变得非常糟糕.任何人都可以为此解决问题吗?
jpa predicate where-clause criteria-api conditional-statements
我有一个String作为参数(实际上是一个valueOf(一个整数),并希望将它与DB中的int值的子字符串进行比较.这是我的代码:
ClinicPatients clp = null;
// Get the criteria builder instance from entity manager
final CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
// Create criteria query and pass the value object which needs to be populated as result
CriteriaQuery<ClinicPatients> criteriaQuery = cb.createQuery(ClinicPatients.class);
// Tell to criteria query which tables/entities you want to fetch
final Root<ClinicPatients> rootClp = criteriaQuery.from(ClinicPatients.class);
criteriaQuery.select(rootClp);
Expression<String> e1 = cb.function("CONVERT", String.class, rootClp.get(idCPFieldName));
Predicate p1 = cb.equal(cb.substring(e1, 1, 3), idClinicPatient);
criteriaList.add(p1);
criteriaQuery.where(p1);
// Here entity manager will …Run Code Online (Sandbox Code Playgroud) 文档说:
为文字创建表达式
在代码中我看到了cb.literal()的此类用法:
Expression<String> wordLiteral = cb.literal(word);
predicates.add(cb.like(namePath, wordLiteral));
Run Code Online (Sandbox Code Playgroud)
但如果这里省略wordLiteral并使用word代替,则不会发生任何变化。那么这个方法是做什么用的呢?
criteria-api ×10
jpa ×6
java ×4
hibernate ×3
jpa-2.0 ×3
alias ×1
criteria ×1
dynamic ×1
grails ×1
groovy ×1
predicate ×1
projection ×1
spring ×1
where-clause ×1