• mybatis动态sql一对多查询


    数据库设计中,一对多关系是非常多的,例如消息通知和附件,一个消息通知中往往会包含多个附件,这种情况下使用mybatis动态sql可以很方便的查询出来。

    1、数据库设计

    消息表:sys_message

    CREATE TABLE `sys_message` (
      `id` varchar(40) COLLATE utf8mb4_unicode_ci NOT NULL,
      `title` varchar(200) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '标题',
      `content` mediumtext COLLATE utf8mb4_unicode_ci COMMENT '内容',
      `message_fk` varchar(40) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '附件fk'
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='消息管理';
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    附件表:sys_attachment

    CREATE TABLE `sys_attachment` (
      `id` varchar(40) NOT NULL COMMENT '主键',
      `file_name` varchar(50) NOT NULL COMMENT '原文件名',
      `storing_name` varchar(100) NOT NULL COMMENT '存储文件名',
      `size` bigint(20) NOT NULL COMMENT '大小',
      `fk` varchar(40) NOT NULL COMMENT '业务主键',
      `suffix_type` tinyint(4) DEFAULT NULL COMMENT '类型(后缀)',
      `file_type` tinyint(4) DEFAULT '0' COMMENT '文件类型:0其他 1图片 2视频',
      `url` varchar(200) NOT NULL COMMENT '访问地址',
      `absolute_path` varchar(200) NOT NULL COMMENT '绝对路径',
      PRIMARY KEY (`id`)
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    一条消息对应多个附件,附件表中的 fk引用消息表的message_fk


    2、实现

    返回类型是Message对象,其中有一个 List fileList,存储附件信息。

    public class SysMessage extends LaboratoryBaseModel<SysMessage> {
        private static final long serialVersionUID=1L;       
        
        @TableField("id")
        private String id;
        
        @TableField("title")
        private String title;
            
        @TableField("content")
        private String content;
            
            
        @TableField("message_fk")
        private String messageFk;
            
    
        @TableField(exist = false)
        private List<SysAttachment> fileList;
                    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    这种情况下,在动态sql的标签中,返回值只能使用resultMap属性接收:

     <select id="selectMessagePage" resultMap="sysMessageMap">
            SELECT
                *
            FROM
                sys_message a
    select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    resultMap是一个外部结果映射关系的引用,描述了结果数据的映射关系,在resultMap中有一个 collection标签,分别是:

    • column:message表的message_fk,即一对多的一中被引用的字段名
    • property:SysMessage中fileList属性,属性名是fileList
    • javaType:SysMessage中fileList属性的对应的java类型Arraylist
    • ofType:javaType的数据类型SysAttachment
    • select:需要引用的select标签的名字,标签中。

      	<resultMap id="sysMessageMap" type="cn.xxx.model.SysMessage">
              <result property="id" column="id"/>
              <result property="title" column="title"/>
              <result property="content" column="content"/>
              <result property="messageFk" column="message_fk"/>
              <collection column="message_fk"
                          property="fileList"
                          javaType="Arraylist"
                          ofType="cn.yibiao163.laboratory.model.SysAttachment"
                          select="selectFileByFk">
              collection>
          resultMap>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      <select id="selectFileByFk" resultMap="cn.xxx.repository.SysAttachmentMapper.sysAttachmentMap">
              select * from sys_attachment where is_deleted = 0 and fk = #{message_fk}
      </select>
      
      • 1
      • 2
      • 3