如何在jOOQ中使用行值表达式?

时间:2014-04-26 09:40:05

标签: java sql jooq

jOOQ博客声称它是ten more common mistakes that Java developers make when writing SQL中的一个,不使用支持行值表达式。

他们的建议是发出如下的SQL(而不是用AND链接几个单列条件):

SELECT c.address
FROM   customer c,
WHERE (c.first_name, c.last_name) = (?, ?)

SELECT c.first_name, c.last_name, a.street
FROM   customer c
JOIN   address a
ON  (c.id, c.tenant_id) = (a.id, a.tenant_id)

但是我如何在jOOQ中实际编码呢?

1 个答案:

答案 0 :(得分:1)

缺少Java中元组/记录的语言支持,您需要使用许多重载DSL.row()方法中的一种。

您的示例(来自问题)将转换为:

// Assuming static imports:
import static org.jooq.impl.DSL.row;
import static your.generated.code.Tables.CUSTOMER;

Customer c = CUSTOMER.as("c");
Address a = ADDRESS.as("a");

DSL.using(configuration)
   .select(c.ADDRESS)
   .from(c)
   .where(row(c.FIRST_NAME, c.LAST_NAME).eq("Jon", "Doe"))
   //         ^^^^^^^^^^^^  ^^^^^^^^^^^ <-> ^^^^^  ^^^^^ Types must match
   .fetch();

DSL.using(configuration)
   .select(c.FIRST_NAME, c.LAST_NAME, a.STREET)
   .from(c)
   .join(a)
   .on(row(c.ID, c.TENANT_ID).eq(a.ID, a.TENANT_ID))
   //      ^^^^  ^^^^^^^^^^^ <-> ^^^^  ^^^^^^^^^^^ Types must match
   .fetch();

在上面的示例中,Row2<T1, T2> DSL.row(Field<T1>, Field<T2>)将适用,并确保左侧和右侧行值表达式具有相同的度和类型。

请注意,根据SQL:1999标准,ROW是与<row value constructor>一起使用的可选关键字,即ROW(a, b)(a, b)相同。