繁体   English   中英

在 jOOQ 中选择相同的命名列

[英]Selecting identical named columns in jOOQ

我目前使用 jOOQ 来构建我的 SQL(通过 mvn 插件生成代码)。

执行创建的查询不是由 jOOQ 完成的(为此使用 vert.X SqlClient)。

假设我想选择两个表的所有列,它们共享一些相同的列名。 例如UserAccount( id , name ,...)Product( id , name ,...) 执行以下代码时

val userTable = USER_ACCOUNT.`as`("u")
val productTable = PRODUCT.`as`("p") 

create().select().from(userTable).join(productTable).on(userTable.ID.eq(productTable.AUTHOR_ID))

构建方法query.getSQL(ParamType.NAMED)我返回一个查询,例如

SELECT "u"."id", "u"."name", ..., "p"."id", "p"."name", ... FROM ...

这里的问题是,结果集将包含两次没有前缀“u”的列ID名称 或“p.”,所以我无法正确映射/解析它。

有没有办法我可以对 jOOQ 说这些列的别名,如下所示,而无需任何进一步的手动操作?

SELECT "u"."id" AS "u.id", "u"."name" AS "u.name", ..., "p"."id" AS "p.id", "p"."name" AS "p.name" ...

我使用神圣的 Postgres 数据库 :)

编辑:目前的方法就像

val productFields = productTable.fields().map { it.`as`(name("p.${it.name}")) }
val userFields = userTable.fields().map { it.`as`(name("p.${it.name}")) }

create().select(productFields,userFields,...)...

虽然这感觉真的很hacky

如何正确地从记录中取消引用表

您应该始终使用传递给查询的列引用来取消引用结果中记录的值。 如果您没有明确传递列引用,则使用通过Table.fields()生成的表中的引用。

在您的代码中,这将对应于:

userTable.NAME
productTable.NAME

因此,在结果记录中,执行以下操作:

val rec = ...
rec[userTable.NAME]
rec[productTable.NAME]

使用Record.into(Table)

由于您似乎将所有列(您真的需要所有列吗?)投影到生成的 POJO 类,如果您愿意,您仍然可以执行此中间步骤:

val rec = ...
val userAccount: UserAccount = rec.into(userTable).into(UserAccount::class.java)
val product: Product = rec.into(productTable).into(Product::class.java)

因为生成的表包含所有必要的元数据,它可以决定哪些列属于它,哪些不属于它。 POJO 没有此元信息,这就是它无法消除重复列名的原因。

使用嵌套记录

您始终可以直接在 SQL 中使用嵌套记录,以生成以下两种类型之一:

  • Record2<Record[N], Record[N]> (例如使用DSL.row(table.fields())
  • Record2<UserAccountRecord, ProductRecord> (例如使用DSL.row(table.fields()).mapping(...) ,或从 jOOQ 3.17 开始直接使用Table<R>作为SelectField<R>

第二个 jOOQ 3.17 解决方案如下所示:

// Using an implicit join here, for convenience
create().select(productTable.userAccount(), productTable)
        .from(productTable)
        .fetch();

上面是使用隐式连接,为了额外的方便

自动别名所有列

在 SQL 中“自动别名”列时,用户可能希望拥有大量的风格。 jOOQ 提供的任何解决方案都不会比您已经找到的解决方案更好,因此,如果您仍想为所有列自动别名,那么只需执行您所做的即可。

但通常,对自动别名的渴望是由于误解了在 jOOQ 中做某事的最佳方法是什么(参见上面的选项)而衍生的功能请求,因此理想情况下,您不要遵循自动别名的道路。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM