在我的Wicket + JPA/Hibernate + Spring项目中,大部分功能都基于Inbox页面,使用许多过滤选项(并非所有过滤选项都必须使用),用户可以限制他们想要使用的对象集.我想知道实现这种过滤的最佳策略是什么?在此应用程序的旧版本中,搜索查询是连接包含SQL条件的字符串.最近我读到了JPA提供的新Criteria API - 您是否会建议使用搜索字符串?这与DAO层如何结合 - 是不是在业务层中使用Criteria API构建搜索查询是否存在层分离的漏洞?
我不知道如何执行返回布尔输出的JPA条件查询.
目标是在Oracle上呈现时具有看起来像这样的条件查询:
select 1 from dual where exists ( ... );
Run Code Online (Sandbox Code Playgroud)
where exists (...)我用子查询执行的部分.我正在努力解决外部问题.
这样做的实际用途是确定exists子句中的子查询是返回true还是false.
这就是我写的:
CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<Object> query = criteriaBuilder.createQuery();
query.from(Boolean.class);
query.select(criteriaBuilder.literal(true));
Subquery<Location> subquery = query.subquery(Location.class);
Root<Location> subRootEntity = subquery.from(Location.class);
subquery.select(subRootEntity);
Path<?> attributePath = subRootEntity.get("State");
Predicate predicate = criteriaBuilder.equal(attributePath, criteriaBuilder.literal("TX"));
subquery.where(predicate);
query.where(criteriaBuilder.exists(subquery));
TypedQuery<Object> typedQuery = em.createQuery(query);
Run Code Online (Sandbox Code Playgroud)
最后一行输出错误,指出" 布尔值不是实体 ".我认为我的问题是不知道如何表达查询的" from "部分,以便结果输出1或0/true或false - 而不是实体.
我知道我可以检索任何实体,然后检查结果列表的大小是否为1.
我问如何得到一个布尔结果,既避免了检索这些列的不必要的任务,也学习了如何做到这一点.
这有可能吗?
谢谢!爱德华多
使用标准api,我有一个查询,它执行以下操作:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<SourcePath> pathQuery = cb.createQuery(SourcePath.class);
Root<SourcePath> pathRoot = pathQuery.from(SourcePath.class);
pathQuery.where(cb.equal(cb.literal(0x00010002).as(String.class), (pathRoot.get(SourcePath_.path))));
TypedQuery<SourcePath> query = entityManager.createQuery(pathQuery);
query.getResultList();
Run Code Online (Sandbox Code Playgroud)
生成的sql查询结果如下:
select ...snip aliases... from SourcePath where cast(x'00010002', char(1)) = path;
Run Code Online (Sandbox Code Playgroud)
(路径将是一些讨厌的旧别名,但这是无关紧要的).
此查询不正确.特别是,中投:cast(x'00010002', char(1))不强制转换为字符串,由指定的.as(String.class),相反,它应该是cast(x'00010002', char),或者cast(x'00010002', char(N)在那里N是一个合适的足够大的数量.
我已将此抛出失败的原因与org.hibernate提供的MySqlDialect隔离开来.尤其:
public String getCastTypeName(int code) {
if ( code==Types.INTEGER ) {
return "signed";
}
else if ( code==Types.VARCHAR ) {
return "char";
}
...snip...
}
Run Code Online (Sandbox Code Playgroud)
链的哪一个被解释为a char,由对话框注册:registerColumnType( Types.CHAR, "char(1)" );.
最后,对我的问题.我该如何解决这个问题?我是否将其报告为Hibernate的错误?我是否扩展了Dialog并从getCastTypeName更正了返回的类型?是否有 …
我有一个Lawsuit包含a 的类,List<Hearing>每个类都有一个Date属性.
我需要选择所有按照Lawsuits日期排序的Hearings
我有一个CriteriaQuery之类的
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Lawsuit> cq = cb.createQuery(Lawsuit.class);
Root<Lawsuit> root = cq.from(Lawsuit.class);
Run Code Online (Sandbox Code Playgroud)
我使用distinct来展平结果:
cq.select(root).distinct(true);
Run Code Online (Sandbox Code Playgroud)
然后我加入 Lawsuit与Hearing
Join<Lawsuit, Hearing> hearing = root.join("hearings", JoinType.INNER);
Run Code Online (Sandbox Code Playgroud)
创造Predicates
predicateList.add(cb.isNotNull(hearing.<Date>get("date")));
Run Code Online (Sandbox Code Playgroud)
和Orders:
orderList.add(cb.asc(hearing.<Date>get("date")));
Run Code Online (Sandbox Code Playgroud)
如果我避免distinct,一切正常,但如果我使用它,它会抱怨无法根据SELECT中没有的字段进行排序:
引起:org.postgresql.util.PSQLException:错误:for
SELECT DISTINCT,ORDER BY表达式必须出现在选择列表中
将List<Hearing>已经访问过Lawsuit班回来了,所以我很困惑:我应该如何将它们添加到选择列表?
我使用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)
或类似的东西存在?我认为这是别名的基本问题
我有以下实体; Ticket包含一组0,N WorkOrder:
@Entity
public class Ticket {
...
@OneToMany(mappedBy="ticket", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<WorkOrder> workOrders = null;
...
}
@Entity
public class WorkOrder {
...
@ManyToOne
@JoinColumn(nullable = false)
private Ticket ticket;
}
Run Code Online (Sandbox Code Playgroud)
我正在加载Tickets并获取属性.所有0,1属性都没有问题.对于workOrders,我使用此答案来获取以下代码.
CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();
CriteriaQuery<Ticket> criteriaQuery = criteriaBuilder
.createQuery(Ticket.class);
Root<Ticket> rootTicket = criteriaQuery.from(Ticket.class);
ListAttribute<? super Ticket, WorkOrder> workOrders =
rootTicket.getModel().getList("workOrders", WorkOrder.class);
rootTicket.fetch(workOrders, JoinType.LEFT);
// WHERE logic
...
criteriaQuery.select(rootTicket);
TypedQuery<Ticket> query = this.entityManager.createQuery(criteriaQuery);
return query.getResultList();
Run Code Online (Sandbox Code Playgroud)
结果是,在一个查询应该返回1个带有5个workOrders的Ticket,我正在检索相同的Ticket 5次.
如果我只是让workOrders成为一个Eager Fetch并删除了获取代码,它就可以正常工作.
谁能帮我?提前致谢.
更新: …
我正在尝试使用CriteriaBuilderAPI 通过一个查询删除一堆对象.我正在寻找像这样的选择:
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<T> query = criteriaBuilder.createQuery(entityClass);
Root<T> root = query.from(entityClass);
query.select(root).where(/*some condition*/);
return entityManager.createQuery(query).getResultList();
Run Code Online (Sandbox Code Playgroud)
但后来删除而不是选择.据我所知,没有remove或delete方法CriteriaQuery.是否可以使用此API?
我当然可以执行select,然后调用entityManager.remove(object)每个结果,但这感觉非常低效.
此查询用于以一对多关系检索最后的记录(请参阅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
criteria-api ×10
jpa-2.0 ×7
java ×6
jpa ×5
hibernate ×3
alias ×1
annotations ×1
casting ×1
dynamic ×1
grails ×1
mysql ×1
postgresql ×1
projection ×1