【问题标题】:JOOQ get POJO object with another POJO - foreign key in tableJOOQ 使用另一个 POJO 获取 POJO 对象 - 表中的外键
【发布时间】:2017-01-07 07:53:12
【问题描述】:

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

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

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

【问题讨论】:

  • Clientseller 作为对象。 DB 有seller_id 作为int。 JOOQ 会自动解决这个问题吗?
  • @bradimus 它会自动将 Seller_id 解析为 int,但正如您在我的 Client 类中看到的那样,我也尝试添加对象 Seller Seller,但没有解决。

标签: java jooq


【解决方案1】:

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

有很多说法,但从设计上看,jOOQ 似乎并不适合在您获取的Client 记录中自动补充Seller 实例。这是与 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 中说明)

在前面提到的对话中,Lukas 将link 添加到有关使用自定义RecordMapperProvider 实例的文档中,因此这很可能是惯用的。

希望有帮助。

【讨论】:

    猜你喜欢
    • 2021-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-08
    • 2022-01-19
    • 2017-09-08
    • 2018-03-31
    相关资源
    最近更新 更多