使用 JOOQ 在通用插入中返回 id

Posted

技术标签:

【中文标题】使用 JOOQ 在通用插入中返回 id【英文标题】:Returning id in generic insert using JOOQ 【发布时间】:2019-09-18 00:29:47 【问题描述】:

我有一个非常通用的 API 可以使用 JOOQ 将内容插入到某些表中:

 void insert(@NonNull final Table<?> table,
                @NonNull final Collection<Field<?>> columns,
                @NonNull final Collection<Object> values) 
        dslContext.insertInto(table)
                .columns(columns)
                .values(values)
                .execute();
    

有没有办法返回插入记录的 id?我的数据库中表的所有主键都命名为“id”,因此我可以对其进行 ahrdcode,但我找不到将其返回并转换为 Integer/Long 的方法。 我正在使用 JOOQ 3.9.5。

编辑:我在下面使用 MSSQL。

【问题讨论】:

【参考方案1】:

写:

long insert(@NonNull final Table<?> table,
            @NonNull final Collection<Field<?>> columns,
            @NonNull final Collection<Object> values) 
    return dslContext
          .insertInto(table)
          .columns(columns)
          .values(values)
          .returningResult(table.field("ID")) // Replace with your field name case
          .fetchOne()
          .into(long.class);

这假设您正在使用生成的代码,其生成的Table 实例实现Table.getIdentity()。或者,如果你不能提供身份,你可以写:

long insert(@NonNull final Table<?> table,
            @NonNull final Collection<Field<?>> columns,
            @NonNull final Collection<Object> values) 
    dslContext
          .insertInto(table)
          .columns(columns)
          .values(values)
          .execute();
    return dslContext.lastID().longValue();

【讨论】:

我得到 NPE: java.lang.NullPointerException: null at com.xxx.db.rest.app.crud.CrudRepository.insert(Cru​​dRepository.java:48) at sun.reflect.NativeMethodAccessorImpl .invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java :498) 仅供参考:我使用 DSL.table(String sql) 从纯字符串创建表 我没有使用生成的代码 - 使用 DSL.table(String sql) 创建表,然后处理它。 @ohwelppp:我明白了,那么您对这种方法不走运。 jOOQ 需要在 returning 调用时附加到您的表的身份信息。请参阅:github.com/jOOQ/jOOQ/issues/2943。但是,您可以使用DSLContext.lastID():jooq.org/javadoc/latest/org/jooq/DSLContext.html#lastID--。我会更新我的答案 使用 lastID() 是否有可能同时通过此 api 插入一些其他记录(我们有很多实例),并将返回该其他 ID 或在该上下文中获取 ID()所以我确定我会返回该插入记录的 ID?问是因为我必须确保我返回正确的 ID,而不是同时由其他 api 实例保存的 ID @ohwelppp: lastID() 执行获取@@identity 的查询。如果@@identity 不符合您的要求,您可以手动使用不同的 SQL Server 功能。

以上是关于使用 JOOQ 在通用插入中返回 id的主要内容,如果未能解决你的问题,请参考以下文章

JOOQ:在通用界面中对来自不同表的列进行逻辑分组

jOOQ 插入查询并返回生成的键

用于检索插入的最后一行的通用 SQL 构造

EF Generic Repository 从新插入的通用实体获取 Id

java.sql.ResultSet、CallableStatement、SQLInput 没有通用接口

如何在使用 jooq 生成的 dao 插入/更新后获取插入/更新的对象