我有两张桌子:
CREATE TABLE [instrument].[InstrumentType] (
[InstrumentTypeId] INT NOT NULL IDENTITY (1, 1),
[Name] VARCHAR (255) NOT NULL,
CONSTRAINT [PK_InstrumentType] PRIMARY KEY CLUSTERED ([InstrumentTypeId] ASC)
);
CREATE TABLE [instrument].[Instrument] (
[InstrumentId] INT NOT NULL IDENTITY (1, 1),
[InstrumentTypeId] INT NOT NULL,
[Name] VARCHAR (255) NOT NULL,
CONSTRAINT [PK_Instrument] PRIMARY KEY CLUSTERED ([InstrumentId] ASC),
CONSTRAINT [FK_Instrument_InstrumentType] FOREIGN KEY ([InstrumentTypeId]) REFERENCES [instrument].[InstrumentType] ([InstrumentTypeId])
);
我可以简单地获取仪器类型,而无需编写连接(很棒的功能):
create.select(INSTRUMENT.INSTRUMENTID, INSTRUMENT.NAME, INSTRUMENT.instrumenttype.NAME)
.from(INSTRUMENT)
.fetch()
我有很多与此类似的表,我想以编程方式创建此查询。我尝试使用
INSTRUMENT.references
但查询失败,因为它引用 IDENTIFIERTYPE
表而不是使用 INSTRUMENT.instrumenttype
路径。这是我的 fetch
方法呈现的查询:
select
[instrument].[Instrument].[InstrumentId],
[instrument].[Instrument].[Name],
[instrument].[InstrumentType].[Name]
from [instrument].[Instrument]
这是我到目前为止所拥有的,但我找不到像手动查询一样通过外键路径的正确方法。
val T = INSTRUMENT
fun fetch(dsl: DSLContext): Any {
return dsl
.select(fieldList())
.from(T)
.fetch()
}
protected open fun fieldList(): Set<Field<*>> {
val result = mutableSetOf<Field<*>>()
val tables = fkTableList(T)
for (t in tables) {
val fk = t.references.flatMap { it.fields }.toSet()
val include = t.fields().toSet()
//Remove INSTRUMENTTYPEID
val selectedFields = include - fk
result.addAll(selectedFields)
}
return result
}
private fun fkTableList(table: Table<*>): List<Table<*>> {
val result = mutableListOf(table)
val fkTables = table.references.map { it.key.table }
result.addAll(fkTables.flatMap { fkTableList(it) })
return result
}
注意,有一个以编程方式构造
org.jooq.Path
实例的功能请求,您可能对此感兴趣:
截至 jOOQ 3.19 尚未实施。如果不使用
Path
类型,您必须自己显式添加连接树。您不能仅添加投影。一个相对简单的方法是使用 ON KEY
合成连接语法(jOOQ 的 Path
实现也在内部使用):
.from(tableList())
然后:
protected open fun tableList(): Set<Table<*>> {
var result = T
for (t in fkTableList(T)) {
// inner join would be possible in case there's a NOT NULL constraint
// on the foreign key columns
result = result.leftJoin(t).onKey()
}
return result
}
onKey()
方法本身无法解决歧义,如果您在同一个子表和父表之间有多个外键,因此最好重构递归fkTableList
函数以返回ForeignKey
实例,并使用它.