我是使用JOOQ的新手,我遇到了问题,但我找不到解决方案。我有两个表的简单数据库:Sellers
和Clients
- 下面的sql:
CREATE TABLE Sellers
(
id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
name varchar(255) NOT NULL,
);
CREATE TABLE Clients
(
id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
name varchar(255) NOT NULL,
seller_id int,
FOREIGN KEY (seller_id) REFERENCES Sellers(id)
);
Client
有foreign key
,它定义了为其分配的Seller
。
我想使用JOOQ从数据库中获取客户端,但使用join()
也会向每个客户端获取Seller
个对象。可能吗?如果是这样怎么办?这是我的POJO对象:
public class Seller {
private final SimpleIntegerProperty id = new SimpleIntegerProperty();
private final SimpleStringProperty name = new SimpleStringProperty();
...
//setters and getters here
...
}
public class Client {
private final SimpleIntegerProperty id = new SimpleIntegerProperty();
private final SimpleStringProperty name = new SimpleStringProperty();
private final SimpleIntegerProperty sellerId = new SimpleIntegerProperty();
//private Seller seller; //not working
...
//setters and getters here
...
}
这是我的JOOQ代码来获取客户:
context.select()
.from(CLIENTS)
.join(SELLERS)
.on(CLIENTS.ID.eq(SELLERS.ID))
.fetchInto(Client.class);
我应该改变什么才能得到我想要的东西?
答案 0 :(得分:1)
查看Lukas Eder(jOOQ的作者)和其他一些jOOQ用户之间的对话here。 Garrett Wilson的用例看起来与你的用例非常相似(你有Client
:Seller
,他有Book
:Author
)。
有很多说法,但是按照设计,似乎jOOQ不适合在你提取的Seller
记录中自动保护Client
个实例。这是与ORM相关的经典N + 1问题(即针对客户查询触发的卖家表的多个查询)。
一项建议是将您的联接分解为离散查询:
select * from Client where ...
select * from Seller where id in (select seller_id from Client where ...)
...然后在应用程序的某处执行client.setSeller()
类型逻辑。在这种情况下,您可以避免N + 1问题,并且您无需依赖编写自定义任何RecordMapper
类型。
我不是jOOQ专家,但是我过去使用的方法,当我在一个查询中返回分层类型的列时,对我来说非常好:
Record
映射到您的域类型/ POJO RecordMapperProvider
并使用它创建DSLContext
单例,将其传递给您查询的任何组件(例如通过依赖注入)DSLContext
撰写查询并使用fetchInto()
指定您的目标类型(应在RecordMapperProvider
中说明)在之前引用的对话中,Lukas将link删除了有关使用自定义RecordMapperProvider
实例的文档,因此这很可能是惯用的。