mybatis多表联查重复字段
user表字段如下:
role表字段如下:
很明显,两张表的id和name字段名称重复了。
resultMap 和 select 语句如下:
<resultMap id="BaseResultMap" type="cn.xx.demo.model.Role" >
<id column="id" property="id" jdbcType="INTEGER" />
<result column="name" property="name" jdbcType="VARCHAR" />
<collection property="userList" ofType="cn.xx.demo.model.UserDTO">
<id column="id" property="id" jdbcType="BIGINT" />
<result column="name" property="name" jdbcType="VARCHAR" />
<result column="age" property="age" jdbcType="INTEGER" />
<result column="gender" property="gender" jdbcType="TINYINT" />
</collection>
</resultMap>
<select id="selectUserRole" resultMap="BaseResultMap" parameterType="Map">
select r.id,
r.name,
u.id,
u.name,
u.age,
u.gender
from role r
left outer join user_role ur on r.id=ur.rid
left outer join user u on ur.uid = u.id
<include refid="Pagination" />
</select>
查询结果如下,user表 的 id 和 name 被 role表重名字段覆盖了
在写mybatis的关联查询时,resultMap中如果两个对象有相同的属性。查询出来的结果内层的对象的属性会被外层对象属性覆盖,导致内层list数据出错。
参考:https://blog.csdn.net/tc979907461/article/details/115489439
解决方法:
在 select 语句中给 user的重名字段写别名,并且在 resultMap 中修改它对应的 column 值。
修改之后的 xml 代码如下:
<resultMap id="BaseResultMap" type="cn.xx.demo.model.Role" >
<id column="id" property="id" jdbcType="INTEGER" />
<result column="name" property="name" jdbcType="VARCHAR" />
<collection property="userList" ofType="cn.xx.demo.model.UserDTO">
<id column="user_id" property="id" jdbcType="BIGINT" />
<result column="uname" property="name" jdbcType="VARCHAR" />
<result column="age" property="age" jdbcType="INTEGER" />
<result column="gender" property="gender" jdbcType="TINYINT" />
</collection>
</resultMap>
<select id="selectUserRole" resultMap="BaseResultMap" parameterType="Map">
select r.id,
r.name,
u.id as user_id,
u.name as uname,
u.age,
u.gender
from role r
left outer join user_role ur on r.id=ur.rid
left outer join user u on ur.uid = u.id
<include refid="Pagination" />
</select>
查询结果如下,可以正常显示:
注意:
在 select 语句中,不能随便写别名,因为这个别名和 resultMap 中的 column 值是对应的,如果 select 语句中写了别名,column 还是表字段的原名,查出来的结果就会是 null 。
比如,这种情况:
在 select 语句中给role表的 id 和 name 设置了别名,没改resultMap
<resultMap id="BaseResultMap" type="cn.xx.demo.model.Role" >
<id column="id" property="id" jdbcType="INTEGER" />
<result column="name" property="name" jdbcType="VARCHAR" />
<collection property="userList" ofType="cn.xx.demo.model.UserDTO">
<id column="id" property="id" jdbcType="BIGINT" />
<result column="name" property="name" jdbcType="VARCHAR" />
<result column="age" property="age" jdbcType="INTEGER" />
<result column="gender" property="gender" jdbcType="TINYINT" />
</collection>
</resultMap>
<select id="selectUserRole" resultMap="BaseResultMap" parameterType="Map">
select r.id as rid,
r.name as rname,
u.id,
u.name,
u.age,
u.gender
from role r
left outer join user_role ur on r.id=ur.rid
left outer join user u on ur.uid = u.id
<include refid="Pagination" />
</select>
在查询结果中,role 表的 id 和 name 就会被 user 表的 id 和 name 覆盖
而在这种情况下,
user 表的 id 和 name 字段正确地设置了别名,
role 表的 id 和 name 字段只在 select 语句中设置了别名
<resultMap id="BaseResultMap" type="cn.xx.demo.model.Role" >
<id column="id" property="id" jdbcType="INTEGER" />
<result column="name" property="name" jdbcType="VARCHAR" />
<collection property="userList" ofType="cn.xx.demo.model.UserDTO">
<id column="uid" property="id" jdbcType="BIGINT" />
<result column="uname" property="name" jdbcType="VARCHAR" />
<result column="age" property="age" jdbcType="INTEGER" />
<result column="gender" property="gender" jdbcType="TINYINT" />
</collection>
</resultMap>
<select id="selectUserRole" resultMap="BaseResultMap" parameterType="Map">
select r.id as rid,
r.name as rname,
u.id as uid,
u.name as uname,
u.age,
u.gender
from role r
left outer join user_role ur on r.id=ur.rid
left outer join user u on ur.uid = u.id
<include refid="Pagination" />
</select>
查询结果中,role 表的 id 和 name 就为null。
因为此时 role 表的 id 和 name 已经不会跟 user 表的 id 和 name 字段重名了,所以 role 表的 id 和 name 字段不会再被 user 表的 id 和 name 字段所覆盖。在找不到该字段的情况下,就会返回空。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)