【问题标题】:jooq cannot convert from class a to class bjooq 无法从 a 类转换为 b 类
【发布时间】:2017-03-22 03:17:42
【问题描述】:

我有问题,我认为可以轻松解决,但我做不到。

我有一个 A 类和 B 类,A 类存储在 postgres db 中:

public class A() {
    private B b;
    ...
}

public class B() {
    private String firstName;
    private String lastName;
    private String personId;
    private String userName;
}

在数据库中,b 类的对象作为字符串 userName 存储在 A 实体中。因此,要在应用程序中从 db 中获取 A 类对象,我必须读取 A 记录并创建 B 类对象。 我想用 jooq 创建查询,但 jooq 不知道如何将此字符串用户名转换为 B 类的实例。如何告诉 jooq 它应该如何将数据库 A 对象映射到 A 类对象。

A类相当于Person,B类相当于Executor。

我的查询

return jooq.select()
    .from(PERSON)
    .where(PERSON.ID.eq(id))
    .fetchOneInto(Person.class);

这是我的查询引发的异常

Caused by: org.jooq.exception.DataTypeException: Cannot convert from superadmin (class java.lang.String) to class fi.ssm.oksa.domain.person.Executor
at org.jooq.tools.Convert$ConvertAll.fail(Convert.java:1118) ~[jooq-3.8.5.jar:na]
...

我想我应该使用这个http://www.jooq.org/doc/3.8/manual/code-generation/custom-data-type-bindings/,但我无法实现它。

【问题讨论】:

  • (为了记录,通过用A和B“抽象”你的具体类名,你让问题变得更复杂了...... :)我建议你要么坚持抽象,要么真实姓名)
  • 是的,你是对的。我会更改它以便其他人可以使用它。

标签: java sql postgresql dao jooq


【解决方案1】:

有不同的方法来解决这个问题:

使用 jOOQ 的未记录(截至 3.8 版)嵌套记录映射功能

jOOQ 在其DefaultRecordMapper 中有一个未记录的功能,允许您在使用任何into(Class) 方法时嵌套结果记录。您必须手动指定嵌套记录的“路径”,就像您实际使用 ORDBMS 嵌套记录一样:

jooq.select(
       PERSON.FIRST_NAME.as("executor.first_name"),
       PERSON.LAST_NAME.as("executor.last_name"),
       PERSON.PERSON_ID.as("executor.person_id"),
       PERSON.USER_NAME.as("executor.user_name"))
    .from(PERSON)
    .where(PERSON.ID.eq(id))
    .fetchOneInto(Person.class);

当您以这种方式为列添加别名时,DefaultRecordMapper 将在 Person 类中搜索 executor 属性,并将尾随子路径放入嵌套对象中。

在此示例中,我将假设您的类的版本略有修改:

// instead of A
public class Person {
    private Executor executor;
    ...
}

// instead of B
public class Executor {
    private String firstName;
    private String lastName;
    private String personId;
    private String userName;
}

覆盖DefaultRecordMapper

使用此处记录的into(Class) 方法时,您可以实现自己的映射算法:

http://www.jooq.org/doc/latest/manual/sql-execution/fetching/pojos-with-recordmapper-provider

使用显式记录映射器:

当然,没有什么会强迫您依赖 jOOQ 的内置自动映射功能。您可以像这样编写自己的算法,例如:

jooq.select()
    .from(PERSON)
    .where(PERSON.ID.eq(id))
    .fetchOne(r -> new Person(new Executor(r.get(PERSON.FIRST_NAME), ...));

【讨论】:

  • 我会在今天晚些时候阅读,但感谢您的回答。
  • @lukas 这很酷,但是当我们获取数据时可以使用它。创建或更新呢?如何处理?
  • @hya:目前还没有实现,获取是实验性的。您必须自己映射嵌套类
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-07
  • 1970-01-01
  • 2016-08-25
  • 2012-01-26
  • 2017-03-23
相关资源
最近更新 更多