我试图关注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进行映射。
答案 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;
}
}