MyBatis 多对多查询的实现
这次我们来实现多对多查询,我们考虑用户和角色这两个关系,角色有很多种比如说院长,校长什么的。一个用户可能有多个角色,一个角色可以赋予多个用户。这样用户和角色两个实体类就是多对多的。
现在我们要实现查询用户时,可以同时得到用户所包含的角色信息。当我们查询角色时,可以同时得到角色的所赋予的用户信息。
前期工作
我们创一个新的工程,然后把one2many的配置全部cv进来,然后删掉account有关的东西
多对多关系就必然要有个中间表,我们用以下代码建表
DROP TABLE IF EXISTS `role`; CREATE TABLE `role` ( `ID` int(11) NOT NULL COMMENT '编号', `ROLE_NAME` varchar(30) default NULL COMMENT '角色名称', `ROLE_DESC` varchar(60) default NULL COMMENT '角色描述', PRIMARY KEY (`ID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; insert into `role`(`ID`,`ROLE_NAME`,`ROLE_DESC`) values (1,'院长','管理整个学院'),(2,'总裁','管理整个公司'),(3,'校长','管理整个学校'); CREATE TABLE `user_role` ( `UID` int(11) NOT NULL COMMENT '用户编号', `RID` int(11) NOT NULL COMMENT '角色编号', PRIMARY KEY (`UID`,`RID`), KEY `FK_Reference_10` (`RID`), CONSTRAINT `FK_Reference_10` FOREIGN KEY (`RID`) REFERENCES `role` (`ID`), CONSTRAINT `FK_Reference_9` FOREIGN KEY (`UID`) REFERENCES `user` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; insert into `user_role`(`UID`,`RID`) values (41,1),(45,1),(41,2);
其中role是角色表,user_role就是中间表,中间表包含uid和rid分别对应user表和role表的主键,中间表可以理解为就是一个map映射
然后我们来到java创建role的实体类,生成相应方法,注意这里的变量名和数据库表的列名不一致
然后我们来写role的dao接口
接着我们来写role的xml配置
随后我们就来写测试类,直接用user的cv一个roletest
运行一下,奈斯
查角色获得角色和用户
因为角色和用户是多对多,我们的role类里就要加入多对多的关系映射,也就是有个user的list,并生成对应方法
在考虑xml配置之前我们得先想我们的sql语句要怎么写,我们要求在查询角色的条件下,同时得到该角色赋予的所有用户,我们得到的结果集应该长这样,依据是那张中间表
所以我们是不是有点眉目了,首先我们讲role左外连接中间表(id=rid),然后再左外连接user表(uid=id),一共两次左外连接
select u.*,r.id as rid,r.role_name,r.role_desc from role r left outer join user_role ur on r.id = ur.rid left outer join user u on u.id = ur.uid;
然后我们在xml配置里面加入这条sql语句,这里有个注意的点就是换行处最好加个空格,这样在字符串拼接的时候语句就不会没间隔
最后我们配置resultMap,和上次一样是collection配置,这里需要注意因为我们role表的id起了别名叫rid,我们在resultMap里要对应改成rid
最后我们在测试类加个分割线和输出用户表
跑一下,见证奇迹的时刻到了!啊!奈斯~
查用户获得用户和角色
那这个流程和查角色是差不多的,角色到用户反过来就是用户到角色,我们只需改改sql语句,用户左外连接中间表然后再左外连接角色表就行(把上面的左外改成右外也行)
我们来到user类,为它添加多对多的关系映射
接着我们写user的xml配置,和上次的写法差不多,需要注意role表的id字段改名为rid了
最后我们改改测试类
run一下,搞定,41和45的user下面有角色信息