如何以通用方式获取新记录的ID? (JOOQ 3.4与Postgres)

时间:2014-09-19 09:15:10

标签: java sql postgresql jooq

使用jooq 3.4我无法弄清楚如何做到这一点(使用Postgresql):

Query query = dsl.insertInto(TABLE)
    .set(TABLE.ID, Sequences.TABLE_ID_SEQ.nextval());

但是当我不知道哪个是确切的表时,就像这样:

TableImpl<?> tableImpl;

Query query = dsl.insertInto(tableImpl)
    .set(tableImpl.getIdentity(), tableImpl.getIdentity().getSequence().nextval());

有可能吗?

我试过了:

dsl.insertInto(tableImpl)
    .set(DSL.field("id"), 
        tableImpl.getSchema().getSequence("table_id_seq").nextval())

这有效但我仍然不知道如何从TableImpl对象获取序列名称。

有解决方案吗?或者我的方法有问题吗?

在纯SQL中我会这样做:

insert into table_A (id) VALUES nextval('table_A_id_seq');
insert into table_B (table_A_id, some_val) VALUES (currval('table_A_id_seq'), some_val);

所以我需要值或对该id的引用,以便以后使用为插入记录生成的id作为默认值,但我不想设置任何其他值。

1 个答案:

答案 0 :(得分:1)

jOOQ目前没有任何方法可以将表与其隐式使用的标识列序列相关联。原因是在创建表时生成序列,但它没有正式连接到该表。

通常,您不必在PostgreSQL数据库中显式设置列的serial值。它在插入时自动生成。就DDL而言,这意味着:

CREATE TABLE tablename (
    colname SERIAL
);

相当于指定:

CREATE SEQUENCE tablename_colname_seq;
CREATE TABLE tablename (
    colname integer NOT NULL DEFAULT nextval('tablename_colname_seq')
);
ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;

以上摘自: http://www.postgresql.org/docs/9.3/static/datatype-numeric.html#DATATYPE-SERIAL

换句话说,只需忽略ID语句中的INSERT值。

“清空”INSERT语句

请注意,如果要创建“空”INSERT语句,即根本不传递任何值的语句,生成带有生成ID的新列,则可以使用DEFAULT VALUES子句。

使用SQL

INSERT INTO tablename DEFAULT VALUES

使用jOOQ

DSL.using(configuration)
   .insertInto(TABLENAME)
   .defaultValues()
   .execute();

返回ID

请注意,PostgreSQL本身支持INSERT .. RETURNING子句,jOOQ也支持该子句:

使用SQL

INSERT INTO tablename (...) VALUES (...) RETURNING ID

使用jOOQ

DSL.using(configuration)
   .insertInto(TABLENAME, ...)
   .values(...)
   .returning(TABLENAME.ID)
   .fetchOne();