业务描述
- 角色添加页面
- 角色修改页面
表设计
@Data
public class SysRole implements Serializable {
private static final long serialVersionUID = 3232155697809432339L;
//角色ID
private Integer id;
//角色名称
private String name;
//菜单ID
private List
<a name="PftZB"></a>
### Dao层
- Dao层接口
```java
package com.cy.pj.sys.dao;
/**创建角色数据逻辑访问对象,基于此对象访问数据库中角色相关数据*/
@Mapper
public interface SysRoleDao {
/**
* 基于条件查询角色信息
* @param:role封装了查询条件的对象
* @return 查询到的结果
*/
List<SysRole> selectRoles(SysRole entity);
/**
* 基于id查找对应的角色,因为修改的时候需要先对这行记录查询出来,在原有的基础上修改
* @param id 角色id
* @return 查找到具体角色对象
*/
SysRole selectById(Integer id);
/**
* 向表中新增一条角色信息
* @param entity 封装了要新增的角色信息的对象
* @return 新增的行数
*/
int insertRole(SysRole entity);
/**
* 基于角色id更新角色信息
* @param entity 封装了要新增的角色信息的对象
* @return 更新的行数
*/
int updateRole(SysRole entity);
/**
* 查询角色id和角色name,
* 每行记录封装为一个CheckBox对象,(复选框的信息展示)
* 后续在为用户分配角色时会用到。
* @return
*/
@Select("select id,name from sys_roles")
List<CheckBox> selectCheckRoles();
}
<?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.cy.pj.sys.dao.SysRoleDao">
<select id="selectRoles" resultType="com.cy.pj.sys.pojo.SysRole">
select id,name,remark,createdTime,modifiedTime,createdUser,modifiedUser
from sys_roles
<where>
<if test="name!=null and name!=''">
name like concat("%",#{name},"%")
</if>
</where>
order by createdTime desc
</select>
<!--
1)useGeneratedKeys="true" 表示获取insert操作时写入到数据库的自增主键值
2)keyProperty="id" 将自增主键值赋值给参数对象的id属性,获得id用于写入角色和菜单关系的数据逻辑层操作,SysRoleMenuMapper.xml
-->
<insert id="insertRole" parameterType="com.cy.pj.sys.pojo.SysRole"
useGeneratedKeys="true"
keyProperty="id">
insert into sys_roles
(name,remark,createdTime,modifiedTime,createdUser,modifiedUser)
values
(#{name},#{remark},now(),now(),#{createdUser},#{modifiedUser})
</insert>
<!--基于id查询角色以及角色对应的菜单信息,多个菜单用集合Collection接收,假如是对象用association接收
resultMap是mybatis中提供的高级映射元素,应用场景:
1)表中字段名与类中属性名不匹配时
2)多表关联查询映射
3)多表嵌套查询映射-->
<resultMap id="roleMenu" type="com.cy.pj.sys.pojo.SysRole">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="remark" column="remark"/>
<collection property="menuIds" ofType="integer">
<result column="menu_id" />
</collection>
</resultMap>
<select id="selectById" resultMap="roleMenu">
select r.id,r.name,r.remark,rm.menu_id
from sys_roles r
left join sys_role_menus rm
on r.id=rm.role_id
where r.id=#{id}
</select>
<update id="updateRole">
update sys_roles
set name = #{name},
remark = #{remark},
modifiedTime = now(),
modifiedUser = #{modifiedUser}
where id=#{id}
</update>
</mapper>
- 角色菜单关系数据 ```java package com.cy.pj.sys.dao;
@Mapper public interface SysRoleMenuDao { /**
* 新增角色菜单关系数据
* @param roleId
* @param menuIds
* @return
*/
int insertRoleMenus(Integer roleId, List<Integer> menuIds);
/**
* 基于角色id删除角色和菜单关系数据
* @param roleId 角色id
* @return 删除的行数
*/
@Delete("delete from sys_role_menus where role_id=#{role_id}")
int deleteByRoleId(Integer roleId);
}
```xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cy.pj.sys.dao.SysRoleMenuDao">
<!--写入角色和菜单关系数据-->
<insert id="insertRoleMenus">
insert into
sys_role_menus(role_id,menu_id)
values <!--(1,2),(1,3),(1,4)-->
<foreach collection="menuIds" separator="," item="menuId">
(#{roleId},#{menuId})
</foreach>
</insert>
</mapper>
Service层
- 接口规范定义
- 通过原型设计找到项目需要完成的业务,来进行业务层的规范定义
```java package com.cy.pj.sys.service;
- 通过原型设计找到项目需要完成的业务,来进行业务层的规范定义
/**
定义角色业务规范 / public interface SysRoleService { /*
- 基于条件查询角色信息
- @param entity 封装了查询条件的对象
@return */ List
findRoles(SysRole entity); /**
- 添加角色
- @param entity 封装了角色信息的对象
@return 受影响的行数 */ int saveRole(SysRole entity);
/**
- 基于角色id查询角色以及角色对应菜单关系数据,将数据呈现出来用于更新
- @param id
@return */ SysRole findById(Integer id);
/**
- 基于角色id更新角色以及角色对应的菜单关系数据
- @param entity
@return */ int updateRole(SysRole entity);
/**
- 为用户授权时,查询可授权的角色
- @return
*/
List
findCheckRoles(); } ```
- 接口实现
- 在实际业务中,一些操作要么都执行,要么不执行,就需要事务控制
- 在更新角色时,角色菜单关系(一对多)数据的更新一般通过先删除原有关系后添加关系来完成 ```java package com.cy.pj.sys.service.impl;
@Service public class SysRoleServiceImpl implements SysRoleService { /关联角色表dao对象*/ @Autowired private SysRoleDao sysRoleDao; /关联角色菜单关系表dao对象*/ @Autowired private SysRoleMenuDao sysRoleMenuDao;
@Override
public List<SysRole> findRoles(SysRole entity) {
return sysRoleDao.selectRoles(entity);
}
/**
* 保存角色以及角色菜单关系数据(思考如何保证数据的完整性)
* @param entity 封装了要新增的角色信息
* @return
*/
@Override
public int saveRole(SysRole entity) {
//保存角色自身信息
int rows = sysRoleDao.insertRole(entity);
//保存角色菜单关系数据
sysRoleMenuDao.insertRoleMenus(entity.getId(), entity.getMenuIds());
return rows;
}
@Override
public SysRole findById(Integer id) {
return sysRoleDao.selectById(id);
}
@Override
public int updateRole(SysRole entity) {
//更新角色自身信息
int rows = sysRoleDao.updateRole(entity);
if (rows==0){
throw new ServiceException("记录可能已经不存在了");
}
//更新角色菜单关系数据(one to many数据更新一般是先删除原有关系,再添加新的关系)
sysRoleMenuDao.deleteByRoleId(entity.getId());
sysRoleMenuDao.insertRoleMenus(entity.getId(), entity.getMenuIds());
return rows;
}
@Override
public List<CheckBox> findCheckRoles() {
return sysRoleDao.selectCheckRoles();
}
}
<a name="rNxyx"></a>
### Controller层
```java
package com.cy.pj.sys.web.controller;
@RequestMapping("/role/")
@RestController
public class SysRoleController {
@Autowired
private SysRoleService sysRoleService;
@GetMapping
public JsonResult doFindRoles(SysRole entity) {
return new JsonResult(PageUtil.startPage().doSelectPageInfo(()->{
sysRoleService.findRoles(entity);
}));
}
@PostMapping
public JsonResult doSaveRole(@RequestBody SysRole entity){
sysRoleService.saveRole(entity);
return new JsonResult("save ok");
}
@GetMapping("{id}")
public JsonResult doFindById(@PathVariable Integer id){
return new JsonResult(sysRoleService.findById(id));
}
@PutMapping
public JsonResult doUpdateRole(@RequestBody SysRole entity){
sysRoleService.updateRole(entity);
return new JsonResult("update ok");
}
@GetMapping("checkRoles")
public JsonResult doFindCheckRoles(){
return new JsonResult(sysRoleService.findCheckRoles());
}
}
Main
package com.cy;
@EnableCaching //启动springboot工程中内置缓存
@SpringBootApplication
public class AdminApplication {
public static void main(String[] args) {
SpringApplication.run(AdminApplication.class,args);
}
}