如何使用jOOQ抽象模式?

时间:2017-08-25 01:18:54

标签: java sql jooq

我试图关注instructions for mapping a schema in jOOQ

首先,我从限定名称和表开始:

Name myTableName = DSL.name("schema", "myTable");
Table<Record> myTable = DSL.table(myTableName);

然后我用架构映射构建一个上下文:

Configuration configuration = new DefaultConfiguration();
configuration.set(SQLDialect.HSQLDB);
Settings settings = new Settings()
    .withRenderNameStyle(RenderNameStyle.QUOTED)
    .withRenderSchema(true)
    .withRenderMapping(
        new RenderMapping()
            .withSchemata(
                new MappedSchema()
                    .withInput("schema")
                    .withOutput("PUBLIC")
            )
    );
configuration.set(settings);
return DSL.using(configuration);

然后我构建一个SQL字符串来创建表:

context.createTable(myTable)....getSQL();

但它无法映射架构:

invalid schema name: schema in statement [create table "schema"."myTable"(
    ...

我到底错在了什么?

从更大的角度来看,我正在尝试编写可以跨不同方言移植的SQL,但我必须构建的每个环境都使用不同的模式。我试图在Java中抽象出一个通用模式,然后我可以根据目标环境使用jOOQ进行映射。

1 个答案:

答案 0 :(得分:1)

这是一个众所周知的问题:https://github.com/jOOQ/jOOQ/issues/5344

从jOOQ 3.9.5开始,架构映射和表映射不适用于纯SQL表和自定义命名表。虽然不会对普通SQL字符串应用任何映射,但后者在jOOQ 3.10中已得到修复。

有两种解决方法:

您可以手动执行映射

您可以完全控制表格引用构造,并可以明确地映射表格:

Name myTableName = DSL.name(schema(), "myTable");

然后:

public String schema() {
    if (something)
        return "schema";
    else
        return "PUBLIC";
}

使用CustomTable

一个鲜为人知的特性是CustomTable,如果您不使用jOOQ的代码生成器,可以使用它来代替生成的表。它比普通的SQL表或命名表要省力,但是如果你可以抽象表的结构,那么它可能是值得的,因为CustomTable允许很容易。一个例子:

public class BookRecord extends CustomRecord<BookRecord> {
    protected BookRecord() {
        super(BookTable.BOOK);
    }
}

public class BookTable extends CustomTable<BookRecord> {
    public static final BookTable                      BOOK       = new BookTable();

    public static final TableField<BookRecord, Short>  ID         
      = createField("ID", SQLDataType.SMALLINT, BOOK);
    public static final TableField<BookRecord, String> TITLE      
      = createField("TITLE", SQLDataType.VARCHAR, BOOK);

    protected BookTable() {
        super("BOOK", DSL.schema(DSL.name("schema")));
    }

    @Override
    public Class<? extends BookRecord> getRecordType() {
        return BookRecord.class;
    }
}