1、案例分析
多对多映射其实就是一个双向的一对多映射,因为两边都是一对多。多对多主要是关联关系要找好,然后根据关联去查询。
由于前面的案例员工和部门一方是一对一,一方是一对多,所以不能形成多对多的条件,我重新换了一个案例——用户和角色。
- 一个用户可以拥有多个角色,User—>Role(一对多)。
- 一个角色可以赋予多个用户,Role—>User(一对多)。
这样就是形成了一个双向的一对多,从而变成了多对多,其实前面掌握了一对多就已经完全足够了,我为了再巩固一下所以继续写了个多对多的例子。数据库表如下:
对应mysql的sql脚本如下:
-- ---------------------------- -- Table structure for t_role -- ---------------------------- DROP TABLE IF EXISTS `t_role`; CREATE TABLE `t_role` ( `roleId` int(11) NOT NULL AUTO_INCREMENT, `roleName` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `remake` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, PRIMARY KEY (`roleId`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of t_role -- ---------------------------- INSERT INTO `t_role` VALUES (1, '管理员', '权限最大'); INSERT INTO `t_role` VALUES (2, '总经理', '公司老大'); INSERT INTO `t_role` VALUES (3, '项目经理', '项目好好搞,你们需求最多,工资最少!好好干哦'); INSERT INTO `t_role` VALUES (4, '销售经理', '销量就靠你们了,销量高,老板才能开上法拉利!'); INSERT INTO `t_role` VALUES (5, '仓库管理员', '仓库就归你管了,货不能出错!'); INSERT INTO `t_role` VALUES (6, '普通员工', '打工人,打工魂,打工都是人上人,加油!'); -- ---------------------------- -- Table structure for t_user -- ---------------------------- DROP TABLE IF EXISTS `t_user`; CREATE TABLE `t_user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `age` int(11) NULL DEFAULT NULL, `birthday` date NULL DEFAULT NULL, `sex` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `address` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of t_user -- ---------------------------- INSERT INTO `t_user` VALUES (1, '唐浩荣', 18, '2020-11-10', '1', '上海'); INSERT INTO `t_user` VALUES (2, '蔡徐坤', 18, '2018-01-18', '0', '北京'); INSERT INTO `t_user` VALUES (3, '黄飞鸿', 42, '2020-11-12', '1', '大清'); INSERT INTO `t_user` VALUES (4, '十三姨', 18, '2020-11-10', '0', '大清'); INSERT INTO `t_user` VALUES (5, '梁宽', 42, '2020-11-10', '0', '大清'); INSERT INTO `t_user` VALUES (6, '马保国', 33, '2020-11-14', '1', '深圳'); INSERT INTO `t_user` VALUES (7, '纳兰元述', 42, '2020-11-12', '1', '大清'); -- ---------------------------- -- Table structure for t_user_role -- ---------------------------- DROP TABLE IF EXISTS `t_user_role`; CREATE TABLE `t_user_role` ( `ur_id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) NULL DEFAULT NULL, `role_id` int(11) NULL DEFAULT NULL, PRIMARY KEY (`ur_id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of t_user_role -- ---------------------------- INSERT INTO `t_user_role` VALUES (1, 1, 2); INSERT INTO `t_user_role` VALUES (2, 2, 4); INSERT INTO `t_user_role` VALUES (3, 5, 1); INSERT INTO `t_user_role` VALUES (4, 3, 3); INSERT INTO `t_user_role` VALUES (5, 4, 6); INSERT INTO `t_user_role` VALUES (6, 6, 6); INSERT INTO `t_user_role` VALUES (7, 7, 4); INSERT INTO `t_user_role` VALUES (8, 2, 5);
创建步骤分析:
- User表和Role表具有多对多关系,需要使用中间表(t_user_role)关联,中间表中包含各自的主键,在中间表中是外键;
- 建立两个实体类:用户实体类中包含对角色的集合引用,角色实体类中包含对用户的集合引用;
- 建立两个Mapper接口:用户的Mapper接口和角色的Mapper接口;
- 建立两个配置文件:用户的配置文件和角色的配置文件;
- 实现功能: 查询用户时,同时得到用户所包含的角色信息; 查询角色时,同时得到角色对应的用户信息;
- 编写测试代码并查看运行结果,能否查询出相应的数据;
2、用户到角色的多对多查询
①、查询所有数据的sql语句
SELECT * FROM t_user u,t_user_role ur,t_role r WHERE u.id = ur.user_id AND ur.role_id = r.roleId ORDER BY id
运行结果如下:
②、编写User实体类和UserMapper接口
User实体类:
/** * 用户实体类 */ public class User { private int userId; private String userName; private int userAge; private Date userBirthday; private int userSex; private String userAddress; //用户拥有的角色 private List<Role> roles; //getter、setter、toString方法省略...... }
UserMapper接口:
/** * UserMapperJ接口 */ public interface UserMapper { //查询所有用户信息 List<User> selectAllUser(); //根据用户id查询用户信息 User selectUserByUserId(@Param("id") Integer userId); }
③、配置映射文件UserMapper.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.thr.mapper.UserMapper"> <resultMap id="userMap" type="com.thr.pojo.User"> <id property="userId" column="id"/> <result property="userName" column="username"/> <result property="userAge" column="age"/> <result property="userBirthday" column="birthday"/> <result property="userSex" column="sex"/> <result property="userAddress" column="address"/> <!--一对多映射--> <collection property="roles" ofType="role"> <id property="roleId" column="roleId"/> <result property="roleName" column="roleName"/> <result property="remake" column="remake"/> </collection> </resultMap> <!-- 查询所有用户--> <select id="selectAllUser" resultMap="userMap"> SELECT * FROM t_user u, t_user_role ur, t_role r WHERE u.id = ur.user_id AND ur.role_id = r.roleId ORDER BY id </select> <!--根据用户id查询用户信息--> <select id="selectUserByUserId" resultMap="userMap"> SELECT * FROM t_user u, t_user_role ur, t_role r WHERE u.id = ur.user_id AND ur.role_id = r.roleId AND u.id = #{id} </select> </mapper>
④、编写测试类
//查询所有用户信息 @Test public void testSelectAllUser(){ List<User> userList = mapper.selectAllUser(); for (User user : userList) { System.out.println(user); } } //根据用户id查询用户信息 @Test public void testSelectUserByUserId(){ User user = mapper.selectUserByUserId(2); System.out.println(user); }
⑤、运行结果
查询所有用户信息:
根据用户id查询用户信息:
3、角色到用户的多对多查询
①、查询所有数据的sql语句
SELECT * FROM t_user u,t_user_role ur,t_role r WHERE u.id = ur.user_id AND ur.role_id = r.roleId ORDER BY roleID
运行结果如下:
②、编写Role实体类和RoleMapper接口
Role实体类:
/** * 角色实体类 */ public class Role { private int roleId; private String roleName; private String remake;//备注 //该角色包含的用户 private List<User> users; //getter、setter、toString方法省略...... }
RoleMapper接口:
/** * 角色Mapper接口 */ public interface RoleMapper { //查询所有角色信息 List<Role> selectAllRole(); //根据角色id查询角色信息 Role selectRoleByRoleId(@Param("id") Integer roleId); }
③、配置映射文件RoleMapper.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.thr.mapper.RoleMapper"> <resultMap id="roleMap" type="com.thr.pojo.Role"> <id property="roleId" column="roleId"/> <result property="roleName" column="roleName"/> <result property="remake" column="remake"/> <collection property="users" ofType="user"> <id property="userId" column="id"/> <result property="userName" column="username"/> <result property="userAge" column="age"/> <result property="userBirthday" column="birthday"/> <result property="userSex" column="sex"/> <result property="userAddress" column="address"/> </collection> </resultMap> <!-- 查询所有角色--> <select id="selectAllRole" resultMap="roleMap"> SELECT * FROM t_user u, t_user_role ur, t_role r WHERE u.id = ur.user_id AND ur.role_id = r.roleId ORDER BY roleId </select> <!-- 根据角色id查询角色信息--> <select id="selectRoleByRoleId" resultMap="roleMap"> SELECT * FROM t_user u, t_user_role ur, t_role r WHERE u.id = ur.user_id AND ur.role_id = r.roleId AND r.roleId = #{id} </select> </mapper>
④、编写测试类
//查询所有角色信息 @Test public void testSelectAllRole(){ List<Role> roleList = mapper.selectAllRole(); for (Role role : roleList) { System.out.println(role); } } //根据角色id查询角色信息 @Test public void testSelectRoleByRoleId(){ Role role = mapper.selectRoleByRoleId(1); System.out.println(role); }
⑤、运行结果
查询所有角色信息:
根据用户id查询角色信息:
这一节的代码我给它放到了云盘上,有需要参考可以下载:链接:https://pan.baidu.com/s/1mCI74OpdqMlnIxcuiNp7TA ;提取码:s03n