MyBatis进行一对多的关联表操作

时间:2021-12-13 11:58:28

一、准备t_role 、t_role_promission、t_promission表

CREATE TABLE `t_role` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `sn` varchar(255) NOT NULL,
  `name` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8;
CREATE TABLE `t_permission` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `url` varchar(255) NOT NULL,
  `sn` varchar(255) NOT NULL,
  `systemmenu_id` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `qwe` (`systemmenu_id`),
  CONSTRAINT `qwe` FOREIGN KEY (`systemmenu_id`) REFERENCES `t_systemmenu` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
CREATE TABLE `t_role_permission` (
  `role_id` bigint(20) NOT NULL DEFAULT '0',
  `permission_id` bigint(20) NOT NULL DEFAULT '0',
  PRIMARY KEY (`role_id`,`permission_id`),
  KEY `wl` (`permission_id`),
  CONSTRAINT `wl` FOREIGN KEY (`permission_id`) REFERENCES `t_permission` (`id`),
  CONSTRAINT `wq` FOREIGN KEY (`role_id`) REFERENCES `t_role` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

二、准备role和permission的domain表,

 1 public class Role {
 2 
 3     private Long id;
 4 
 5     private String sn;//编码  admin
 6 
 7     private String name;//名称  超级管理员
 8 
 9     private List<Permission> permissions;//角色对应的权限
10 
11     //省略了get、set      
12 }
 1 public class Permission {
 2     private Long id;
 3 
 4     private String name;
 5 
 6     private String url;//权限路径  /employee/save
 7 
 8     private String sn;//编码  employee:save
 9 
10     private Long systemmenuId;//菜单
11   
12    // 省略get、set    
13 }

由于mabatis没有级联操作,所以我们将中间表也需要建立一个domain

1 public class RolePermission {
2 
3     private Role role;
4     private Permission permission;
5   
6   //省略get、set    
7 }

三、mabatis一对多关联查询

RoleMapper.xml
 1 <mapper namespace="com.wangshifu.car_repair.mapper.RoleMapper" >
 2   <resultMap id="BaseResultMap" type="com.wangshifu.car_repair.domain.Role" >
 3     <id column="id" property="id" jdbcType="BIGINT" />
 4     <result column="sn" property="sn" jdbcType="VARCHAR" />
 5     <result column="name" property="name" jdbcType="VARCHAR" />
 6     <collection property="permissions" ofType="com.wangshifu.car_repair.domain.Permission"
 7       column="id" select="com.wangshifu.car_repair.mapper.PermissionMapper.selectPermission"
 8     >
 9      <!-- <id column="pid" property="id" />
10       <result column="pname" property="name" />
11       <result column="purl" property="url" />
12       <result column="psn" property="sn" />-->
13     </collection>
14   </resultMap>
15 <!--分页查询-->
16   <select id="selectQuery" resultMap="BaseResultMap" parameterType="com.wangshifu.car_repair.query.RoleQuery" >
17     /*select r.id, r.sn, r.name,p.id pid,p.name pname,p.url purl,p.sn psn
18     from t_role r left join t_role_permission rp ON r.id=rp.role_id
19     left JOIN t_permission p ON p.id =rp.permission_id*/
20     select distinct id, sn, name
21     from t_role
22     /*高级查询*/
23   <where>
24     <if test="name !=null and name!=''">
25       and r.name like concat('%',#{name},'%')
26     </if>
27   </where>
28   </select>
1 <!--  permission.xml     查询角色权限-->
2   <select id="selectPermission" resultMap="BaseResultMap"  parameterType="com.wangshifu.car_repair.domain.Role">
3   select p.*
4     from t_role r join t_role_permission rp ON r.id=rp.role_id
5   JOIN t_permission p ON p.id =rp.permission_id where r.id=#{id}
6   </select>

四、mabatis关联查询出现的分页问题

在上面我这里分别用了嵌套查询(注释部分)和嵌套结果,最开始使用的是嵌套查询,发现前台的分页是先将数据查询出来然后进行的分页,这样就导致的分页的错误信息,

MyBatis进行一对多的关联表操作

 

所以得使用嵌套结果,将这俩条sql独立,先将需要进行分页的数据进行分页,再将关联表的数据加入进来,分页信息就ok了。

MyBatis进行一对多的关联表操作

 

五、mabatis一对多关联增、删、改

 1 <!--   roleMapper.xml   角色权限添加-->
 2   <insert id="insertRoleAndPermission" parameterType="com.wangshifu.car_repair.domain.RolePermission">
 3     insert into t_role_permission (role_id, permission_id)
 4     values (#{role.id}, #{permission.id});
 5   </insert>
 6   <!--角色权限修改-->
 7   <update id="updateRoleAndPermission" parameterType="com.wangshifu.car_repair.domain.RolePermission">
 8     update t_role_permission
 9     set  permission_id = #{permission.id}
10     where role_id = #{role.id,jdbcType=BIGINT}
11     and permission_id=#{permission.id,jdbcType=BIGINT}
12   </update>
13   <!--角色权限删除-->
14   <delete id="deleteRoleAndPermission" parameterType="com.wangshifu.car_repair.domain.RolePermission" >
15     delete from t_role_permission
16     where role_id = #{role.id,jdbcType=BIGINT}
17     and permission_id=#{permission.id,jdbcType=BIGINT}
18   </delete>

六、mabatis一对多关联增、删、改java代码部分

 1 @Controller
 2 @RequestMapping("/role")
 3 public class RoleController {
 4 
 5     @Autowired
 6     private IRoleService roleService;
 7     @Autowired
 8     private IPermissionService permissionService;
 9 
10 
11     @RequestMapping("/delete")
12     @ResponseBody
13     public AjaxResult delete(Long id){
14         try {
15             //查询角色
16             Role role = roleService.findOne(id);
17             //查询权限
18             List<Permission> permissionsList = permissionService.selectPermission(role);
19             permissionsList.forEach(e->{
20                 //先删除中间表
21                 roleService.deleteRoleAndPermission(new RolePermission(role, e));
22             });
23             //再删除角色表
24             roleService.delete(id);
25             return new AjaxResult();
26         } catch (Exception e) {
27             e.printStackTrace();
28             return new AjaxResult(e.getMessage());
29         }
30     }
31 
32 
33     @RequestMapping("/save")
34     @ResponseBody
35     public AjaxResult save(Role role){
36         try {
37             //该角色权限(只有id,前台传过来的)
38             List<Permission> permissions = role.getPermissions();
39             //保存角色返回主键(需要在对应mapper.xml配置属性)
40             roleService.save(role);
41             //如果有权限
42             if(permissions.size()>0){
43                 permissions.forEach(e->{
44                     //保存中间表
45                     roleService.insertRoleAndPermission(new RolePermission(role, e));
46                 });
47             }
48             return new AjaxResult();
49         } catch (Exception e) {
50             e.printStackTrace();
51             return new AjaxResult(e.getMessage());
52         }
53     }
54 
55     @RequestMapping("/update")
56     @ResponseBody
57     public AjaxResult update(Role role){
58         try {
59             //该角色最新的权限(有id)
60             List<Permission> permissions = role.getPermissions();
61             //原来的权限
62             List<Permission> permissionList = permissionService.selectPermission(role);
63             if(permissionList.size()>0){
64                 permissionList.forEach(e->{
65                     //先删除原有关系中间表
66                     roleService.deleteRoleAndPermission(new RolePermission(role, e));
67                 });
68             }
69            if( permissions!=null  && permissions.size()>0 ){
70                permissions.forEach(p->{
71                    //添加最新的权限中间表
72                    roleService.insertRoleAndPermission(new RolePermission(role, p));
73                });
74            }
75             //最后修改角色表(因为外键关联、需要在中间表操作后才操作)
76             roleService.update(role);
77             return new AjaxResult();
78         } catch (Exception e) {
79             e.printStackTrace();
80             return new AjaxResult(e.getMessage());
81         }
82     }
83 }