DSL选择中的JOOQ和PostgreSQL类型

时间:2016-09-20 21:58:51

标签: java sql postgresql jooq

我遇到了jOOQ 3.8的问题。 所以,我在PostgreSQL 9.5中有一个表,比如。

CREATE TABLE my_table(
  id bigserial,
  types my_type[]
)

其中my_type是类似

的类型
CREATE TYPE my_type AS(
  id smallint,
  something text
)

现在,在jOOQ 3.8中,我想做类似

的事情
dsl.selectDistinct(MY_TABLE.ID)
   .from(MY_TABLE)
   .join(TYPE_TABLE).on(TYPE_TABLE.ID.equal(DSL.any(
       MY_TABLE.TYPES.ID
   ))
   .fetch(MY_TABLE.ID);

显然,我MY_TABLE.TYPES.ID的步骤是错误的。我在考虑使用DSL.select(MY_TYPE.ID)...,但显然my_type是一个类型,而不是表。

如何使用jOOQ访问类型属性?

1 个答案:

答案 0 :(得分:1)

如何使用PostgreSQL

解决这个问题

我认为没有一种简单的方法可以将my_type[]转换为PostgreSQL中的integer[]类型,为每个值提取my_type.id,以便它可以与{any()一起使用1}} operator。

但您可以使用UNNEST()来解决此限制,例如:

SELECT DISTINCT my_table.id
FROM my_table
CROSS JOIN LATERAL unnest(my_table.types)

以上将产生类似

的内容
id   types                      id   something
----------------------------------------------
1    {"(1,a)","(2,b)"}          1    a
1    {"(1,a)","(2,b)"}          2    b
2    {"(1,a)","(2,b)","(3,c)"}  1    a
2    {"(1,a)","(2,b)"}          2    b
2    {"(1,a)","(2,b)"}          3    c

现在,您可以再次加入TYPE_TABLE,例如:

SELECT DISTINCT my_table.id
FROM my_table
CROSS JOIN LATERAL unnest(my_table.types) types
INNER JOIN type_table ON type_table.id = types.id

或者,可能表现更好:

SELECT my_table.id
FROM my_table
WHERE EXISTS (
  SELECT 1
  FROM type_table
  JOIN unnest(my_table.types) AS types ON type_table.id = types.id
)

如何使用jOOQ解决此问题

jOOQ目前(从3.8版本开始)的不当支持相当简单,即你没有得到结果表中的所有类型信息,这就是为什么你需要做一些简单的SQL混合。但它肯定是可行的!方法如下:

create().select(MY_TABLE.ID)
        .from(MY_TABLE)
        .whereExists(
            selectOne()
            .from(unnest(MY_TABLE.TYPES).as("types", 
                 MY_TYPE.ID.getName(), 
                 MY_TYPE.SOMETHING.getName()
             ))
            .join(TYPE_TABLE)
            .on(TYPE_TABLE.ID.eq(field(name("types", MY_TYPE.ID.getName()), 
                                     MY_TYPE.ID.getDataType())))
        )
        .fetch(MY_TABLE.ID);