Mybatis 关联查询

作者:範宗雲 来源:原创 发布时间:2015-05-03 归档:mybatis

环境 : JDK 7 Mybatis 3.2.7 Maven 3 Junit 4.11 Spring 4.1.5 Eclipse Luna
数据库表结构 :
实体类定义 :
            <mapper namespace="org.lychie.mapper.MusicMapper">

              <resultMap type="Music" id="musicResult">
                <id property="id" column="id" />
                <result property="name" column="name" />
                <result property="singer" column="singer" />
                <result property="createTime" column="create_time" />
                <association property="lyric" javaType="Lyric">
                  <id property="id" column="lyric_id" />
                  <result property="name" column="lyric_name" />
                  <result property="content" column="lyric_content" />
                  <result property="createTime" column="lyric_create_time" />
                </association>
                <collection property="tags" ofType="Tag">
                  <id property="id" column="tag_id" />
                  <result property="name" column="tag_name" />
                  <result property="createTime" column="tag_create_time" />
                </collection>
              </resultMap>

              <select id="queryById" parameterType="int" resultMap="musicResult">
                select
                  m.id, m.name, m.singer, m.create_time, 
                  l.id as lyric_id, l.name as lyric_name, l.content as lyric_content, l.create_time as lyric_create_time,
                  t.id as tag_id, t.name as tag_name, t.create_time as tag_create_time
                from music m
                  left join lyric l on m.lyric_id = l.id
                  left join music_tag mt on mt.music_id = m.id
                  left join tag t on mt.tag_id = t.id
                where m.id = #{id}
              </select>

            </mapper>
          
此 SQL 为根据主键查询一条 Music 记录, 其中, Music 关联了一个 Lyric 实体和一个 Tag 集合。表 music 和 lyric 是一对一的关系, music 和 tag 是多对多的关系, music_tag 是中间表。
关联 :
            <association property="lyric" javaType="Lyric">
              <id property="id" column="lyric_id" />
              <result property="name" column="lyric_name" />
              <result property="content" column="lyric_content" />
              <result property="createTime" column="lyric_create_time" />
            </association>
          
<association> 映射一个复杂的类型, 用来处理 "有一个" 的类型关系。如一首音乐有一个歌词。property 指明关联属性的名称, javaType 指明为属性装配的数据类型 ( 类的完全限定名或别名 )。试验得出, 如果不手工配置查询结果列与实体类属性之间的映射关系, 即使类的属性名称与查询结果列的名称一致, 也无法自动映射查询结果的列到类的属性, 即查询结果列的值无法赋到类的属性上。
你也可以这样来配置关联 :
            <association property="lyric" resultMap="lyricResult" />

            <resultMap type="Lyric" id="lyricResult">
              <id property="id" column="lyric_id" />
              <result property="name" column="lyric_name" />
              <result property="content" column="lyric_content" />
              <result property="createTime" column="lyric_create_time" />
            </resultMap>
          
这里将 Lyric 结果映射单独抽了出来, 这样子可以重用 Lyric 结果映射。如果你不需要重用它, 采用上一种配置方式即可, 当然,你也可以采用这种配置。
集合 :
            <collection property="tags" ofType="Tag">
              <id property="id" column="tag_id" />
              <result property="name" column="tag_name" />
              <result property="createTime" column="tag_create_time" />
            </collection>
          
与关联非常相似, 只是将 <association> 换成了 <collection>。用来处理 "有多个" 的类型关系。如一首音乐有多个标签。