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

标签 java select 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 和注释通过单个 Select 查询获取复杂对象的最佳方法是什么?我应该如何使用 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。

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

关于java - MyBatis:使用注释选择复杂对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50477964/

相关文章:

javascript - 尝试在javascript中的java变量上使用.get方法

java - 具有不同类型 session 的 Spring Security

不存在的 MySQL

mysql - XA 数据源和驾驶舱

java - Jersey+Spring+MyBatis Autowiring 似乎有问题

java - 什么是 antiJARLocking 属性?

java - Java的通用类型参数命名约定(带有多个字符)?

javascript - 选择一个项目或链接

sql - 如何使用一个 select 语句的结果作为另一个 select 语句的列?

java - 如何在带有注释的mysql中使用mybatis在插入时返回id