JOOQ使用另一个POJO获取POJO对象 - 表中的外键

时间:2016-08-30 21:38:15

标签: java jooq

我是使用JOOQ的新手,我遇到了问题,但我找不到解决方案。我有两个表的简单数据库:SellersClients - 下面的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)
);

Clientforeign 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);

我应该改变什么才能得到我想要的东西?

1 个答案:

答案 0 :(得分:1)

查看Lukas Eder(jOOQ的作者)和其他一些jOOQ用户之间的对话here。 Garrett Wilson的用例看起来与你的用例非常相似(你有ClientSeller,他有BookAuthor)。

有很多说法,但是按照设计,似乎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专家,但是我过去使用的方法,当我在一个查询中返回分层类型的列时,对我来说非常好:

  1. 定义自定义记录映射器,将您的jOOQ Record映射到您的域类型/ POJO
  2. 定义自定义RecordMapperProvider并使用它创建DSLContext单例,将其传递给您查询的任何组件(例如通过依赖注入)
  3. 使用上述DSLContext撰写查询并使用fetchInto()指定您的目标类型(应在RecordMapperProvider中说明)
  4. 在之前引用的对话中,Lukas将link删除了有关使用自定义RecordMapperProvider实例的文档,因此这很可能是惯用的。

    希望有所帮助。