java - QueryDSL 与 Spring Boot Data JPA 的交集
问题描述
我在 Spring Boot、Spring Data JPA 项目中使用 QueryDSL。我有一个名为的表的以下架构test
:
| id | key | value |
|----|------|-------|
| 1 | test | hello |
| 1 | test | world |
| 2 | test | hello |
| 2 | foo | bar |
| 3 | test | hello |
| 3 | test | world |
现在我想在 QueryDSL 中编写以下 SQL:
select id from test where key = 'test' and value = 'hello'
INTERSECT
select id from test where key = 'test' and value = 'world'
这会给我所有的 ID,其中键是“测试”,值是“你好”和“世界”。
我还没有找到在 QueryDSL 中声明这种 SQL 的任何方法。我能够编写两个 select 语句,但后来我被困在将它们与INTERSECT
.
JPAQueryFactory queryFactory = new JPAQueryFactory(em); // em is an EntityManager
QTestEntity qTestEntity = QTestEntity.testEntity;
var q1 = queryFactory.query().from(qTestEntity).select(qTestEntity.id).where(qTestEntity.key("test").and(qTestEntity.value.eq("hello")));
var q2 = queryFactory.query().from(qTestEntity).select(qTestEntity.id).where(qTestEntity.key("test").and(qTestEntity.value.eq("world")));;
最后,我想检索与给定查询匹配的 id 列表。一般来说,相交的数量可能在 20 或 30 左右,具体取决于我要搜索的键/值对的数量。
有谁知道如何用 QueryDSL 做这样的事情?
编辑:
现在假设以下模式,有两个表:test
和“用户”:
test:
| userId | key | value |
|---------|------|-------|
| 1 | test | hello |
| 1 | test | world |
| 2 | test | hello |
| 2 | foo | bar |
| 3 | test | hello |
| 3 | test | world |
user:
| id | name |
|----|----------|
| 1 | John |
| 2 | Anna |
| 3 | Felicita |
对应的 java 类如下所示。TestEntity
有一个由其所有属性组成的复合键。
@Entity
public class TestEntity {
@Id
@Column(name = "userId", nullable = false)
private String pubmedId;
@Id
@Column(name = "value", nullable = false)
private String value;
@Id
@Column(name = "key", nullable = false)
private String key;
}
@Entity
class User {
@Id
private int id;
private String name;
@ElementCollection
private Set<TestEntity> keyValues;
}
如何将test
表映射到类中的keyValues
属性User
?
解决方案
您的 TestEntity 并不是真正的实体,因为它的 id 不是主键,而是用户表的外键。
如果它只能通过使用它的所有属性来识别,它就是一个@Embeddable,并且没有任何@Id 属性。
您可以将 Embeddables 的集合映射为另一个以 id 作为主键的实体的 @ElementCollection 部分。您的情况下的 id 列不是 Embeddable 的属性,它只是主表的外键,因此您将其映射为@JoinColumn:
@Embeddable
public class TestEmbeddable {
@Column(name = "value", nullable = false)
private String value;
@Column(name = "key", nullable = false)
private String key;
}
@Entity
class User {
@Id
private int id;
@ElementCollection
@CollectionTable(
name="test",
joinColumns=@JoinColumn(name="id")
)
private Set<TestEmbeddable> keyValues;
}
在这种情况下,QueryDSL 变成了这样(不知道确切的 api):
user.keyValues.any().in(new TestEmbeddable("test", "hello"))
.and(user.keyValues.keyValues.any().in(new TestEmbeddable("test", "world"))
推荐阅读
- amazon-web-services - AWS cognito 用户池的 EmailConfiguration
- php - laravel 6 + elasticsearch-php 7.6 + xampp:在您的集群中找不到活动节点
- java - 为@ApiResponse 设置自定义示例
- c# - 使用 NUnit 模拟 EF 的 ExecuteSqlCommand
- python - 谁能建议一种更快的方法来创建这个数组?
- swift - 如何在 SwiftUI 中制作时区选择器?
- azure - Kusto 查询:根据时间检索最近的 2 次运行并进行汇总
- javascript - 根据条件更改 Bootstrap 弹出框
- ios - iPad 上的 SwiftUI 弹出框随设备旋转而移动
- python - Python重复字典