MyBatis:使用注释选择复杂对象



我卡住了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)

这个解决方案看起来不错,但我不想调用对数据库的多个查询(在现实生活中,我想在一个请求中从多个连接的表中获取条目列表(。

其次,我知道,如果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 和注释通过单个选择查询获取复杂对象的最佳方法是什么?我应该如何使用TypeHandler@Result

好的,我找到了基于@ConstructorArgs的工作解决方案。

因此,对于我的示例,我必须添加构造函数:

public AttachmentHierarchy(int id, String title, int originalId, String originalAuthor){
this.id = id;
this.title = title;
this.originalAttach = new Attachment(originalId, originalAuthor);
}

对于映射器:

@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}")
@ConstructorArgs(value = {
@Arg(column = "id", javaType = int.class),
@Arg(column = "title", javaType = String.class),
@Arg(column = "hierarchy_id", javaType = int.class),
@Arg(column = "hierarchy_author", javaType = String.class)
})
AttachmentHierarchy findAttachmentHierarchy(@Param(attach_id) int attachId);

请注意,您必须在 constructorArg 中指定确切的javaType。

这对我有用,但我仍在寻找更简单和更好的解决方案。

最新更新