spring cloud(六)系统管理之用户、角色、菜单数据库设计及实现

本系列文章均参考:朝雨忆轻尘,感谢博主!

这里还有他的技术交流群:429854222,欢迎大家支持博主

若有侵权,还请告知,一定删除

一、需求说明

不同的账户登录系统看到的是不同的菜单,最高权限账户能看到所有的。

二、数据库设计

首先看张ER图:

我们看图说话:后台人员各自拥有不同的账户,分配了不同的角色,一个账号可以分配多个角色(一对多),一个角色也可以分配给不同的账户(一对多),所以账户角色是多对多的关系;同理。角色权限也是多对多,这里设计的时候把菜单和权限绑定在一起。

数据库设计如下:

账户表sys_user:

角色表sys_role:

菜单表sys_menu:

用户角色表sys_user_role:

角色菜单表sys_role_menu:

 

这样的话,根据需求的数据库就设计出来了,接下来就是代码实现了。

三、代码实现

3.1、用户

3.1.1、model

public class SysUser extends BaseModel {

    private String name;

    private String password;

    private String salt;

    private String email;

    private String mobile;

    private Byte status;

    private Long deptId;
    
    private String deptName;
    
    private Byte delFlag;
    
    private String roleNames;
    
    private List<SysUserRole> userRoles = new ArrayList<>();

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getSalt() {
		return salt;
	}

	public void setSalt(String salt) {
		this.salt = salt;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getMobile() {
		return mobile;
	}

	public void setMobile(String mobile) {
		this.mobile = mobile;
	}

	public Byte getStatus() {
		return status;
	}

	public void setStatus(Byte status) {
		this.status = status;
	}

	public Long getDeptId() {
		return deptId;
	}

	public void setDeptId(Long deptId) {
		this.deptId = deptId;
	}

	public String getDeptName() {
		return deptName;
	}

	public void setDeptName(String deptName) {
		this.deptName = deptName;
	}

	public Byte getDelFlag() {
		return delFlag;
	}

	public void setDelFlag(Byte delFlag) {
		this.delFlag = delFlag;
	}

	public String getRoleNames() {
		return roleNames;
	}

	public void setRoleNames(String roleNames) {
		this.roleNames = roleNames;
	}

	public List<SysUserRole> getUserRoles() {
		return userRoles;
	}

	public void setUserRoles(List<SysUserRole> userRoles) {
		this.userRoles = userRoles;
	}

}

3.1.2、dao

public interface SysUserMapper {
    int deleteByPrimaryKey(Long id);

    int insert(SysUser record);

    int insertSelective(SysUser record);

    SysUser selectByPrimaryKey(Long id);

    int updateByPrimaryKeySelective(SysUser record);

    int updateByPrimaryKey(SysUser record);
    
    List<SysUser> findPage();
    
    SysUser findByName(@Param(value="name") String name);
    
	List<SysUser> findPageByName(@Param(value="name") String name);
	
	List<SysUser> findPageByNameAndEmail(@Param(value="name") String name, @Param(value="email") String email);
}

3.1.3、mapper

<?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.***.dao.SysUserMapper">
  <resultMap id="BaseResultMap" type="com.***.model.SysUser">
    <id column="id" jdbcType="BIGINT" property="id" />
    <result column="name" jdbcType="VARCHAR" property="name" />
    <result column="password" jdbcType="VARCHAR" property="password" />
    <result column="salt" jdbcType="VARCHAR" property="salt" />
    <result column="email" jdbcType="VARCHAR" property="email" />
    <result column="mobile" jdbcType="VARCHAR" property="mobile" />
    <result column="status" jdbcType="TINYINT" property="status" />
    <result column="dept_id" jdbcType="BIGINT" property="deptId" />
    <result column="create_by" jdbcType="BIGINT" property="createBy" />
    <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
    <result column="last_update_by" jdbcType="BIGINT" property="lastUpdateBy" />
    <result column="last_update_time" jdbcType="TIMESTAMP" property="lastUpdateTime" />
    <result column="del_flag" jdbcType="TINYINT" property="delFlag" />
  </resultMap>
  <sql id="Base_Column_List">
    id, name, password, salt, email, mobile, status, dept_id, create_by, create_time, 
    last_update_by, last_update_time, del_flag
  </sql>
  <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
    select 
    <include refid="Base_Column_List" />
    from sys_user
    where id = #{id,jdbcType=BIGINT}  
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
    delete from sys_user
    where id = #{id,jdbcType=BIGINT}
  </delete>
  <insert id="insert" parameterType="com.***.model.SysUser">
    insert into sys_user (id, name, password, 
      salt, email, mobile, 
      status, dept_id, create_by, 
      create_time, last_update_by, last_update_time, 
      del_flag)
    values (#{id,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, 
      #{salt,jdbcType=VARCHAR}, #{email,jdbcType=VARCHAR}, #{mobile,jdbcType=VARCHAR}, 
      #{status,jdbcType=TINYINT}, #{deptId,jdbcType=BIGINT}, #{createBy,jdbcType=BIGINT}, 
      #{createTime,jdbcType=TIMESTAMP}, #{lastUpdateBy,jdbcType=BIGINT}, #{lastUpdateTime,jdbcType=TIMESTAMP}, 
      #{delFlag,jdbcType=TINYINT})
  </insert>
  <insert id="insertSelective" parameterType="com.***.model.SysUser">
    insert into sys_user
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
      <if test="name != null">
        name,
      </if>
      <if test="password != null">
        password,
      </if>
      <if test="salt != null">
        salt,
      </if>
      <if test="email != null">
        email,
      </if>
      <if test="mobile != null">
        mobile,
      </if>
      <if test="status != null">
        status,
      </if>
      <if test="deptId != null">
        dept_id,
      </if>
      <if test="createBy != null">
        create_by,
      </if>
      <if test="createTime != null">
        create_time,
      </if>
      <if test="lastUpdateBy != null">
        last_update_by,
      </if>
      <if test="lastUpdateTime != null">
        last_update_time,
      </if>
      <if test="delFlag != null">
        del_flag,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="id != null">
        #{id,jdbcType=BIGINT},
      </if>
      <if test="name != null">
        #{name,jdbcType=VARCHAR},
      </if>
      <if test="password != null">
        #{password,jdbcType=VARCHAR},
      </if>
      <if test="salt != null">
        #{salt,jdbcType=VARCHAR},
      </if>
      <if test="email != null">
        #{email,jdbcType=VARCHAR},
      </if>
      <if test="mobile != null">
        #{mobile,jdbcType=VARCHAR},
      </if>
      <if test="status != null">
        #{status,jdbcType=TINYINT},
      </if>
      <if test="deptId != null">
        #{deptId,jdbcType=BIGINT},
      </if>
      <if test="createBy != null">
        #{createBy,jdbcType=BIGINT},
      </if>
      <if test="createTime != null">
        #{createTime,jdbcType=TIMESTAMP},
      </if>
      <if test="lastUpdateBy != null">
        #{lastUpdateBy,jdbcType=BIGINT},
      </if>
      <if test="lastUpdateTime != null">
        #{lastUpdateTime,jdbcType=TIMESTAMP},
      </if>
      <if test="delFlag != null">
        #{delFlag,jdbcType=TINYINT},
      </if>
    </trim>
  </insert>
  <update id="updateByPrimaryKeySelective" parameterType="com.***.model.SysUser">
    update sys_user
    <set>
      <if test="name != null">
        name = #{name,jdbcType=VARCHAR},
      </if>
      <if test="password != null">
        password = #{password,jdbcType=VARCHAR},
      </if>
      <if test="salt != null">
        salt = #{salt,jdbcType=VARCHAR},
      </if>
      <if test="email != null">
        email = #{email,jdbcType=VARCHAR},
      </if>
      <if test="mobile != null">
        mobile = #{mobile,jdbcType=VARCHAR},
      </if>
      <if test="status != null">
        status = #{status,jdbcType=TINYINT},
      </if>
      <if test="deptId != null">
        dept_id = #{deptId,jdbcType=BIGINT},
      </if>
      <if test="createBy != null">
        create_by = #{createBy,jdbcType=BIGINT},
      </if>
      <if test="createTime != null">
        create_time = #{createTime,jdbcType=TIMESTAMP},
      </if>
      <if test="lastUpdateBy != null">
        last_update_by = #{lastUpdateBy,jdbcType=BIGINT},
      </if>
      <if test="lastUpdateTime != null">
        last_update_time = #{lastUpdateTime,jdbcType=TIMESTAMP},
      </if>
      <if test="delFlag != null">
        del_flag = #{delFlag,jdbcType=TINYINT},
      </if>
    </set>
    where id = #{id,jdbcType=BIGINT}
  </update>
  <update id="updateByPrimaryKey" parameterType="com.***.model.SysUser">
    update sys_user
    set name = #{name,jdbcType=VARCHAR},
      password = #{password,jdbcType=VARCHAR},
      salt = #{salt,jdbcType=VARCHAR},
      email = #{email,jdbcType=VARCHAR},
      mobile = #{mobile,jdbcType=VARCHAR},
      status = #{status,jdbcType=TINYINT},
      dept_id = #{deptId,jdbcType=BIGINT},
      create_by = #{createBy,jdbcType=BIGINT},
      create_time = #{createTime,jdbcType=TIMESTAMP},
      last_update_by = #{lastUpdateBy,jdbcType=BIGINT},
      last_update_time = #{lastUpdateTime,jdbcType=TIMESTAMP},
      del_flag = #{delFlag,jdbcType=TINYINT}
    where id = #{id,jdbcType=BIGINT}
  </update>
  <select id="findPage" resultMap="BaseResultMap">
    select u.*, (select d.name from sys_dept d where d.id = u.dept_id) deptName from sys_user u where 
  </select>
  <select id="findByName" parameterType="java.lang.String" resultMap="BaseResultMap">
    select u.*, (select d.name from sys_dept d where d.id = u.dept_id) deptName from sys_user u
    where u.name = #{name,jdbcType=VARCHAR}
  </select>
  <select id="findPageByName" parameterType="java.lang.String" resultMap="BaseResultMap">
  	<bind name="pattern" value="'%' + _parameter.name + '%'" />
    select u.*, (select d.name from sys_dept d where d.id = u.dept_id) deptName from sys_user u
    where u.name like #{pattern} 
  </select>
  <select id="findPageByNameAndEmail" parameterType="java.lang.String" resultMap="BaseResultMap">
  	<bind name="patternName" value="'%' + _parameter.name + '%'" />
  	<bind name="patternEmail" value="'%' + _parameter.email + '%'" />
    select u.*, (select d.name from sys_dept d where d.id = u.dept_id) deptName from sys_user u
    where u.name like #{patternName}
    and u.email like #{patternEmail} 
  </select>
</mapper>

3.1.4、service以及impl

public interface SysUserService extends CurdService<SysUser> {

	SysUser findByName(String username);
	
	SysUser findByToken(String token);

	/**
	 * 查找用户的菜单权限标识集合
	 * @param userName
	 * @return
	 */
	Set<String> findPermissions(String userName);

	/**
	 * 查找用户的角色集合
	 * @param userName
	 * @return
	 */
	List<SysUserRole> findUserRoles(Long userId);
	
	int savePWD(SysUser sysUser);

}
@Service
public class SysUserServiceImpl  implements SysUserService {

	@Autowired
	private SysUserMapper sysUserMapper;
	@Autowired
	private SysMenuMapper sysMenuMapper;
	@Autowired
	private SysUserRoleMapper sysUserRoleMapper;
	@Autowired
	private SysRoleMapper sysRoleMapper;
	@Autowired
	private SysUserTokenMapper sysUserTokenMapper;

	@Override
	public int save(SysUser record) {
		Long id = null;
		if(record.getId() == null || record.getId() == 0) {
			// 新增用户
			sysUserMapper.insertSelective(record);
			id = record.getId();
		} else {
			// 更新用户信息
			sysUserMapper.updateByPrimaryKeySelective(record);
		}
		// 更新用户角色
		if(id != null && id == 0) {
			return 1;
		}
		if(id != null) {
			for(SysUserRole sysUserRole:record.getUserRoles()) {
				sysUserRole.setUserId(id);
			}
		} else {
			sysUserRoleMapper.deleteByUserId(record.getId());
		}
		for(SysUserRole sysUserRole:record.getUserRoles()) {
			sysUserRoleMapper.insertSelective(sysUserRole);
		}
		return 1;
	}
	
	@Override
	public int savePWD(SysUser sysUser) {
		if(sysUser.getId() == null || sysUser.getId() == 0) {
			return 0;
		}
		// 更新用户信息
		return sysUserMapper.updateByPrimaryKeySelective(sysUser);
	}

	@Override
	public int delete(SysUser record) {
		return sysUserMapper.deleteByPrimaryKey(record.getId());
	}

	@Override
	public int delete(List<SysUser> records) {
		for(SysUser record:records) {
			delete(record);
		}
		return 1;
	}

	@Override
	public SysUser findById(Long id) {
		return sysUserMapper.selectByPrimaryKey(id);
	}
	
	@Override
	public SysUser findByName(String name) {
		return sysUserMapper.findByName(name);
	}
	
	@Override
	public PageResult findPage(PageRequest pageRequest) {
		PageResult pageResult = null;
		String name = getColumnFilterValue(pageRequest, "name");
		String email = getColumnFilterValue(pageRequest, "email");
		if(name != null) {
			if(email != null) {
				pageResult = MybatisPageHelper.findPage(pageRequest, sysUserMapper, "findPageByNameAndEmail", name, email);
			} else {
				pageResult = MybatisPageHelper.findPage(pageRequest, sysUserMapper, "findPageByName", name);
			}
		} else {
			pageResult = MybatisPageHelper.findPage(pageRequest, sysUserMapper);
		}
		// 加载用户角色信息
		findUserRoles(pageResult);
		return pageResult;
	}

	/**
	 * 获取过滤字段的值
	 * @param filterName
	 * @return
	 */
	public String getColumnFilterValue(PageRequest pageRequest, String filterName) {
		String value = null;
		ColumnFilter columnFilter = pageRequest.getColumnFilter(filterName);
		if(columnFilter != null) {
			value = columnFilter.getValue();
		}
		return value;
	}
	
	/**
	 * 加载用户角色
	 * @param pageResult
	 */
	private void findUserRoles(PageResult pageResult) {
		List<?> content = pageResult.getContent();
		for(Object object:content) {
			SysUser sysUser = (SysUser) object;
			List<SysUserRole> userRoles = findUserRoles(sysUser.getId());
			sysUser.setUserRoles(userRoles);
			sysUser.setRoleNames(getRoleNames(userRoles));
		}
	}

	private String getRoleNames(List<SysUserRole> userRoles) {
		StringBuilder sb = new StringBuilder();
		for(Iterator<SysUserRole> iter=userRoles.iterator(); iter.hasNext();) {
			SysUserRole userRole = iter.next();
			SysRole sysRole = sysRoleMapper.selectByPrimaryKey(userRole.getRoleId());
			if(sysRole == null) {
				continue ;
			}
			sb.append(sysRole.getRemark());
			if(iter.hasNext()) {
				sb.append(", ");
			}
		}
		return sb.toString();
	}

	@Override
	public Set<String> findPermissions(String userName) {	
		Set<String> perms = new HashSet<>();
		List<SysMenu> sysMenus = findByUser(userName);
		for(SysMenu sysMenu:sysMenus) {
			if(sysMenu.getPerms() != null && !"".equals(sysMenu.getPerms())) {
				perms.add(sysMenu.getPerms());
			}
		}
		return perms;
	}

	@Override
	public List<SysUserRole> findUserRoles(Long userId) {
		return sysUserRoleMapper.findUserRoles(userId);
	}
	
	private List<SysMenu> findByUser(String userName) {
		if(userName == null || "".equals(userName) || SysConstants.ADMIN.equalsIgnoreCase(userName)) {
			return sysMenuMapper.findAll();
		}
		return sysMenuMapper.findByUserName(userName);
	}

	@Override
	public SysUser findByToken(String token) {
		SysUserToken sysUserToken = sysUserTokenMapper.findByToken(token);
		return sysUserMapper.selectByPrimaryKey(sysUserToken.getUserId());
	}

}

代码有的地方是跟token有关的,这是因为后台API的接口都是通过token鉴权来访问的(每个用户登录一次都会生成一个token),通过token来查询更方便一点。

重点方法:findPermissionsfindUserRoles

3.2、角色

3.2.1、model

public class SysRole extends BaseModel {

    private String name;

    private String remark;

    private Byte delFlag;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getRemark() {
		return remark;
	}

	public void setRemark(String remark) {
		this.remark = remark;
	}

	public Byte getDelFlag() {
		return delFlag;
	}

	public void setDelFlag(Byte delFlag) {
		this.delFlag = delFlag;
	}

}

3.2.2、dao

public interface SysRoleMapper {
    int deleteByPrimaryKey(Long id);

    int insert(SysRole record);

    int insertSelective(SysRole record);

    SysRole selectByPrimaryKey(Long id);

    int updateByPrimaryKeySelective(SysRole record);

    int updateByPrimaryKey(SysRole record);
    
    List<SysRole> findPage();

	List<SysRole> findAll();
	
	List<SysRole> findPageByName(@Param(value="name") String name);
	
	List<SysRole> findByName(@Param(value="name") String name);
}

3.2.3、mapper

<?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.***.dao.SysRoleMapper">
  <resultMap id="BaseResultMap" type="com.***.model.SysRole">
    <id column="id" jdbcType="BIGINT" property="id" />
    <result column="name" jdbcType="VARCHAR" property="name" />
    <result column="remark" jdbcType="VARCHAR" property="remark" />
    <result column="create_by" jdbcType="BIGINT" property="createBy" />
    <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
    <result column="last_update_by" jdbcType="BIGINT" property="lastUpdateBy" />
    <result column="last_update_time" jdbcType="TIMESTAMP" property="lastUpdateTime" />
    <result column="del_flag" jdbcType="TINYINT" property="delFlag" />
  </resultMap>
  <sql id="Base_Column_List">
    id, name, remark, create_by, create_time, last_update_by, last_update_time, 
    del_flag
  </sql>
  <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
    select 
    <include refid="Base_Column_List" />
    from sys_role
    where id = #{id,jdbcType=BIGINT} 
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
    delete from sys_role
    where id = #{id,jdbcType=BIGINT} 
  </delete>
  <insert id="insert" parameterType="com.***.model.SysRole">
    insert into sys_role (id, name, remark, 
      create_by, create_time, last_update_by, 
      last_update_time, del_flag)
    values (#{id,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{remark,jdbcType=VARCHAR}, 
      #{createBy,jdbcType=BIGINT}, #{createTime,jdbcType=TIMESTAMP}, #{lastUpdateBy,jdbcType=BIGINT}, 
      #{lastUpdateTime,jdbcType=TIMESTAMP}, #{delFlag,jdbcType=TINYINT})
  </insert>
  <insert id="insertSelective" parameterType="com.***.model.SysRole">
    insert into sys_role
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
      <if test="name != null">
        name,
      </if>
      <if test="remark != null">
        remark,
      </if>
      <if test="createBy != null">
        create_by,
      </if>
      <if test="createTime != null">
        create_time,
      </if>
      <if test="lastUpdateBy != null">
        last_update_by,
      </if>
      <if test="lastUpdateTime != null">
        last_update_time,
      </if>
      <if test="delFlag != null">
        del_flag,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="id != null">
        #{id,jdbcType=BIGINT},
      </if>
      <if test="name != null">
        #{name,jdbcType=VARCHAR},
      </if>
      <if test="remark != null">
        #{remark,jdbcType=VARCHAR},
      </if>
      <if test="createBy != null">
        #{createBy,jdbcType=BIGINT},
      </if>
      <if test="createTime != null">
        #{createTime,jdbcType=TIMESTAMP},
      </if>
      <if test="lastUpdateBy != null">
        #{lastUpdateBy,jdbcType=BIGINT},
      </if>
      <if test="lastUpdateTime != null">
        #{lastUpdateTime,jdbcType=TIMESTAMP},
      </if>
      <if test="delFlag != null">
        #{delFlag,jdbcType=TINYINT},
      </if>
    </trim>
  </insert>
  <update id="updateByPrimaryKeySelective" parameterType="com.***.model.SysRole">
    update sys_role
    <set>
      <if test="name != null">
        name = #{name,jdbcType=VARCHAR},
      </if>
      <if test="remark != null">
        remark = #{remark,jdbcType=VARCHAR},
      </if>
      <if test="createBy != null">
        create_by = #{createBy,jdbcType=BIGINT},
      </if>
      <if test="createTime != null">
        create_time = #{createTime,jdbcType=TIMESTAMP},
      </if>
      <if test="lastUpdateBy != null">
        last_update_by = #{lastUpdateBy,jdbcType=BIGINT},
      </if>
      <if test="lastUpdateTime != null">
        last_update_time = #{lastUpdateTime,jdbcType=TIMESTAMP},
      </if>
      <if test="delFlag != null">
        del_flag = #{delFlag,jdbcType=TINYINT},
      </if>
    </set>
    where id = #{id,jdbcType=BIGINT}
  </update>
  <update id="updateByPrimaryKey" parameterType="com.***.model.SysRole">
    update sys_role
    set name = #{name,jdbcType=VARCHAR},
      remark = #{remark,jdbcType=VARCHAR},
      create_by = #{createBy,jdbcType=BIGINT},
      create_time = #{createTime,jdbcType=TIMESTAMP},
      last_update_by = #{lastUpdateBy,jdbcType=BIGINT},
      last_update_time = #{lastUpdateTime,jdbcType=TIMESTAMP},
      del_flag = #{delFlag,jdbcType=TINYINT}
    where id = #{id,jdbcType=BIGINT}
  </update>
  <select id="findPage" resultMap="BaseResultMap">
    select 
    <include refid="Base_Column_List" />
    from sys_role  
  </select>
  <select id="findAll" resultMap="BaseResultMap">
    select 
    <include refid="Base_Column_List" />
    from sys_role  
  </select>
  <select id="findPageByName" parameterType="java.lang.String" resultMap="BaseResultMap">
  	<bind name="pattern" value="'%' + _parameter.name + '%'" />
  	select 
    <include refid="Base_Column_List" />
    from sys_role
    where name like #{pattern} 
  </select>
  <select id="findByName" parameterType="java.lang.String" resultMap="BaseResultMap">
    select 
    <include refid="Base_Column_List" />
    from sys_role
    where name = #{name,jdbcType=VARCHAR} 
  </select>
</mapper>

3.2.4、service以及impl

public interface SysRoleService extends CurdService<SysRole> {

	/**
	 * 查询全部
	 * @return
	 */
	List<SysRole> findAll();

	/**
	 * 查询角色菜单集合
	 * @return
	 */
	List<SysMenu> findRoleMenus(Long roleId);

	/**
	 * 保存角色菜单
	 * @param records
	 * @return
	 */
	int saveRoleMenus(List<SysRoleMenu> records);

	/**
	 * 根据名称查询
	 * @param name
	 * @return
	 */
	List<SysRole> findByName(String name);
	
	
	/**
	 * 查询角色区域集合
	 * @return
	 */
	List<SysArea> findRoleAreas(Long roleId);

	/**
	 * 保存角色区域
	 * @param records
	 * @return
	 */
	int saveRoleAreas(List<SysRoleArea> records);

	List<SysRole> findRoleByName(String name);
}
@Service
public class SysRoleServiceImpl  implements SysRoleService {

	@Autowired
	private SysRoleMapper sysRoleMapper;
	@Autowired
	private SysRoleMenuMapper sysRoleMenuMapper;
	@Autowired
	private SysRoleAreaMapper sysRoleAreaMapper;
	@Autowired
	private SysMenuMapper sysMenuMapper;
	@Autowired
	private SysAreaMapper sysAreaMapper;
	@Autowired
	private SysUserMapper sysUserMapper;
	@Autowired
	private SysUserRoleMapper sysUserRoleMapper;

	@Override
	public int save(SysRole record) {
		if(record.getId() == null || record.getId() == 0) {
			return sysRoleMapper.insertSelective(record);
		}
		return sysRoleMapper.updateByPrimaryKeySelective(record);
	}

	@Override
	public int delete(SysRole record) {
		return sysRoleMapper.deleteByPrimaryKey(record.getId());
	}

	@Override
	public int delete(List<SysRole> records) {
		for(SysRole record:records) {
			delete(record);
		}
		return 1;
	}

	@Override
	public SysRole findById(Long id) {
		return sysRoleMapper.selectByPrimaryKey(id);
	}

	@Override
	public PageResult findPage(PageRequest pageRequest) {
		ColumnFilter columnFilter = pageRequest.getColumnFilter("name");
		if(columnFilter != null && columnFilter.getValue() != null) {
			return MybatisPageHelper.findPage(pageRequest, sysRoleMapper, "findPageByName", columnFilter.getValue());
		}
		return MybatisPageHelper.findPage(pageRequest, sysRoleMapper);
	}

	@Override
	public List<SysRole> findAll() {
		return sysRoleMapper.findAll();
	}

	public SysRoleMapper getSysRoleMapper() {
		return sysRoleMapper;
	}

	public void setSysRoleMapper(SysRoleMapper sysRoleMapper) {
		this.sysRoleMapper = sysRoleMapper;
	}

	@Override
	public List<SysMenu> findRoleMenus(Long roleId) {
		SysRole sysRole = sysRoleMapper.selectByPrimaryKey(roleId);
		if(SysConstants.ADMIN.equalsIgnoreCase(sysRole.getName())) {
			// 如果是超级管理员,返回全部
			return sysMenuMapper.findAll();
		}
		return sysMenuMapper.findRoleMenus(roleId);
	}

	@Transactional
	@Override
	public int saveRoleMenus(List<SysRoleMenu> records) {
		if(records == null || records.isEmpty()) {
			return 1;
		}
		Long roleId = records.get(0).getRoleId(); 
		sysRoleMenuMapper.deleteByRoleId(roleId);
		for(SysRoleMenu record:records) {
			sysRoleMenuMapper.insertSelective(record);
		}
		return 1;
	}

	@Override
	public List<SysRole> findByName(String name) {
		return sysRoleMapper.findByName(name);
	}

	@Override
	public List<SysArea> findRoleAreas(Long roleId) {
		SysRole sysRole = sysRoleMapper.selectByPrimaryKey(roleId);
		if(SysConstants.ADMIN.equalsIgnoreCase(sysRole.getName())) {
			// 如果是超级管理员,返回全部
			return sysAreaMapper.findAll();
		}
		return sysAreaMapper.findRoleAreas(roleId);
	}

	@Override
	public int saveRoleAreas(List<SysRoleArea> records) {
		if(records == null || records.isEmpty()) {
			return 1;
		}
		Long roleId = records.get(0).getRoleId(); 
		sysRoleAreaMapper.deleteByRoleId(roleId);
		for(SysRoleArea record:records) {
			sysRoleAreaMapper.insert(record);
		}
		return 1;
	}

	@Override
	public List<SysRole> findRoleByName(String name) {
		SysUser user = sysUserMapper.findByName(name);
		List<SysUserRole> userRoles = sysUserRoleMapper.findUserRoles(user.getId());
		List<SysRole> res = new ArrayList<>();
		for (SysUserRole userRole : userRoles) {
			res.add(sysRoleMapper.selectByPrimaryKey(userRole.getRoleId()));
		}
		return res;
	}

}

重点方法: findRoleMenus、saveRoleMenus、findRoleByName

3.3、菜单

3.3.1、model

public class SysMenu extends BaseModel {

    private Long parentId;

    private String name;

    private String url;

    private String perms;

    private Integer type;

    private String icon;

    private Integer orderNum;

    private Byte delFlag;

    // 非数据库字段
    private String parentName;
    // 非数据库字段
    private Integer level;
    // 非数据库字段
    private List<SysMenu> children;
    
	public Long getParentId() {
		return parentId;
	}

	public void setParentId(Long parentId) {
		this.parentId = parentId;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public String getPerms() {
		return perms;
	}

	public void setPerms(String perms) {
		this.perms = perms;
	}

	public Integer getType() {
		return type;
	}

	public void setType(Integer type) {
		this.type = type;
	}

	public String getIcon() {
		return icon;
	}

	public void setIcon(String icon) {
		this.icon = icon;
	}

	public Integer getOrderNum() {
		return orderNum;
	}

	public void setOrderNum(Integer orderNum) {
		this.orderNum = orderNum;
	}

	public Byte getDelFlag() {
		return delFlag;
	}

	public void setDelFlag(Byte delFlag) {
		this.delFlag = delFlag;
	}

	public List<SysMenu> getChildren() {
		return children;
	}

	public void setChildren(List<SysMenu> children) {
		this.children = children;
	}

	public Integer getLevel() {
		return level;
	}

	public void setLevel(Integer level) {
		this.level = level;
	}

	public String getParentName() {
		return parentName;
	}

	public void setParentName(String parentName) {
		this.parentName = parentName;
	}
	
}

3.3.2、dao

public interface SysMenuMapper {
    int deleteByPrimaryKey(Long id);

    int insert(SysMenu record);

    int insertSelective(SysMenu record);

    SysMenu selectByPrimaryKey(Long id);

    int updateByPrimaryKeySelective(SysMenu record);

    int updateByPrimaryKey(SysMenu record);
    
	List<SysMenu> findPage();

	List<SysMenu> findPageByName(@Param(value="name") String name);
	
	List<SysMenu> findAll();

	List<SysMenu> findByUserName(@Param(value="userName") String userName);
	
	List<SysMenu> findByName(@Param(value="name") String name);
	
	List<SysMenu> findSimpleByName(@Param(value="name") String name);

	List<SysMenu> findRoleMenus(@Param(value="roleId") Long roleId);
	
}

3.3.3、mapper

<?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.***.dao.SysMenuMapper">
  <resultMap id="BaseResultMap" type="com.***.model.SysMenu">
    <id column="id" jdbcType="BIGINT" property="id" />
    <result column="parent_id" jdbcType="BIGINT" property="parentId" />
    <result column="name" jdbcType="VARCHAR" property="name" />
    <result column="url" jdbcType="VARCHAR" property="url" />
    <result column="perms" jdbcType="VARCHAR" property="perms" />
    <result column="type" jdbcType="INTEGER" property="type" />
    <result column="icon" jdbcType="VARCHAR" property="icon" />
    <result column="order_num" jdbcType="INTEGER" property="orderNum" />
    <result column="create_by" jdbcType="BIGINT" property="createBy" />
    <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
    <result column="last_update_by" jdbcType="BIGINT" property="lastUpdateBy" />
    <result column="last_update_time" jdbcType="TIMESTAMP" property="lastUpdateTime" />
    <result column="del_flag" jdbcType="TINYINT" property="delFlag" />
  </resultMap>
  <sql id="Base_Column_List">
    id, parent_id, name, url, perms, type, icon, order_num, create_by, create_time, 
    last_update_by, last_update_time, del_flag
  </sql>
  <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
    select 
    <include refid="Base_Column_List" />
    from sys_menu
    where id = #{id,jdbcType=BIGINT}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
    delete from sys_menu
    where id = #{id,jdbcType=BIGINT}
  </delete>
  <insert id="insert" parameterType="com.***.model.SysMenu">
    insert into sys_menu (id, parent_id, name, 
      url, perms, type, icon, 
      order_num, create_by, create_time, 
      last_update_by, last_update_time, del_flag
      )
    values (#{id,jdbcType=BIGINT}, #{parentId,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, 
      #{url,jdbcType=VARCHAR}, #{perms,jdbcType=VARCHAR}, #{type,jdbcType=INTEGER}, #{icon,jdbcType=VARCHAR}, 
      #{orderNum,jdbcType=INTEGER}, #{createBy,jdbcType=BIGINT}, #{createTime,jdbcType=TIMESTAMP}, 
      #{lastUpdateBy,jdbcType=BIGINT}, #{lastUpdateTime,jdbcType=TIMESTAMP}, #{delFlag,jdbcType=TINYINT}
      )
  </insert>
  <insert id="insertSelective" parameterType="com.***.model.SysMenu">
    insert into sys_menu
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
      <if test="parentId != null">
        parent_id,
      </if>
      <if test="name != null">
        name,
      </if>
      <if test="url != null">
        url,
      </if>
      <if test="perms != null">
        perms,
      </if>
      <if test="type != null">
        type,
      </if>
      <if test="icon != null">
        icon,
      </if>
      <if test="orderNum != null">
        order_num,
      </if>
      <if test="createBy != null">
        create_by,
      </if>
      <if test="createTime != null">
        create_time,
      </if>
      <if test="lastUpdateBy != null">
        last_update_by,
      </if>
      <if test="lastUpdateTime != null">
        last_update_time,
      </if>
      <if test="delFlag != null">
        del_flag,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="id != null">
        #{id,jdbcType=BIGINT},
      </if>
      <if test="parentId != null">
        #{parentId,jdbcType=BIGINT},
      </if>
      <if test="name != null">
        #{name,jdbcType=VARCHAR},
      </if>
      <if test="url != null">
        #{url,jdbcType=VARCHAR},
      </if>
      <if test="perms != null">
        #{perms,jdbcType=VARCHAR},
      </if>
      <if test="type != null">
        #{type,jdbcType=INTEGER},
      </if>
      <if test="icon != null">
        #{icon,jdbcType=VARCHAR},
      </if>
      <if test="orderNum != null">
        #{orderNum,jdbcType=INTEGER},
      </if>
      <if test="createBy != null">
        #{createBy,jdbcType=BIGINT},
      </if>
      <if test="createTime != null">
        #{createTime,jdbcType=TIMESTAMP},
      </if>
      <if test="lastUpdateBy != null">
        #{lastUpdateBy,jdbcType=BIGINT},
      </if>
      <if test="lastUpdateTime != null">
        #{lastUpdateTime,jdbcType=TIMESTAMP},
      </if>
      <if test="delFlag != null">
        #{delFlag,jdbcType=TINYINT},
      </if>
    </trim>
  </insert>
  <update id="updateByPrimaryKeySelective" parameterType="com.***.model.SysMenu">
    update sys_menu
    <set>
      <if test="parentId != null">
        parent_id = #{parentId,jdbcType=BIGINT},
      </if>
      <if test="name != null">
        name = #{name,jdbcType=VARCHAR},
      </if>
      <if test="url != null">
        url = #{url,jdbcType=VARCHAR},
      </if>
      <if test="perms != null">
        perms = #{perms,jdbcType=VARCHAR},
      </if>
      <if test="type != null">
        type = #{type,jdbcType=INTEGER},
      </if>
      <if test="icon != null">
        icon = #{icon,jdbcType=VARCHAR},
      </if>
      <if test="orderNum != null">
        order_num = #{orderNum,jdbcType=INTEGER},
      </if>
      <if test="createBy != null">
        create_by = #{createBy,jdbcType=BIGINT},
      </if>
      <if test="createTime != null">
        create_time = #{createTime,jdbcType=TIMESTAMP},
      </if>
      <if test="lastUpdateBy != null">
        last_update_by = #{lastUpdateBy,jdbcType=BIGINT},
      </if>
      <if test="lastUpdateTime != null">
        last_update_time = #{lastUpdateTime,jdbcType=TIMESTAMP},
      </if>
      <if test="delFlag != null">
        del_flag = #{delFlag,jdbcType=TINYINT},
      </if>
    </set>
    where id = #{id,jdbcType=BIGINT}
  </update>
  <update id="updateByPrimaryKey" parameterType="com.***.model.SysMenu">
    update sys_menu
    set parent_id = #{parentId,jdbcType=BIGINT},
      name = #{name,jdbcType=VARCHAR},
      url = #{url,jdbcType=VARCHAR},
      perms = #{perms,jdbcType=VARCHAR},
      type = #{type,jdbcType=INTEGER},
      icon = #{icon,jdbcType=VARCHAR},
      order_num = #{orderNum,jdbcType=INTEGER},
      create_by = #{createBy,jdbcType=BIGINT},
      create_time = #{createTime,jdbcType=TIMESTAMP},
      last_update_by = #{lastUpdateBy,jdbcType=BIGINT},
      last_update_time = #{lastUpdateTime,jdbcType=TIMESTAMP},
      del_flag = #{delFlag,jdbcType=TINYINT}
    where id = #{id,jdbcType=BIGINT}
  </update>
  <select id="findAll"  resultMap="BaseResultMap">
    select 
    <include refid="Base_Column_List" />
    from sys_menu
  </select>
  <select id="findPage"  resultMap="BaseResultMap">
    select 
    <include refid="Base_Column_List" />
    from sys_menu
  </select>
  <select id="findPageByName" parameterType="java.lang.String" resultMap="BaseResultMap">
  	<bind name="pattern" value="'%' + _parameter.name + '%'" />
    select 
    <include refid="Base_Column_List" />
    from sys_menu
    where name like #{pattern}
  </select>
  <select id="findByUserName" parameterType="java.lang.String" resultMap="BaseResultMap">
  	select m.* from sys_menu m, sys_user u, sys_user_role ur, sys_role_menu rm
  	where u.name = #{userName,jdbcType=BIGINT} and u.id = ur.user_id 
  	and ur.role_id = rm.role_id and rm.menu_id = m.id
  </select>
  <select id="findByName" parameterType="java.lang.String" resultMap="BaseResultMap">
  	select m.* from sys_menu m, sys_user u, sys_user_role ur, sys_role_menu rm
  	where m.name = #{name,jdbcType=VARCHAR} and u.id = ur.user_id 
  	and ur.role_id = rm.role_id and rm.menu_id = m.id
  </select>
  <select id="findSimpleByName" parameterType="java.lang.String" resultMap="BaseResultMap">
  	select m.* from sys_menu m
  	where m.name = #{name,jdbcType=VARCHAR}
  </select>
  <select id="findRoleMenus" parameterType="java.lang.Long" resultMap="BaseResultMap">
    select m.* from sys_menu m, sys_role_menu rm
    where rm.role_id = #{roleId,jdbcType=BIGINT}
    and m.id = rm.menu_id
  </select>
</mapper>

3.3.4、service以及impl

public interface SysMenuService extends CurdService<SysMenu> {

	/**
	 * 查询菜单树,用户ID和用户名为空则查询全部
	 * @param menuType 获取菜单类型,0:获取所有菜单,包含按钮,1:获取所有菜单,不包含按钮
	 * @param userId 
	 * @return
	 */
	List<SysMenu> findTree(String userName, int menuType,String name);

	/**
	 * 根据用户名查找菜单列表
	 * @param userName
	 * @return
	 */
	List<SysMenu> findByUser(String userName, String name);
	
	List<SysMenu> findByName(String name);
}
@Service
public class SysMenuServiceImpl implements SysMenuService {

	@Autowired
	private SysMenuMapper sysMenuMapper;

	@Override
	public int save(SysMenu record) {
		if(record.getId() == null || record.getId() == 0) {
			return sysMenuMapper.insertSelective(record);
		}
		if(record.getParentId() == null) {
			record.setParentId(0L);
		}
		return sysMenuMapper.updateByPrimaryKeySelective(record);
	}

	@Override
	public int delete(SysMenu record) {
		return sysMenuMapper.deleteByPrimaryKey(record.getId());
	}

	@Override
	public int delete(List<SysMenu> records) {
		for(SysMenu record:records) {
			delete(record);
		}
		return 1;
	}

	@Override
	public SysMenu findById(Long id) {
		return sysMenuMapper.selectByPrimaryKey(id);
	}

	@Override
	public PageResult findPage(PageRequest pageRequest) {
		return MybatisPageHelper.findPage(pageRequest, sysMenuMapper);
	}
	
	@Override
	public List<SysMenu> findTree(String userName, int menuType,String name) {
		List<SysMenu> sysMenus = new ArrayList<>();
		List<SysMenu> menus = findByUser(userName,name);
		for (SysMenu menu : menus) {
			if (menu.getParentId() == null || menu.getParentId() == 0) {
				menu.setLevel(0);
				if(!exists(sysMenus, menu)) {
					sysMenus.add(menu);
				}
			}
		}
		sysMenus.sort((o1, o2) -> o1.getOrderNum().compareTo(o2.getOrderNum()));
		findChildren(sysMenus, menus, menuType);
		return sysMenus;
	}

	@Override
	public List<SysMenu> findByUser(String userName, String name) {
		if(!StringUtils.isBlank(name)) {
			return sysMenuMapper.findByName(name);
		}
		if(userName == null || "".equals(userName) || SysConstants.ADMIN.equalsIgnoreCase(userName)) {
			return sysMenuMapper.findAll();
		}
		return sysMenuMapper.findByUserName(userName);
	}

	private void findChildren(List<SysMenu> SysMenus, List<SysMenu> menus, int menuType) {
		for (SysMenu SysMenu : SysMenus) {
			List<SysMenu> children = new ArrayList<>();
			for (SysMenu menu : menus) {
				if(menuType == 1 && menu.getType() == 2) {
					// 如果是获取类型不需要按钮,且菜单类型是按钮的,直接过滤掉
					continue ;
				}
				if (SysMenu.getId() != null && SysMenu.getId().equals(menu.getParentId())) {
					menu.setParentName(SysMenu.getName());
					menu.setLevel(SysMenu.getLevel() + 1);
					if(!exists(children, menu)) {
						children.add(menu);
					}
				}
			}
			SysMenu.setChildren(children);
			children.sort((o1, o2) -> o1.getOrderNum().compareTo(o2.getOrderNum()));
			findChildren(children, menus, menuType);
		}
	}

	private boolean exists(List<SysMenu> sysMenus, SysMenu sysMenu) {
		boolean exist = false;
		for(SysMenu menu:sysMenus) {
			if(menu.getId().equals(sysMenu.getId())) {
				exist = true;
			}
		}
		return exist;
	}

	@Override
	public List<SysMenu> findByName(String name) {
		return sysMenuMapper.findSimpleByName(name);
	}
	
}

 这里查找树形菜单时使用了递归的方法。

重点方法:findTree、findChildren

3.4、用户角色

3.4.1、model

public class SysUserRole extends BaseModel {

    private Long userId;

    private Long roleId;

	public Long getUserId() {
		return userId;
	}

	public void setUserId(Long userId) {
		this.userId = userId;
	}

	public Long getRoleId() {
		return roleId;
	}

	public void setRoleId(Long roleId) {
		this.roleId = roleId;
	}

}

3.4.2、dao

public interface SysUserRoleMapper {
    int deleteByPrimaryKey(Long id);

    int insert(SysUserRole record);

    int insertSelective(SysUserRole record);

    SysUserRole selectByPrimaryKey(Long id);

    int updateByPrimaryKeySelective(SysUserRole record);

    int updateByPrimaryKey(SysUserRole record);

	List<SysUserRole> findUserRoles(@Param(value="userId") Long userId);

	int deleteByUserId(@Param(value="userId") Long userId);
}

3.4.3、mapper

<?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.***.dao.SysUserRoleMapper">
  <resultMap id="BaseResultMap" type="com.***.model.SysUserRole">
    <id column="id" jdbcType="BIGINT" property="id" />
    <result column="user_id" jdbcType="BIGINT" property="userId" />
    <result column="role_id" jdbcType="BIGINT" property="roleId" />
  </resultMap>
  <sql id="Base_Column_List">
    id, user_id, role_id
  </sql>
  <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
    select 
    <include refid="Base_Column_List" />
    from sys_user_role
    where id = #{id,jdbcType=BIGINT}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
    delete from sys_user_role
    where id = #{id,jdbcType=BIGINT}
  </delete>
  <insert id="insert" parameterType="com.***.model.SysUserRole">
    insert into sys_user_role (id, user_id, role_id
      )
    values (#{id,jdbcType=BIGINT}, #{userId,jdbcType=BIGINT}, #{roleId,jdbcType=BIGINT}
      )
  </insert>
  <insert id="insertSelective" parameterType="com.***.model.SysUserRole">
    insert into sys_user_role
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
      <if test="userId != null">
        user_id,
      </if>
      <if test="roleId != null">
        role_id,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="id != null">
        #{id,jdbcType=BIGINT},
      </if>
      <if test="userId != null">
        #{userId,jdbcType=BIGINT},
      </if>
      <if test="roleId != null">
        #{roleId,jdbcType=BIGINT},
      </if>
    </trim>
  </insert>
  <update id="updateByPrimaryKeySelective" parameterType="com.***.model.SysUserRole">
    update sys_user_role
    <set>
      <if test="userId != null">
        user_id = #{userId,jdbcType=BIGINT},
      </if>
      <if test="roleId != null">
        role_id = #{roleId,jdbcType=BIGINT},
      </if>
    </set>
    where id = #{id,jdbcType=BIGINT}
  </update>
  <update id="updateByPrimaryKey" parameterType="com.***.model.SysUserRole">
    update sys_user_role
    set user_id = #{userId,jdbcType=BIGINT},
      role_id = #{roleId,jdbcType=BIGINT}
    where id = #{id,jdbcType=BIGINT}
  </update>
  <select id="findUserRoles" parameterType="java.lang.Long" resultMap="BaseResultMap">
    select 
    <include refid="Base_Column_List" />
    from sys_user_role
    where user_id = #{userId,jdbcType=BIGINT}
  </select>
  <delete id="deleteByUserId" parameterType="java.lang.Long">
    delete from sys_user_role
    where user_id = #{userId,jdbcType=BIGINT}
  </delete>
</mapper>

3.4.4、service以及impl

详见SysUserService和SysRoleService

3.5、角色菜单

3.5.1、model

public class SysRoleMenu extends BaseModel {

    private Long roleId;

    private Long menuId;

	public Long getRoleId() {
		return roleId;
	}

	public void setRoleId(Long roleId) {
		this.roleId = roleId;
	}

	public Long getMenuId() {
		return menuId;
	}

	public void setMenuId(Long menuId) {
		this.menuId = menuId;
	}

}

3.5.2、dao

public interface SysRoleMenuMapper {
    int deleteByPrimaryKey(Long id);

    int insert(SysRoleMenu record);

    int insertSelective(SysRoleMenu record);

    SysRoleMenu selectByPrimaryKey(Long id);

    int updateByPrimaryKeySelective(SysRoleMenu record);

    int updateByPrimaryKey(SysRoleMenu record);

	List<SysRoleMenu> findRoleMenus(@Param(value="roleId") Long roleId);
	
	List<SysRoleMenu> findAll();

	int deleteByRoleId(@Param(value="roleId") Long roleId);
}

3.5.3、mapper

<?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.***.dao.SysRoleMenuMapper">
  <resultMap id="BaseResultMap" type="com.***.model.SysRoleMenu">
    <id column="id" jdbcType="BIGINT" property="id" />
    <result column="role_id" jdbcType="BIGINT" property="roleId" />
    <result column="menu_id" jdbcType="BIGINT" property="menuId" />
    <result column="create_by" jdbcType="BIGINT" property="createBy" />
    <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
    <result column="last_update_by" jdbcType="BIGINT" property="lastUpdateBy" />
    <result column="last_update_time" jdbcType="TIMESTAMP" property="lastUpdateTime" />
  </resultMap>
  <sql id="Base_Column_List">
    id, role_id, menu_id, create_by, create_time, last_update_by, last_update_time
  </sql>
  <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
    select 
    <include refid="Base_Column_List" />
    from sys_role_menu
    where id = #{id,jdbcType=BIGINT}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
    delete from sys_role_menu
    where id = #{id,jdbcType=BIGINT}
  </delete>
  <insert id="insert" parameterType="com.***.model.SysRoleMenu">
    insert into sys_role_menu (id, role_id, menu_id, 
      create_by, create_time, last_update_by, 
      last_update_time)
    values (#{id,jdbcType=BIGINT}, #{roleId,jdbcType=BIGINT}, #{menuId,jdbcType=BIGINT}, 
      #{createBy,jdbcType=BIGINT}, #{createTime,jdbcType=TIMESTAMP}, #{lastUpdateBy,jdbcType=BIGINT}, 
      #{lastUpdateTime,jdbcType=TIMESTAMP})
  </insert>
  <insert id="insertSelective" parameterType="com.***.model.SysRoleMenu">
    insert into sys_role_menu
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
      <if test="roleId != null">
        role_id,
      </if>
      <if test="menuId != null">
        menu_id,
      </if>
      <if test="createBy != null">
        create_by,
      </if>
      <if test="createTime != null">
        create_time,
      </if>
      <if test="lastUpdateBy != null">
        last_update_by,
      </if>
      <if test="lastUpdateTime != null">
        last_update_time,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="id != null">
        #{id,jdbcType=BIGINT},
      </if>
      <if test="roleId != null">
        #{roleId,jdbcType=BIGINT},
      </if>
      <if test="menuId != null">
        #{menuId,jdbcType=BIGINT},
      </if>
      <if test="createBy != null">
        #{createBy,jdbcType=BIGINT},
      </if>
      <if test="createTime != null">
        #{createTime,jdbcType=TIMESTAMP},
      </if>
      <if test="lastUpdateBy != null">
        #{lastUpdateBy,jdbcType=BIGINT},
      </if>
      <if test="lastUpdateTime != null">
        #{lastUpdateTime,jdbcType=TIMESTAMP},
      </if>
    </trim>
  </insert>
  <update id="updateByPrimaryKeySelective" parameterType="com.***.model.SysRoleMenu">
    update sys_role_menu
    <set>
      <if test="roleId != null">
        role_id = #{roleId,jdbcType=BIGINT},
      </if>
      <if test="menuId != null">
        menu_id = #{menuId,jdbcType=BIGINT},
      </if>
      <if test="createBy != null">
        create_by = #{createBy,jdbcType=BIGINT},
      </if>
      <if test="createTime != null">
        create_time = #{createTime,jdbcType=TIMESTAMP},
      </if>
      <if test="lastUpdateBy != null">
        last_update_by = #{lastUpdateBy,jdbcType=BIGINT},
      </if>
      <if test="lastUpdateTime != null">
        last_update_time = #{lastUpdateTime,jdbcType=TIMESTAMP},
      </if>
    </set>
    where id = #{id,jdbcType=BIGINT}
  </update>
  <update id="updateByPrimaryKey" parameterType="com.***.model.SysRoleMenu">
    update sys_role_menu
    set role_id = #{roleId,jdbcType=BIGINT},
      menu_id = #{menuId,jdbcType=BIGINT},
      create_by = #{createBy,jdbcType=BIGINT},
      create_time = #{createTime,jdbcType=TIMESTAMP},
      last_update_by = #{lastUpdateBy,jdbcType=BIGINT},
      last_update_time = #{lastUpdateTime,jdbcType=TIMESTAMP}
    where id = #{id,jdbcType=BIGINT}
  </update>
  <select id="findRoleMenus" parameterType="java.lang.Long" resultMap="BaseResultMap">
    select 
    <include refid="Base_Column_List" />
    from sys_role_menu
    where role_id = #{roleId,jdbcType=BIGINT}
  </select>
  <select id="findAll" resultMap="BaseResultMap">
    select 
    <include refid="Base_Column_List" />
    from sys_role_menu
  </select>
  <delete id="deleteByRoleId" parameterType="java.lang.Long">
    delete from sys_role_menu
    where role_id = #{roleId,jdbcType=BIGINT}
  </delete>
</mapper>

3.5.4、service以及impl

详见SysUserService和SysRoleService

4、controller层调用及其他相关

根据用户名查找角色:

//	@RequiresPermissions("sys:user:view")
	@GetMapping(value="/findByName")
	public HttpResult findByUserName(@RequestParam String name) {
		return HttpResult.ok(sysRoleService.findRoleByName(name));
	}

根据角色查找菜单:

	@RequiresPermissions("sys:role:view")
	@GetMapping(value="/findRoleMenus")
	public HttpResult findRoleMenus(@RequestParam Long roleId) {
		return HttpResult.ok(sysRoleService.findRoleMenus(roleId));
	}

(其实都是直接调用service方法,至于方法是干啥的,稍微懂点英文就行了吧 /笑哭/笑哭/笑哭/笑哭)

还有就是,从上面代码也能看到一个注解:@RequiresPermissions,这玩意就是权限,放在库里就是这样:

实现方式是shiro+oauth2,首先写个shiro配置:

@Configuration
public class ShiroConfig {
	
    @Bean
	public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
		ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
		shiroFilter.setSecurityManager(securityManager);
		// 自定义 OAuth2Filter 过滤器,替代默认的过滤器
		Map<String, Filter> filters = new HashMap<>();
		filters.put("oauth2", new OAuth2Filter());
		shiroFilter.setFilters(filters);
		// 访问路径拦截配置,"anon"表示无需验证,未登录也可访问
		Map<String, String> filterMap = new LinkedHashMap<>();
		// 首页和登录页面
		filterMap.put("/", "anon");
		filterMap.put("/login", "anon"); 
        // 图片
        filterMap.put("/images/**", "anon");
        // 其他所有路径交给OAuth2Filter处理
		filterMap.put("/**", "oauth2");
		shiroFilter.setFilterChainDefinitionMap(filterMap);
		return shiroFilter;
	}

    @Bean
	public SecurityManager securityManager(){
	    DefaultWebSecurityManager securityManager =  new DefaultWebSecurityManager();
	    // 注入 Realm 实现类,实现自己的登录逻辑
	    securityManager.setRealm(getShiroRealm());
	    return securityManager;
	}

	@Bean
    public Realm getShiroRealm(){
    	OAuth2Realm myShiroRealm = new OAuth2Realm();
        return myShiroRealm;
    }
	
    /**
     * Shiro生命周期处理器
     */
    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }
    
    /**
     * 开启Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证
     * 配置以下两个bean(DefaultAdvisorAutoProxyCreator(可选)和AuthorizationAttributeSourceAdvisor)即可实现此功能
     */
    @Bean
    @DependsOn({"lifecycleBeanPostProcessor"})
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
        return authorizationAttributeSourceAdvisor;
    }
}

 然后是oauth2三个类:

public class OAuth2Filter extends AuthenticatingFilter {

    @Override
    protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception {
        // 获取请求token
        String token = getRequestToken((HttpServletRequest) request);
        if(StringUtils.isBlank(token)){
            return null;
        }
        return new OAuth2Token(token);
    }

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
    	return false;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
    	HttpServletRequest httpRequest = (HttpServletRequest) request;
    	if("OPTIONS".equals(httpRequest.getMethod())) {
    		// 如果是跨域中复杂请求的预检请求(OPTIONS类型),因为预检请求不带token, 所以不需要验证token
    		 return true;
    	}
        // 获取请求token,如果token不存在,直接返回401
        String token = getRequestToken(httpRequest);
        if(StringUtils.isBlank(token)){
            HttpServletResponse httpResponse = (HttpServletResponse) response;
            httpResponse.setContentType("application/json; charset=utf-8");
            HttpResult result = HttpResult.error(HttpStatus.SC_UNAUTHORIZED, "invalid token");
            String json = JSONObject.toJSONString(result);
			httpResponse.getWriter().print(json);
            return false;
        }
        return executeLogin(request, response);
    }

    @Override
    protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request, ServletResponse response) {
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        httpResponse.setContentType("application/json; charset=utf-8");
        try {
            // 处理登录失败的异常
            Throwable throwable = e.getCause() == null ? e : e.getCause();
            HttpResult result = HttpResult.error(HttpStatus.SC_UNAUTHORIZED, throwable.getMessage());
            String json = JSONObject.toJSONString(result);
            httpResponse.getWriter().print(json);
        } catch (IOException e1) {
        }
        return false;
    }

    /**
     * 获取请求的token
     */
    private String getRequestToken(HttpServletRequest httpRequest){
        // 从header中获取token
        String token = httpRequest.getHeader("token");
        // 如果header中不存在token,则从参数中获取token
        if(StringUtils.isBlank(token)){
            token = httpRequest.getParameter("token");
        }
        return token;
    }

}

 

@Component
public class OAuth2Realm extends AuthorizingRealm {

	@Autowired
	SysUserMapper sysUserMapper;
	@Autowired
	SysMenuMapper sysMenuMapper;
	@Autowired
	SysUserTokenMapper sysUserTokenMapper;
	
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof OAuth2Token;
    }

    /**
     * 授权(接口保护,验证接口调用权限时调用)
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SysUser user = (SysUser)principals.getPrimaryPrincipal();
        // 用户权限列表,根据用户拥有的权限标识与如 @permission标注的接口对比,决定是否可以调用接口
        Set<String> permsSet = findPermissions(user.getName());
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setStringPermissions(permsSet);
        return info;
    }

    /**
     * 认证(登录时调用)
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String token = (String) authenticationToken.getPrincipal();
        // 根据accessToken,查询用户token信息
        SysUserToken sysUserToken = sysUserTokenMapper.findByToken(token);
        if(sysUserToken == null || sysUserToken.getExpireTime().getTime() < System.currentTimeMillis()){
        	// token已经失效
            throw new IncorrectCredentialsException("token失效,请重新登录");
        }
        // 查询用户信息
        SysUser user = sysUserMapper.selectByPrimaryKey(sysUserToken.getUserId());
        // 账号被锁定
        if(user.getStatus() == 0){
            throw new LockedAccountException("账号已被锁定,请联系管理员");
        }
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, token, getName());
        return info;
    }
    
    private Set<String> findPermissions(String userName) {	
		Set<String> perms = new HashSet<>();
		List<SysMenu> sysMenus = findByUser(userName);
		for(SysMenu sysMenu:sysMenus) {
			if(sysMenu.getPerms() != null && !"".equals(sysMenu.getPerms())) {
				perms.add(sysMenu.getPerms());
			}
		}
		return perms;
	}
    
    private List<SysMenu> findByUser(String userName) {
		if(userName == null || "".equals(userName) || SysConstants.ADMIN.equalsIgnoreCase(userName)) {
			return sysMenuMapper.findAll();
		}
		return sysMenuMapper.findByUserName(userName);
	}
}

 

public class OAuth2Token implements AuthenticationToken {
	private static final long serialVersionUID = 1L;
	
	private String token;

    public OAuth2Token(String token){
        this.token = token;
    }

    @Override
    public String getPrincipal() {
        return token;
    }

    @Override
    public Object getCredentials() {
        return token;
    }
}

 到这,基本上就算完工了,告辞!

附:

public class BaseModel {

	private Long id;
	
    private String createBy;

    private Date createTime;

    private String lastUpdateBy;

    private Date lastUpdateTime;

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getCreateBy() {
		return createBy;
	}

	public void setCreateBy(String createBy) {
		this.createBy = createBy;
	}

	public Date getCreateTime() {
		return createTime;
	}

	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}

	public String getLastUpdateBy() {
		return lastUpdateBy;
	}

	public void setLastUpdateBy(String lastUpdateBy) {
		this.lastUpdateBy = lastUpdateBy;
	}

	public Date getLastUpdateTime() {
		return lastUpdateTime;
	}

	public void setLastUpdateTime(Date lastUpdateTime) {
		this.lastUpdateTime = lastUpdateTime;
	}
    
}

 

public interface CurdService<T> {
	
	/**
	 * 保存操作
	 * @param record
	 * @return
	 */
	int save(T record);
	
	/**
	 * 删除操作
	 * @param record
	 * @return
	 */
	int delete(T record);
	
	/**
	 * 批量删除操作
	 * @param entities
	 */
	int delete(List<T> records);
	
	/**
	 * 根据ID查询
	 * @param id
	 * @return
	 */
	T findById(Long id);
	
    /**
     * 分页查询
	 * 这里统一封装了分页请求和结果,避免直接引入具体框架的分页对象, 如MyBatis或JPA的分页对象
	 * 从而避免因为替换ORM框架而导致服务层、控制层的分页接口也需要变动的情况,替换ORM框架也不会
	 * 影响服务层以上的分页接口,起到了解耦的作用
	 * @param pageRequest 自定义,统一分页查询请求
	 * @return PageResult 自定义,统一分页查询结果
     */
	PageResult findPage(PageRequest pageRequest);
	
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章