本系列文章均參考:朝雨憶輕塵,感謝博主!
這裏還有他的技術交流羣: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來查詢更方便一點。
重點方法:findPermissions、findUserRoles
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);
}