【问题标题】:Nested objects jdbi 3 with bean mapper is null带有 bean 映射器的嵌套对象 jdbi 3 为空
【发布时间】:2022-10-03 06:44:54
【问题描述】:

我有一个子类,其成员变量嵌套如下定义。但是,当我跑步时

val child = childRepo[1]

child.parentnull。如何自动获取嵌套成员变量?

模型.kt

import org.jdbi.v3.core.mapper.Nested
data class Child(
        var id: Int = -1,

        @Nested
        var parent: Parent? = null,

        var created: Instant? = null
)

data class Parent(
        var id: Int = -1,
)

ChildRepo.kt

import org.jdbi.v3.sqlobject.config.RegisterBeanMapper
import org.jdbi.v3.sqlobject.statement.SqlQuery
@SqlQuery(\"\"\"
        SELECT 
            c.id as c_id, c.created as c_created,
            p.id as p_id 
        FROM child as c
            INNER JOIN parent p on p.id = c.parent_id
        WHERE c.id = :id
        \"\"\")
@RegisterBeanMapper(value = Child::class, prefix = \"c\")
@RegisterBeanMapper(value = Parent::class, prefix = \"p\")
operator fun get(id: Int): Child?

    标签: jdbi jdbi3


    【解决方案1】:

    如果您还为这两个类注册了JoinRowMapper(例如使用@RegisterJoinRowMapper),您将获得最接近您的存储库sn-p 的东西。您的get 方法的返回类型将是JoinRow,您可以从中检索两个值。

    这里有更多信息和一些例子:https://jdbi.org/#_joins

    如果您愿意在类定义中设置前缀,则可能更简单的方法是将 @Nested("p") 放在 parentChild 字段上,并在存储库方法上仅添加以下注释:

    @SqlQuery("""
        SELECT 
            c.id as id, c.created as created,
            p.id as p_id 
        FROM child as c
            INNER JOIN parent p on p.id = c.parent_id
        WHERE c.id = :id
        """)
    @RegisterBeanMapper(value = Child::class)
    

    【讨论】:

      【解决方案2】:

      已注册映射器中的前缀适用于顶级 bean。因此,您的 Child bean 使用“c”前缀正确映射。但是,“@Nested”注释不提供任何附加信息,哪些列用于嵌套 bean。因此,JDBI 尝试将带有“c”前缀的列映射到“Parent”bean,这不起作用。将 @Nested 注释替换为 @Nested("p") 以向 JDBI 发出该嵌套 bean 使用不同前缀的信号。然而,由于这是一个嵌套 Bean,JDBI 使用一个嵌套前缀(即 c_p)。因此,将父级的列选择为p_id as c_p_id

      此代码适用于 JDBI 3.33.0(其中对 bean 映射逻辑进行了一些更改):

          @Test
          void testParentChild() {
              handle.execute("create table child (id integer not null, parent_id integer, created timestamp)");
              handle.execute("create table parent(id integer, created timestamp)");
              handle.execute("insert into parent (id, created) values (1, now())");
              handle.execute("insert into parent (id, created) values (2, now())");
              handle.execute("insert into parent (id, created) values (3, now())");
      
              handle.execute("insert into child(id, parent_id, created) values(1, 1, now())");
              handle.execute("insert into child(id, parent_id, created) values(2, 1, now())");
              handle.execute("insert into child(id, parent_id, created) values(3, 1, now())");
              handle.execute("insert into child(id, parent_id, created) values(4, 2, now())");
              handle.execute("insert into child(id, parent_id, created) values(5, 2, now())");
              handle.execute("insert into child(id, parent_id, created) values(6, 2, now())");
              handle.execute("insert into child(id, parent_id, created) values(7, 3, now())");
              handle.execute("insert into child(id, parent_id, created) values(8, 3, now())");
              handle.execute("insert into child(id, parent_id, created) values(9, 3, now())");
      
              ParentChildDao dao = handle.attach(ParentChildDao.class);
      
              Child c = dao.getChild(4);
      
              assertThat(c).isNotNull();
              assertThat(c.getParent()).isNotNull();
              assertThat(c.getParent().getId()).isEqualTo(2);
      
          }
      
          public static class Child {
              private int id;
              private Parent parent;
              private Instant created;
      
              public int getId() {
                  return id;
              }
      
              public void setId(int id) {
                  this.id = id;
              }
      
              public Parent getParent() {
                  return parent;
              }
      
              @Nested("p")
              public void setParent(Parent parent) {
                  this.parent = parent;
              }
      
              public Instant getCreated() {
                  return created;
              }
      
              public void setCreated(Instant created) {
                  this.created = created;
              }
          }
      
          public static class Parent {
              private int id;
              private Instant created;
      
              public int getId() {
                  return id;
              }
      
              public void setId(int id) {
                  this.id = id;
              }
      
              public Instant getCreated() {
                  return created;
              }
      
              public void setCreated(Instant created) {
                  this.created = created;
              }
          }
      
          public interface ParentChildDao {
              @SqlQuery("SELECT  c.id as c_id, c.created as c_created,p.id as c_p_id  FROM child as c INNER JOIN parent p on p.id = c.parent_id WHERE c.id = :id")
              @RegisterBeanMapper(value=Child.class, prefix="c")
              @RegisterBeanMapper(value=Parent.class)
              Child getChild(int id);
          }
      

      【讨论】:

        猜你喜欢
        • 2021-07-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-27
        • 2013-08-01
        • 1970-01-01
        相关资源
        最近更新 更多