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

Java MyBatis:使用注释选择复杂对象,java,select,mybatis,Java,Select,Mybatis,我被MyBatis select查询搞砸了。下面是一些细节 我有几个java类(包括构造函数、getter、setter等): 还有,我有这样的MyBatis疑问 @Select("SELECT a.id id, a.title title, hierarchy.id hierarchy_id, hierarchy.author hierarchy_author FROM attachments a JOIN attac

我被MyBatis select查询搞砸了。下面是一些细节

我有几个java类(包括构造函数、getter、setter等):

还有,我有这样的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;
    }
  ...
}
但我不知道怎么用。它应该以某种方式处理嵌套查询,在映射中创建“composites”对象,并将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);
 }
对于Mapper:

@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中指定确切的javaTypes


这对我来说是可行的,但我仍在寻找更简单、更好的解决方案。

当然,可以从MyBatis查询创建一些平面对象,然后将其转换为复杂的层次结构。但它很难看,不是吗?也许我应该以某种方式使用MyBatis关联,但据我所知,关联不受注释的支持。。。
 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);