(一)案例背景
有两张表:sys_group(用户组表)和sys_menu(菜单项表),他们还有个关联表:sys_group_menu(为用户组分配菜单表)。要求:需要查询得到所有的用户组(未分配菜单的用户组也需要查询出来)
(二)案例分析
按照我一开始的想法,只要将sys_group与sys_group_menu与sys_menu外键关联一下:“where sys_group.id=sys_group_menu.group_id and sys_menu.id=sys_group_menu.menu_id
”即可,但是这样做的问题就是只能查询出已经分配了菜单项的用户组,即在“sys_group_menu”建立关系的用户组,但是我们还需要将未分配的用户组也查询出来,因为我们接下来需要为这些“未分配的用户组”分配菜单项。
要想解决这个问题,就必须利用“LEFT JOIN”的特性:保证主表始终出现在最终结果表中(a LEFT JOIN b,其中a就是主表)。
我们对开始想到的sql语句进行改造,保证不管用户组有没有对应的菜单选项,用户组都会被查询出来。改造的结果就是:
1.Mybatis映射
<resultMap id="GroupMap" type="Group">
<id column="g_id" property="id"/>
<result column="g_name" property="name"/>
<!-- 1对多映射 -->
<collection property="menuList" ofType="Menu">
<id column="m_id" property="id"/>
<result column="m_name" property="name"/>
<result column="m_url" property="url"/>
<result column="m_parent_id" property="parentId"/>
<result column="m_order_num" property="orderNum"/>
</collection>
</resultMap>
2.sql语句
<select id="selectGroups" parameterType="Group" resultMap="GroupMap">
SELECT g.id g_id,g.name g_name,m.id m_id,m.name m_name,m.url m_url,m.parent_id m_parent_id,m.order_num m_order_num
FROM sys_group g
LEFT JOIN sys_group_menu gm ON g.id=gm.group_id
LEFT JOIN sys_menu m ON m.id=gm.menu_id
<where>
<if test="id != null">AND g.id=#{id}</if>
<if test="name != null and !"".equals(name.trim())">AND g.`name`=#{name}</if>
</where>
ORDER BY CONVERT(g.`name` using gbk) COLLATE gbk_chinese_ci
</select>