【发布时间】:2018-05-22 23:50:31
【问题描述】:
我坚持使用 MyBatis 选择查询。所以,这里有一些细节。
我有几个 java 类(包括构造函数、getter、setter 等):
class AttachmentHierarchy{
int id;
String title;
Attachment originalAttach;
}
class Attachment{
int id;
String author;
}
另外,我有这样的 MyBatis 查询
@Select("SELECT
a.id id,
a.title title,
hierarchy.id hierarchy_id,
hierarchy.author hierarchy_author
FROM attachments a
JOIN attachments hierarchy on hierarchy.id = a.parent_id
WHERE a.id = #{attach_id}")
AttachmentHierarchy findAttachmentHierarchy(@Param(attach_id) int attachId);
是的,我知道,当前的代码看起来既奇怪又丑陋,但我试图简化示例。主要思想是我想使用 MyBatis 注释在一个查询中选择复杂对象。
首先,我们可以使用@One 注解:
@Select("SELECT ...")
@Results(value = {
@Result(property = "originalAttach",
column = "parent_id",
one = @One(select = "findOriginalAttach"))
})
AttachmentHierarchy findAttachmentHierarchy(...);
@Select("SELECT a.id id,
a.author author
FROM attachment a
WHERE a.parent_id = #{parent_id}")
Attachment findOriginalAttach(@Param("parent_id") int parentId)
这个解决方案看起来不错,但我不想对 DB 调用多个查询(在现实生活中,我想在一个请求中从多个连接表中获取条目列表)。
第二,我知道,如果Attachment 类只包含一个字段,比如author,我可以这样做:
@Results(value = {
@Result(property = "originalAttach",
column = "hierarchy_author",
typeHandler = AttachmentTypeHandler.class)
})
class AttachmentTypeHandler implements TypeHandler<Attachment>{
...
@Override
public Attachment getResult(final ResultSet rs, final String columnName) {
Attachment a = new Attachment();
a.setAuthor(rs.getString(columnName));
return a;
}
...
}
终于知道@Result注解支持这样的语法了:
@Result(property = "originalAttach",
column = "{id=hierarchy_id, author=hierarchy_author}",
typeHandler = AttachmentTypeHandler.class)
但我不知道如何使用它。它应该以某种方式与嵌套查询一起工作,在映射中创建“复合”对象并将 null 作为列名传递给 TypeHandler...
那么,长话短说,使用 MyBatis 和注释通过单个 Select 查询获取复杂对象的最佳方法是什么?我应该如何使用TypeHandler 和@Result?
【问题讨论】:
-
当然,可以从 MyBatis 查询创建一些平面对象,然后将其转换为复杂的层次结构。但它很丑,不是吗?
-
也许我应该以某种方式使用 MyBatis 关联,但据我了解,注释不支持关联...