MyBatis几种关联查询配置

前言

简单的记录使用MyBatis关联查询的几种写法

正文

<select id="getLogonByCondition" parameterType="withoutspring.TestDTO" resultMap="logons">
        select t.id as logon_id,
               t.logonname,
               t.password,
               t.userid,
               t1.id as user_id,
               t1.displayname,
               t1.logon
        from logon t,user1 t1
        where t.userid = t1.id
        <if test="userid != null">
            and t.userid = #{userid}
        </if>
        <if test="displayname != null and displayname != '' ">
            and t1.displayname = #{displayname}
        </if>   
    </select>

这是一个mybatis查询关联的配置,从上面看到,我通过sql的关联查询将两个表需要的字段都查询出来了。下面需要做的就是将查询的字段匹配到返回的对象中,这里返回的对象是一个Logon的javaBean

    private Integer id;
    private String logonname;
    private String password;
    private List<User> user;

id、logonname、password是logon表中,这种匹配简单,关键是List<User>如何与查询出来的字段关联?
几种方法
从上面看到List<User>是一个集合,所以resultMap配置的时候使用<collection> 这个标签,如果只是一个实体类对象,那么使用<association>标签,两种使用方法差不多

 <select id="getLogonByCondition" parameterType="withoutspring.TestDTO" resultMap="logons">
        select t.id as logon_id,
               t.logonname,
               t.password,
               t.userid,
               t1.id as user_id,
               t1.displayname,
               t1.logon
        from logon t,user1 t1
        where t.userid = t1.id
        <if test="userid != null">
            and t.userid = #{userid}
        </if>
        <if test="displayname != null and displayname != '' ">
            and t1.displayname = #{displayname}
        </if>   
    </select>

对应的resultMap配置

<resultMap id="logons" type="withoutspring.Logon">
        <id property="id" column="logon_id" />
        <result property="logonname" column="logonname"/>
        <result property="password" column="password"/>
        <!-- 关联查询,单个实例association 集合collection-->
        <!-- 可以select(n+1),也可以resultmap(无,sql关联查询,字段匹配),或者在collection中配置对应字段 -->
        <!-- column指的是sql后面的别名,这样才能正确匹配 -->
        <collection property="user" javaType="list" ofType="withoutspring.User">
            <id property="id" column="user_id" />
            <result property="display" column="displayname"/>
            <result property="logon" column="logon"/>
        </collection>
    </resultMap>

具体看一下<collection>里面的配置,为了能将select查询出来的字段匹配到返回对象中,我们必须得将查询出来的字段一一对应返回对象的属性,

select t.id as logon_id,  //column为logon_id
               t.logonname, //column为logonname
               t.password, //column为password
               t.userid,   //column为userid
               t1.id as user_id, //column为 user_id
               t1.displayname,  //displayname
               t1.logon   //displayname

从上面代码注释可以看出,如果有别名,那么别名就是column,没有别名那么column每张表的字段名;这里如果t.id 和t1.id不使用别名,那么他们column都是id,这样产生歧义了。

<collection  property="user" javaType="list" ofType="withoutspring.User">
            <id property="id" column="user_id" />
            <result property="display" column="displayname"/>
            <result property="logon" column="logon"/>
        </collection>

我从关联表查出了t1.id as user_id,t1.displayname, t1.logon ,这三个字段,我要关联到Logon中: <id property=”id” column=”user_id” />将查询出来的字段user_id的值赋值到User对象的id属性中,
<result property=”display” column=”displayname”/>将t1.displayname查询出来的值,赋值到这个User对象的display属性中
<result property=”logon” column=”logon”/>将查询出来的t1.logon的值赋值到User对象的logon属性中

可以看到resultMap的好处,将查询出来的column(别名或表字段名)值与返回对象的property一一匹配。在hibernate中通过hibernateTemplate来做一些sql查询,不得不用setResultTransformer来绑定实体类,而且需要用别名(column)来保证与实体类的属性一致

当然在关联查询中还可以collection 中使用select(会有n+1问题),resultMap(减少代码重复)

如果查询出来2条数据,resultMap的返回对象是Logon,如何才能返回一个集合? 只需要在接口中返回值设置为List<Logon>就可以了,配置文件resultMap只是说明查询出来的每一行数据与实体类映射的关系

你可能感兴趣的:(mybatis)