jOOQ是否支持解析嵌套行?

时间:2018-04-03 11:54:22

标签: sql postgresql jooq

我正在评估我们是否可以从普通JDBC迁移到我们项目的jOOQ。大多数看起来很有希望,但我想知道目前有一个特定的流程:嵌套行。让我解释一下。

假设您有以下两个表:

class(id, name)
student(id, name, class_id)

(我们假设学生只能参加一个班级。)

让我们为这些表创建响应类型。我将在下面的查询中使用这些。

create type type_student as(id integer, name text);
create type type_class as(id integer, name text, students type_student[]);

现在让我们通过使用嵌套行来获取其学生的所有课程:

select row(class.id, class.name, array
       (
         select row(student.id, student.name)::type_student
         from   student
         where  student.class_id = class.id
       ))::type_class
from   class

一个有用的变体是只在数组中使用嵌套行:

select class.id, class.name, array
       (
         select row(student.id, student.name)::type_student
         from   student
         where  student.class_id = class.id
       ) as students
from   class

我想知道jOOQ是否有一种优雅的方法来解析包含嵌套行的结果?

2 个答案:

答案 0 :(得分:1)

你对“解析”一词的使用可能意味着几件事情,如果有人发现这个问题寻找“jOOQ”/“parse”/“row”,我会全部回答。

shell: | ... shell_var={{ role_var if role_var is defined else hostvars[item].host_var | default('defalut_value') }} ... with_items: "{{ groups[hosts_group_iterator] }}" 是否支持行值表达式?

尚未(截至jOOQ 3.10和3.11)。 jOOQ附带一个SQL解析器,可以解析(几乎)可以使用jOOQ API表示的任何内容。这有各种好处,包括:

不幸的是,它无法在预测中解析行值表达式,即在org.jooq.Parser子句中。

jOOQ API是否支持(“解析”)行值表达式?

是的,您可以使用各种DSL.row()构造函数来使用它们,主要用于谓词,也可以使用DSL.rowField()将它们包装在SELECT中进行投影。从jOOQ 3.11开始,这仍然有点实验性,因为PostgreSQL本身存在许多边缘情况,与允许的内容和不允许的内容相关。但原则上,像你这样的查询应该是可能的

jOOQ是否支持解析PostgreSQL Field

的序列化版本

PostgreSQL支持这些匿名record类型,以及命名的“复合”类型。及其阵列。并且嵌套数组和复合类型。如果jOOQ可以使用类型信息,即如果您正在使用代码生成器,则jOOQ可以对这些类型进行序列化和反序列化。例如,如果您的查询存储为视图

record

然后,代码生成器将生成适当的类型,包括:

  • create view test as select row(class.id, class.name, array ( select row(student.id, student.name)::type_student from student where student.class_id = class.id ))::type_class from class
  • TypeStudentRecord

可以按预期序列化。原则上,没有代码生成器也可以这样做,但是你必须自己手动创建上面的类型,所以为什么不使用代码生成器。

答案 1 :(得分:0)

是的,https://www.jooq.org/doc/latest/manual/sql-building/table-expressions/nested-selects/

Field<Object> records =
create.select(student.id, student.name)
      .from(student)
      .where(student.class_id.eq(class.id)
      .asField("students");

create.select(class.id, class.name, array, records)
      .from(class)
      .fetch();

以上示例可能无法直接使用,因为我没有尝试过,但只是想提出一个大致的想法。

注意:对象记录不是单独执行的。在第二个语句中调用fetch时,JOOQ应在内部创建一个SQL语句。