已注册映射器中的前缀适用于顶级 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);
}