RBAC权限模型,基于角色的权限控制 ,本质即用户与角色,角色与权限多对多的关系,通过这样的模型方便权限管理,避免多次重复赋予用户权限,减小了时间的浪费。
UserService
/**
* @className: UserService
* @description: service类描述
* @author: whz
* @date: 2021/9/19
**/
public interface UserService {
//通过id删除单个用户
int deleteById(Integer id);
//查全部
List<User> selectAll();
//批量删除
int deletedisp(int[] ids);
//通过id查询用户详细信息(包括角色集合)
UserVo selectUrById(Integer id);
//添加用户
int insert(User user,List<Integer> roleids);
//更新用户信息
int update(User user, List<Integer> uproleids);
//登录验证并回显菜单树
UserVo login(User user, HttpServletRequest request, HttpServletResponse response);
}
UserServiceImpl
/**
* @className: UserServiceImpl
* @description: TODO 类描述
* @author: whz
* @date: 2021/9/19
**/
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public int deleteById(Integer id) {
int i=userMapper.deleteById(id);
userMapper.deleteur(id);
return i;
}
@Override
public List<User> selectAll() {
List<User> li=userMapper.selectAll();
return li;
}
@Override
public int deletedisp(int[] ids) {
int flag=1;
int j;
for (int i = 0; i <ids.length ; i++) {
j=deleteById(ids[i]);
if(j==0){
flag=0;
}
}
return flag;
}
@Override
public UserVo selectUrById(Integer id) {
UserVo userVo = userMapper.selectUrById(id);
return userVo;
}
@Override
public int insert(User user, List<Integer> roleids) {
int i=userMapper.insert(user);
int userid=user.getId();
for (int j = 0; j <roleids.size() ; j++) {
User_Role user_role = new User_Role();
user_role.setUserid(userid);
user_role.setRoleid(roleids.get(j));
userMapper.insertur(user_role);
}
return i;
}
@Override
public int update(User user, List<Integer> uproleids) {
int i=userMapper.update(user);
userMapper.deleteur(user.getId());
for (int j = 0; j <uproleids.size() ; j++) {
User_Role user_role = new User_Role();
user_role.setUserid(user.getId());
user_role.setRoleid(uproleids.get(j));
userMapper.insertur(user_role);
}
return i;
}
public UserVo login(User user, HttpServletRequest request, HttpServletResponse response){
UserVo uv=userMapper.login(user);
if(uv!=null){//登陆成功
request.getSession().setAttribute("username",uv.getUsername() );
return uv;
}else {//登陆失败
return null;
}
}
}
登录验证做的比较简单,还可以添加拦截器对未登录用户强制转回登录页面,这里主要写了一些主要的增删改查逻辑,需要在删除用户的同时维护好用户——角色关联表,更新同理,这里先删除了待更新对象旧的关系行,然后重新添加。
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.qcby.shujia.demo.mapper.UserMapper">
<select id="selectUrById" resultMap="uservo">
SELECT user.id,user.username,user.password,role.rolename,role.id rid FROM user,user_role,role where user.id=user_role.userid and user_role.roleid=role.id and user.id=#{id}
</select>
<resultMap id="uservo" type="com.qcby.shujia.demo.entity.vo.UserVo">
<result property="id" column="id"></result>
<result property="username" column="username"></result>
<result property="password" column="password"></result>
<collection property="urlist" ofType="com.qcby.shujia.demo.entity.Role">
<result property="rolename" column="rolename"></result>
<result property="id" column="rid"></result>
</collection>
</resultMap>
<select id="selectAll" resultType="com.qcby.shujia.demo.entity.User">
select * from user where flag=1
</select>
<insert id="insert">
<selectKey keyProperty="id" resultType="int" order="AFTER">
select last_insert_id();
</selectKey>
insert into user (username,password) values (#{username},#{password})
</insert>
<insert id="insertur">
insert into user_role (userid,roleid) VALUES (#{userid},#{roleid})
</insert>
<update id="deleteById">
UPDATE user set flag=0 where id=#{id}
</update>
<update id="update" parameterType="com.qcby.shujia.demo.entity.User">
update user
<set>
<if test="username != null">
username=#{username},
</if>
<if test="password != null">
password=#{password},
</if>
</set>
where id = #{id}
</update>
<delete id="deleteur">
delete from user_role where userid=#{id}
</delete>
<select id="login" parameterType="com.qcby.shujia.demo.entity.User" resultMap="uservo">
SELECT user.id,user.username,user.password,role.rolename,role.id rid FROM user,user_role,role where user.id=user_role.userid and user_role.roleid=role.id
and username=#{username} and password=#{password}
</select>
</mapper>
涉及到多表联查,以及插入后获取当前id等零碎知识点
RoleServiceImpl
/**
* @className: RoleServiceImpl
* @description: TODO 类描述
* @author: whz
* @date: 2021/9/20
**/
@Service
public class RoleServiceImpl implements RoleService {
@Autowired
private RoleMapper roleMapper;
@Override
public int deleteById(Integer id) {
int i=roleMapper.deleteById(id);
roleMapper.deleterr(id);
roleMapper.deleteur(id);
return i;
}
@Override
public List<Role> selectAll() {
List<Role> li=roleMapper.selectAll();
return li;
}
@Override
public int deletedisp(int[] ids) {
int flag=1;
int j;
for (int i = 0; i <ids.length ; i++) {
j=deleteById(ids[i]);
if(j==0){
flag=0;
}
}
return flag;
}
@Override
public RoleVo selectRrById(Integer id) {
RoleVo roleVo = roleMapper.selectRrById(id);
return roleVo;
}
@Override
public int insert(Role role, List<Integer> rightids) {
int i=roleMapper.insert(role);
int roleid=role.getId();
for (int j = 0; j <rightids.size() ; j++) {
Role_Right role_right = new Role_Right();
role_right.setRoleid(roleid);
role_right.setRightid(rightids.get(j));
roleMapper.insertrr(role_right);
}
return i;
}
@Override
public int update(Role role, List<Integer> uprightids) {
int i = roleMapper.update(role);
roleMapper.deleterr(role.getId());
for (int j = 0; j < uprightids.size(); j++) {
Role_Right role_right = new Role_Right();
role_right.setRoleid(role.getId());
role_right.setRightid(uprightids.get(j));
roleMapper.insertrr(role_right);
}
return i;
}
}
对角色权限表进行维护,同样是多对多的处理,通过包装类同时将角色的权限对象查出来
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.qcby.shujia.demo.mapper.RoleMapper">
<select id="selectRrById" resultMap="rolevo">
SELECT role.id,role.rolename,tright.path_value,tright.path_str,tright.id rid FROM role inner join role_right on role.id=role_right.roleid inner join tright on role_right.rightid=tright.id where role.id=#{id}
</select>
<resultMap id="rolevo" type="com.qcby.shujia.demo.entity.vo.RoleVo">
<result property="id" column="id"></result>
<result property="rolename" column="rolename"></result>
<collection property="roRightli" ofType="com.qcby.shujia.demo.entity.Tright">
<result property="path_value" column="path_value"></result>
<result property="id" column="rid"></result>
<result property="path_str" column="path_str"></result>
</collection>
</resultMap>
<select id="selectAll" resultType="com.qcby.shujia.demo.entity.Role">
select * from role where flag=1
</select>
<insert id="insert">
<selectKey keyProperty="id" resultType="int" order="AFTER">
select last_insert_id();
</selectKey>
insert into role (rolename) values (#{rolename})
</insert>
<update id="deleteById">
UPDATE role set flag=0 where id=#{id}
</update>
<update id="update" parameterType="com.qcby.shujia.demo.entity.Role">
update role
<set>
<if test="rolename != null">
rolename=#{rolename},
</if>
</set>
where id = #{id}
</update>
<delete id="deleterr">
delete from role_right where roleid=#{id}
</delete>
<delete id="deleteur">
delete from user_role where roleid=#{id}
</delete>
<insert id="insertrr">
insert into role_right (roleid,rightid) VALUES (#{roleid},#{rightid})
</insert>
</mapper>
TrightServiceImpl
/**
* @className: TrightServiceImpl
* @description: TODO 类描述
* @author: whz
* @date: 2021/9/20
**/
@Service
public class TrightServiceImpl implements TrightService {
@Autowired
private TrightMapper trightMapper;
@Override
public int insert(Tright tright) {
int i=trightMapper.insert(tright);
return i;
}
@Override
public int delete(Integer id) {
int i=trightMapper.deleteById(id);
trightMapper.deleterr(id);
return i;
}
@Override
public int deletedisp(int[] ids) {
int flag=1;
for (int i = 0; i <ids.length ; i++) {
int i1 = delete(ids[i]);
if(i1==0){
flag=0;
}
}
return flag;
}
@Override
public List<Tright> selectAll() {
List<Tright> li=trightMapper.selectAll();
return li;
}
@Override
public int update(Tright tright) {
int i=trightMapper.update(tright);
return i;
}
}
最简单的一环,因为是单表的增删改查,有一个点需要注意,删除权限后需要去维护权限——角色表里的信息,否则导致无效的权限仍然会被角色获取。
RightMapper.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.qcby.shujia.demo.mapper.TrightMapper">
<insert id="insert">
insert into tright (path_value,path_str) values (#{path_value},#{path_str})
</insert>
<update id="deleteById">
UPDATE tright set flag=0 where id=#{id}
</update>
<select id="selectAll" resultType="com.qcby.shujia.demo.entity.Tright">
select * from tright where flag=1
</select>
<delete id="deleterr">
delete from role_right where rightid=#{id}
</delete>
<update id="update" parameterType="com.qcby.shujia.demo.entity.Tright">
update tright
<set>
<if test="path_value != null">
path_value=#{path_value},
</if>
<if test="path_str != null">
path_str=#{path_str},
</if>
</set>
where id = #{id}
</update>
</mapper>
这一块博主犯了一个错误,在建表的时候将权限表名字设置为了right,这是个关键字!!!导致后期联表查询怎么查都报错才发现,大家千万要避免踩坑,因此我把right设置成了tright的名字,但是后面太多不好改,在不影响代码的前提下做了一些修正,建表需要以_为间隔,代码规范很重要!