我尝试将以下简单查询转换为JPA条件API:
SELECT ticket_action.ticket_id IS NOT NULL, ticket.id
FROM ticket
LEFT OUTER JOIN ticket_action ON ticket.id = ticket_action.ticket_id
我尝试了两种方法:
1.使用criteriaBuilder.function("ISNULL", Boolean.class, ticketAction.get(TicketAction_.ticketId))
:问题是,如果ISNULL
类似于ISNOTNULL
(对于MySQL/MariaDB数据库),则不存在否定
1.使用criteriaBuilder.isNotNull(ticketAction.get(TicketAction_.ticketId))
:但这将返回Predicate
,而select语句只接受Expression
扩展目标:与GROUP BY ticket.ticket_id IS NOT NULL
相同
所请求的表结构
+-----------+---------+
| ticket |
+-----------+---------+
| name | type |
+-----------+---------+
| id | integer |
| title | varchar |
+-----------+---------+
+-----------+---------+
| ticket_action |
+-----------+---------+
| name | type |
+-----------+---------+
| id | integer |
| ticket_id | integer |
| title | varchar |
+-----------+---------+
结果:
最后,我使用了一个构造函数查询,它接收ticket_action
的id
以及其他信息。this.hasTicketAction = ticketActionId != null;
不是很满意,但工作。
谢谢大家张贴您的答案!
3条答案
按热度按时间vnjpjtjt1#
一种工作方法是使用
CriteriaBuilder.selectCase(..)
。与
DTO
类似(Object[]
的作用相同,但从一开始就是类型安全的)可以通过以下查询获得结果
关于分组,我不太明白你需要什么分组,但例如
将返回具有和不具有
TicketAction
的Ticket
的计数。我不知道实际的原因,但问题 * 似乎是 * 在
cb.isNotNull(..)
(我的)JPA
实现中要么总是获取似乎不是null
的内容要么根据检查null
的方式,它创建了一些INNER JOIN
,因此null
值从结果集中被丢弃。(我正在使用OpenJPA)
2lpgd9682#
对于此查询,您需要有
@OneToMany
类型的集合属性。此外,我不得不使用Tuple
而不是TicketTuple
(在this答案中引用),因为在处理没有票证的ticket_actions时,它会给出IllegalArgumentException
(参数类型不匹配),我不知道您的架构中是否有这种可能性。EclipseLink JPA实现、Derby数据库。
在类
Ticket
中,必须具有以下属性:条件查询代码:
产生的查询:
w8ntj3qf3#
您可以使用下面的示例在select表达式中生成 is not null:
我认为生成的查询将抛出一个查询语法异常,因为jpa/hib可能不支持在select表达式中包含 is not null。如果是这种情况,那么一个可能的解决方案是在where子句中放置 is not null。您可以在这里找到这种情况的示例https://docs.oracle.com/cd/E19798-01/821-1841/gjitv/index.html