Mybatis多表关联内连接和左连接结果不一致
小试SSM框架遇到个问题,如下:
使用的是mysql数据库,三张表如下:
user_t 用户表,
u_grade 权限表(user_t和u_grade是多对多关系,只是为了测试多对多级联而已),
u_g_mpping 关联映射表
数据如下:
项目中UserMapper.xml配置如下:
<resultMap id="BaseUser_Grade" type="org.ssm.entity.User"> <id column="uid" jdbcType="INTEGER" property="uid" /> <result column="user_name" jdbcType="VARCHAR" property="userName" /> <result column="password" jdbcType="VARCHAR" property="password" /> <result column="age" jdbcType="INTEGER" property="age" /> <collection property="grades" ofType="org.ssm.entity.Grade"> <id column="gid" jdbcType="INTEGER" property="gid" /> <result column="identity" jdbcType="VARCHAR" property="identity" /> <result column="jurisdiction" jdbcType="VARCHAR" property="jurisdiction" /> </collection> </resultMap>
在userMapper中我要查询所有用户信息及权限信息,首先使用的是内连接查询,如下:
<select id="getUserGrades" resultMap="BaseUser_Grade"> select u.*,g.* from user_t u,u_g_mapping m,u_grade g where u.uid=m.uid and m.gid=g.gid </select>
直接在数据库中使用相同的sql语句查询结果正确如下:
但mybatis查询结果错误如下:
UserID: 1 UserName: 李四 UserPW: lisi UserAge: 24 size: 1
------ GradeID: 2 GradeIden: 普通用户 GrdeJurs: 查
UserID: 3 UserName: 王武 UserPW: wangwu UserAge: 23 size: 2
------ GradeID: 1 GradeIden: 管理员 GrdeJurs: 增删改查
------ GradeID: 2 GradeIden: 普通用户 GrdeJurs: 查
UserID: 4 UserName: 赵柳 UserPW: zhaoliu UserAge: 24 size: 1
------ GradeID: 2 GradeIden: 普通用户 GrdeJurs: 查
UserID: 5 UserName: 陈琦 UserPW: chenqi UserAge: 23 size: 1
------ GradeID: 2 GradeIden: 普通用户 GrdeJurs: 查
UserID: 6 UserName: 张八 UserPW: zhangba UserAge: 23 size: 1
------ GradeID: 2 GradeIden: 普通用户 GrdeJurs: 查
UserID: 7 UserName: 曹久 UserPW: caojiu UserAge: 22 size: 1
------ GradeID: 2 GradeIden: 普通用户 GrdeJurs: 查
UserID: 8 UserName: 刘师 UserPW: liushi UserAge: 25 size: 1
------ GradeID: 2 GradeIden: 普通用户 GrdeJurs: 查
UserID: 3 UserName: 王武 UserPW: wangwu UserAge: 23 size: 2
------ GradeID: 1 GradeIden: 管理员 GrdeJurs: 增删改查
------ GradeID: 2 GradeIden: 普通用户 GrdeJurs: 查
问题:id是2的用户没有查出来,且id是3的用户重复了一遍,Debug发现查询的结果就是错的
困扰了好久一直不知道原因,最后将sql语句改成左连接:
<select id="getUserGrades" resultMap="BaseUser_Grade"> select u.*,g.* from user_t u left join u_g_mapping m on u.uid=m.uid left join u_grade g on m.gid=g.gid </select>
在数据库中使用相同的左关联sql语句查询结果正确如下:
改成左关联查询后结果正确了:
UserID: 1 UserName: 李四 UserPW: lisi UserAge: 24 size: 1
------ GradeID: 2 GradeIden: 普通用户 GrdeJurs: 查
UserID: 2 UserName: 张三 UserPW: zhangsan UserAge: 25 size: 2
------ GradeID: 1 GradeIden: 管理员 GrdeJurs: 增删改查
------ GradeID: 2 GradeIden: 普通用户 GrdeJurs: 查
UserID: 3 UserName: 王武 UserPW: wangwu UserAge: 23 size: 2
------ GradeID: 1 GradeIden: 管理员 GrdeJurs: 增删改查
------ GradeID: 2 GradeIden: 普通用户 GrdeJurs: 查
UserID: 4 UserName: 赵柳 UserPW: zhaoliu UserAge: 24 size: 1
------ GradeID: 2 GradeIden: 普通用户 GrdeJurs: 查
UserID: 5 UserName: 陈琦 UserPW: chenqi UserAge: 23 size: 1
------ GradeID: 2 GradeIden: 普通用户 GrdeJurs: 查
UserID: 6 UserName: 张八 UserPW: zhangba UserAge: 23 size: 1
------ GradeID: 2 GradeIden: 普通用户 GrdeJurs: 查
UserID: 7 UserName: 曹久 UserPW: caojiu UserAge: 22 size: 1
------ GradeID: 2 GradeIden: 普通用户 GrdeJurs: 查
UserID: 8 UserName: 刘师 UserPW: liushi UserAge: 25 size: 1
------ GradeID: 2 GradeIden: 普通用户 GrdeJurs: 查
但是问题一直没搞懂,为什么上面的表数据使用内连接查询数据会有缺失和重复?
查看了sql的结果顺序不一致,个人觉得两个表内连接时mysql的主表选择机制不同,
FORM user_t u,u_g_mapping m,u_grade g
会先内关联查询user_t和u_g_mapping,但是主表选择的是u_g_mapping,所以结果顺序和u_g_mapping表顺序一致,这里是一个疑惑点,内连接主表的选择依据是什么?根据哪个表的顺序显示结果?
但如果是因为主表选择问题也只会影响最后的结果顺序不一致,不会影响数据的缺失和重复,但我的数据结果是错的,为什么?
这两个问题一直没搞懂,初次接触学习mybatis,望大神多多指教(对于说内连接和左连接本来就不一样的,请先祥看我的表内容),不胜感激!