我想创建一个
DataType
,其行为类似于 SQLDataType.VARCHAR
,除了在 sql server 上它的长度是指定长度的三倍,这可能吗?
以下代码应在 MySQL 上创建
varchar(15)
,但在 SQL Server 上创建 varchar(45)
:
create.createTable("table")
.column("col1", myVarchar.length(15))
.execute();
我认为这会起作用,如果
construct()
方法和大 DefaultDataType
构造函数不是包私有的:
myVarchar = new DefaultDataType<>(null, String.class, "varchar(l)");
new DefaultDataType<>(SQLDialect.MYSQL, myVarchar, "varchar", "char");
new SqlServerCharType(myVarchar);
private class SqlServerCharType extends DefaultDataType<String> {
public SqlServerCharType(DataType<String> baseType) {
super(SQLDialect.SQLSERVER, baseType, "varchar", "varchar(max)");
}
DefaultDataType<String> construct(Integer newPrecision, Integer newScale, Integer newLength, Nullability newNullability, boolean newReadonly, Generator<?, ?, String> newGeneratedAlwaysAs, QOM.GenerationOption newGenerationOption, QOM.GenerationLocation newGenerationLocation, Collation newCollation, CharacterSet newCharacterSet, boolean newIdentity, Field<String> newDefaultValue) {
return new DefaultDataType(this, newPrecision, newScale, newLength * 3, newNullability, newReadonly, newGeneratedAlwaysAs, newGenerationOption, newGenerationLocation, newCollation, newCharacterSet, newIdentity, newDefaultValue);
}
}
是否可以用
Binding
来做到这一点?我唯一的选择是等到建立连接、了解方言后再做这样的事情吗?
create.createTable("table")
.column("col1", multiply(create, SQLDataType.VARCHAR(15))
.execute();
...
private <T> DataType<T> multiply(Scope scope, DataType<T> type) {
if (scope.dialect().family().equals(SQLDialect.SQLSERVER) && type.isString()) {
return type.length(type.length() * 3);
}
return type;
}
ExecuteListener
来替换任何 QOM.CreateTable
查询,如果您的条件匹配,例如:
ExecuteListener.onRenderStart(ctx -> {
if (ctx.family() == SQLSERVER
&& ctx.query() instanceof QOM.CreateTable ct
) {
if (ct.$tableElements().stream().anyMatch(e ->
e instanceof Field<?> f && f.getDataType().isString()
)) {
ctx.query(ct.$tableElements(ct.$tableElements()
.stream()
.map(e -> {
if (e instanceof Field<?> f && f.getDataType().isString())
return DSL.field(
f.getQualifiedName(),
f.getDataType().length(f.getDataType().length() * 3)
);
else
return e;
})
.toList()
));
}
}
});
现在,这将适用于 jOOQ 的任何地方,包括例如解析器:
configuration.set(l);
configuration.dsl()
.parser()
.parseQuery("create table t (i int, j varchar(10))")
.execute();
您可以在日志中看到:
Executing query : create table t (i int, j varchar(30))