问题描述
用户(User)、角色(Role)、菜单功能(Menu)分别建立三张表,并建立用户_角色中间表(t_user_role),角色_菜单中间表(t_role_menu)。
效果:用户登录,查出对应的角色和菜单信息。
一个用户可以有多个角色,一个角色有多个功能菜单。
(多表联查——多对多)
数据库设计
实体类分析设计
User实体类:一个用户可以有多个角色,所以在User实体类中将角色的集合List<Role> roles作为User的属性,并写出get、set方法。
private List<Role> roles; public List<Role> getRoles() { return roles; } public void setRoles(List<Role> roles) { this.roles = roles; }
Role实体类:一个角色对应多个用户,一个角色又对应多个菜单功能,所以在Role实体类中将用户的集合List<User> users和菜单的集合List<Menu> menus作为Role的属性,并写出get、set方法。
private List<User> users; private List<Menu> menus; public List<Menu> getMenus() { return menus; } public void setMenus(List<Menu> menus) { this.menus = menus; } public List<User> getUsers() { return users; } public void setUsers(List<User> users) { this.users = users; }
Menu实体类:一个菜单功能可能对应多个角色,所以在Menu实体类中将角色的集合List<Role> roles作为Menu的属性,并写出get、set方法。
private List<Role> roles; public List<Role> getRoles() { return roles; } public void setRoles(List<Role> roles) { this.roles = roles; }
实现方式一:通过多条sql语句实现
(1)UserDao.java层方法:
注:传入参数为多个,此处采用参数前加@Param("属性名")进行处理。
//方式一:多句sql——传入两个参数——通过用户名、密码登录 User login(@Param("uname") String uname,@Param("pwd") String pwd);
(2)UserMpper.xml:
采用一对多的方式一进行处理,collection标签内 column为传入获取角色sql方法的属性名。
<mapper namespace="com.zx.dao.UserDao"> <!--login方式一——多句sql实现--> <select id="login" resultMap="userResult"> select * from t_user where uname=#{uname} and pwd=#{pwd} </select> <resultMap id="userResult" type="com.zx.pojo.User"> <id column="uid" property="uid"></id> <result column="uname" property="uname"></result> <result column="pwd" property="pwd"></result> <result column="age" property="age"></result> <!--集合映射——查询角色--> <collection column="uid" property="roles" select="com.zx.dao.RoleDao.getRoleByUid" ofType="com.zx.pojo.Role"></collection> </resultMap> </mapper>
(3)RoleDao.java层方法:一个用户可能对应多个角色,所有采用数组接收返回值。
//查询用户角色 List<Role> getRoleByUid(int uid);
(4)RoleMapper.xml:采用一对多的方式一进行处理,collection标签内 column为传入获取菜单功能sql方法的属性名。
<mapper namespace="com.zx.dao.RoleDao"> <select id="getRoleByUid" resultMap="roleResult"> select * from t_role where rid in (select rid from t_user_role where uid=#{uid}) </select> <resultMap id="roleResult" type="com.zx.pojo.Role"> <id column="rid" property="rid"></id> <result column="rname" property="rname"></result> <result column="rdescription" property="rdescription"></result> <!--集合映射——查询角色菜单--> <collection column="rid" property="menus" select="com.zx.dao.MenuDao.getMenuByRid" ofType="com.zx.pojo.Menu"></collection> </resultMap> </mapper>
(5)MenuDao.java层方法:一个用户对应多个菜单功能,所以采用数组接收返回值。
//查询角色对应菜单 List<Menu> getMenuByRid(int rid);
(6)MenuMapper.xml:
<mapper namespace="com.zx.dao.MenuDao"> <select id="getMenuByRid" resultType="com.zx.pojo.Menu"> select * from t_menu where mid in (select mid from t_role_menu where rid=#{rid}); </select> </mapper>
(7)在mybatis-config.xml中添加sql的映射:
<mappers> <mapper resource="com/zx/dao/UserMapper.xml"></mapper> <mapper resource="com/zx/dao/RoleMapper.xml"></mapper> <mapper resource="com/zx/dao/MenuMapper.xml"></mapper> </mappers>
(8)运行测试:
@Test public void loginTest(){ SqlSession sqlSession = MybatisUtil.getSqlSession(); UserDao userDao = sqlSession.getMapper(UserDao.class); //登录用户 User user = userDao.login("王管", "111111"); System.out.println(user); //接收角色数组 List<Role> roles = user.getRoles(); //遍历角色 for (Role role : roles) { System.out.println(role.toString()); //接收并遍历菜单功能 List<Menu> menus = role.getMenus(); for (Menu menu : menus) { System.out.println(menu.toString()); } } }
运行结果: