当前位置: 首页 > 知识库问答 >
问题:

JOOQ:在公共接口中对不同表中的列进行逻辑分组

蒙勇
2023-03-14

我们有一种表设计,其中许多表共享一些列,例如,在一种情况下,我们的一些表将列标记为deletion。在另一种情况下,我们的多个表具有列approvedAtapprovedBy。这些表在待连接数据方面不共享任何内容,因此,我不想为这些数据引入公共连接表(由于性能问题,这也不是一个选项)。

但是从应用的角度来看,我确实有非常相似的任务要执行。例如,如果我创建了一个新行,在哪个表中插入条目并不重要,我需要从请求中提取审批者和请求时间来将其填充到我的表中,以及稍后的其他行数据我的代码。

在JOOQ中,我现在可以做如下事情

private void insertApprovalInformation(Record record, RequestContext ctx) {
   record.set(DSL.field("approver"), ctx.getRequestUser());
   record.set(DSL.field("approvedAt"), ctx.getRequestTime());
}

然而,我将失去所有我心爱的类型安全与该方法。理想情况下,我想写一些

private void insertApprovalInformation(Approvablerecord record, RequestContext ctx) {
   record.set(ApprovableTable.APPROVER, ctx.getRequestUser());
   record.set(ApprovableTable.APPROVED_AT, ctx.getRequestTime());
}

我知道这类似于Postgres继承特性,但我希望它更独立于数据库,并希望在Oracle数据库中使用它。我想象一下,配置JOOQ生成器并告诉它“这四个表属于一个逻辑组,我将其命名为“approvable”,它们都有APPROVERAPPROVED\u AT”列这将让JOOQ生成类,例如为该组实现标记接口。

我认为在考虑历史化、批准、标记删除行等常见任务时,这可能是一个相当频繁使用的特性。

我的问题是:

  • 在JOOQ中是否已经有一种方法可以实现我想要的类型安全结果
  • 关于如何以类型安全的方式处理此场景,还有其他建议吗
  • 还是我应该忘记这里的类型安全性

共有1个答案

焦苏燕
2023-03-14

JOOQ3.14引入了“嵌入式类型”,它在代码生成器的基础上彻底解决了这个问题。您可以这样定义一个可嵌入的:

<configuration>
  <generator>
    <database>
      <embeddables>
        <embeddable>
          <name>APPROVAL_INFORMATION</name>
          <fields>
            <field><expression>APPROVER</expression></field>
            <field><expression>APPROVED_AT</expression></field>
          </fields>
        </embeddable>
      </embeddables>
    </database>
  </generator>
</configuration>

(可以进行更具体的配置,有关详细信息,请参阅手册)。现在将为您生成一个辅助embeddedBlerecord,格式如下:

public class ApprovalInformationRecord
extends EmbeddableRecordImpl<ApprovalInformationRecord> {
    public ApprovalInformationRecord(
        String approver, LocalDateTime approvedAt
    ) { /* ... */ }
    
    // Getters, setters
}

您可以在查询、投影等中使用此可嵌入列,而不是底层列。

Result<Record2<Long, ApprovalInformationRecord>> result =
ctx.select(T.ID, T.APPROVAL_INFORMATION)
   .from(T)
   .where(T.APPROVAL_INFORMATION.eq(new ApprovalInformationRecord(...))
   .fetch();

您可以轻松地配置和扩展jOOQ代码生成器,为您添加类型信息。由于您希望处理生成的记录,只需在代码库中添加如下新接口:

public interface Approvable {
    void setApprover(String approver);
    void setApprovedAt(Timestamp approvedAt);
}

然后配置代码生成器,让所有相关生成的记录使用生成器策略实现上述接口:

  • 计划的
  • 构型的

一个配置示例:

..
<generator>
  <strategy>
    <matchers>
      <tables>
        <table>
          <expression>MY_TABLE</expression>
          <recordImplements>com.example.Approvable</recordImplements>
        </table>
      </tables>
    </matchers>
  </strategy>
</generator>
 类似资料:
  • 请你澄清我的疑问: WebDriver驱动程序=new ChromeDriver(); 我们知道WebDriver是一个in接口,Chrome驱动程序是类,它实现了 Web驱动程序接口。 这意味着,无论接口中定义了什么方法,我们都只是用Chrome驱动程序类重写了相同的方法。 现在,如果我们像上面那样编写代码。。。。我们仍然可以运行代码。 现在我的疑问是: 我们这里不涉及Webdriver接口。但

  • 问题内容: 我想获取所有行(至少)在df [mylist]中的一列包含True。 我目前正在做: 其中mylist是与的列有关的字符串列表df。但我想在不限长度的情况下进行此操作mylist。 我能想到的唯一方法是循环并为其每个元素创建一个新的数据框,然后进行合并/合并或其他操作。但这对我来说并不聪明。 有没有更好的办法? 问题答案: 建立在LondonRob的答案上,您可以使用 与每行一次调用P

  • 我有一个对象列表 销售模式为: 轮班模式为: 如何按名称对中的项目进行分组,然后对相应的销售和班次进行求和?所以,如果我在列表中有两个名称相同的项目,那么将它们分组,并求和其销售额和移动量? 我尝试过stream,但没有成功: 另一种选择是: 在这种情况下,我不知道如何求和相应的销售额和班次 编辑 下面是预期结果的示例:

  • 问题内容: 我正在尝试整理实现公共接口的对象列表。涉及3个类和1个接口: 社区 类(具有一种方法: List getPeople(); ) 人员 接口(具有一种方法: String getName(); ) 女生 班(实施人员) 男生 班(实施人员) 请参见下面的代码。 我想要一个看起来像这样的XML: 或可能: 到目前为止,我得到的是: 我意识到我可以将元素更改为其他名称,但是我希望元素名称成为

  • 我已经使用反射发射很长一段时间了,但这次它根本没有意义......在我的程序中的某个地方,我正在使用 emit 实现接口。例如: 因为我正在实现多个接口,并且接口可以从其他接口继承,所以我会消除重复的方法/接口。(虽然它在这里不相关,但我将使用一些众所周知的接口作为我的例子)。例如,如果我同时实现 IList 和 I 词典,它们都实现 ICollection,而我只实现一次 ICect。 之后,我

  • 我有三张桌子: 我想从表1中选择COL1,从表2中选择COL5,从表3中选择COL4 它喜欢两个联接表,但是当我使用以下查询时,它不起作用,COL5是空白的。 请帮忙。 PS我复制了之前的一个类似示例,但输出不同。