一. 🦁 写在前面
今天又是 BUG 气满满的一天,一个 xxxMapper.xml 因主键id 重复而出现的 bug 献上!
二. 🦁 探索过程
2.1 开端 —— 开始写 bug
就在刚刚,🦁 在写项目的时候,在实现一个多表联查的功能时,遇到一个不可描述的 BUG,我写完SQL 测试完成才去项目配置相关映射的!SQL 如下:
SELECT
a.id,
a.username,
r.id ,
r.role_name,
r.role_desc,
p.id ,
p.permission_name,
p.url
FROM
`admin` a
LEFT JOIN admin_role ON a.id = admin_role.aid
LEFT JOIN `role` r ON admin_role.rid = r.id
LEFT JOIN role_permission ON r.id = role_permission.rid
LEFT JOIN permission p ON role_permission.pid = p.id
WHERE
a.id = 133622996
测试结果如下:
一点毛病没有!
2.2 发展 —— bug 完成
当我自信满满回到项目中,配置完相关代码后(因为时多表查询,所以需要配置一个 xxxMapper.xml 文件):
<select id="findById" parameterType="long" resultMap="adminMapper">
SELECT a.id,a.username,r.id ,r.role_name,r.role_desc,p.id ,p.permission_name,p.url
FROM `admin` a
LEFT JOIN admin_role
ON a.id = admin_role.aid
LEFT JOIN `role` r
ON admin_role.rid = r.id
LEFT JOIN role_permission
ON r.id = role_permission.rid
LEFT JOIN permission p
ON role_permission.pid = p.id
WHERE a.id = #{aid}
</select>
adminMapper 配置如下:
<resultMap id="adminMapper" type="com.lion.online.pojo.Admin">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<collection property="roles" column="id" ofType="com.lion.online.pojo.Role">
<id property="id" column="id"></id>
<result property="roleName" column="role_name"></result>
<result property="roleDesc" column="role_desc"></result>
<collection property="permissions" column="id" ofType="com.lion.online.pojo.Permission">
<id property="id" column="id"/>
<result property="permissionName" column="permission_name"></result>
<result property="url" column="url"></result>
</collection>
</collection>
</resultMap>
运行控制台结果和数据库查询的结果一样:
正当一切都是朝着正轨走的时候,页面运行的结果却长这样:
🦁 已经亚麻住了… … 想起了手机中的这个表情包:
2.3 高潮 —— bug探究
出现这个结果始料不及,于是去搜了一下,发现也有很多 冤大头
出现了和我一样的错误,终于知道问题出现在哪里!
原因是在构造返回类型的时候使用了 ResultMap
标签,但是由于我的数据库表主键名字都是 id,所以在 ResultMap
中出现了多个同样的 id 字段,导致分表的 id 值和主表一样(简单来说就是Mybatis在查询时,对这几个都长得一样的id 混乱了!)。知道了问题,我们就可以着手解决了:
- 配置 collection 一对多关联的话需要改 column 别名,否则查询出来条数不对!
- 在 ResultMap 中,property 属性对应实体类中的属性,而 column 属性严格来说对应结果集中的列名,而不是数据库中的列名。
- 例如,如果对列起了别名,那么 column 属性对应的就是别名,而不是原来的列名。
改动如下:
- resultMap 修改 column 列名:
- 代码使用别名
2.4 结局 —— 效果展示
三. 🦁 写在最后
一个 BUG 赠给屏幕前的你!望君喜欢。
欢迎加入狮子的社区:『Lion-编程进阶之路』,日常收录优质好文
更多文章可持续关注上方🦁的博客,2023咱们顶峰相见!