ExecuteListener 提取 ExecuteContext 表、列和行值

问题描述 投票:0回答:1
我正在使用 jOOQ

ExecuteListener

 SPI 来执行外部 API 调用作为预提交挂钩。我的目标是使用一些插入的值调用网络调用(逻辑将根据每个表编写),如果失败,事务应该回滚。

这是我首先尝试的:

使用

ExecuteContext

 实例,我可以访问查询、SQL 语句、参数。但是,如果不解析字符串 SQL 语句,我就无法知道表名是什么。

public class WriteListener implements ExecuteListener { @Override public void end(ExecuteContext ctx) { if (ctx.type() == ExecuteType.WRITE) { // extract table, rows and their values final org.jooq.Query query = ctx.query(); // tried to cast to InsertQuery too final org.jooq.Record record = ctx.record(); // can't access the values // etc.. } ExecuteListener.super.end(ctx); } }
另一个选择是尝试使用实验性 API 

QOM

:

public class WriteListener implements ExecuteListener { @Override public void end(ExecuteContext ctx) { if (ctx.query() instanceof QOM.Insert insert) { final Table table = insert.$into(); final var cols = insert.$columns(); final var rows = insert.$values(); // can't extract row values! } ExecuteListener.super.end(ctx); } }
我能够读取表格、列和字段。但是,如果没有反射就无法提取值。

最终目标是将记录转换为代码生成记录类型之一,在其中我可以获得强类型对象,并且会填充值。我不确定今天是否可能。理想情况下,寻找以下代码:

public class WriteListener implements ExecuteListener { @Override public void end(ExecuteContext ctx) { if (ctx.type() == ExecuteType.WRITE) { // NOTE: THIS DOES NOT WORK, IT'S AN IDEA ONLY. if (ctx.record() instanceof MyTableRowRecord record) { final DateTime createdAt = record.CREATED_AT; // invoke an external API call with the table name, and the created at value. } } ExecuteListener.super.end(ctx); } }
值得一提的是,我使用的是社区版,但如果这是另一层的 API,我愿意升级。

jooq
1个回答
0
投票
我能够读取表格、列和字段。但是,如果没有反射就无法提取值。

为什么需要反射来访问字段/值?

QOM.Insert.$values()

 返回 Row
 类型的列表,其中提供 
Row.$fields()
,每个 
Field
 可以是 
Param
(当然也可以是其他东西)。所以:

for (Row row : insert.$values()) { for (Field<?> field : row.$fields()) { if (field instanceof Param<?> param) { // ... } } }

最终目标是将记录转换为代码生成记录类型之一,在其中我可以获得强类型对象,并且会填充值。

ExecuteListener

 SPI 不知道任何“强类型对象”,例如 
UpdatableRecord
 类型。假设您最初调用的是这样的:

MyTableRowRecord record = ... record.insert();
这将在生成 

RecordListener

 语句之前触发 
INSERT
 SPI,该语句的执行随后会触发 
ExecuteListener
 SPI。但同样,后者不知道记录,而前者仅针对 
UpdatableRecord
 操作被调用。

© www.soinside.com 2019 - 2024. All rights reserved.