简单的记录使用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只是说明查询出来的每一行数据与实体类映射的关系