一、数据库准备
1.1、基于“用户-角色-权限”数据模型
1、 用户表(tb_admin)
- id : 主键
- username : 用户名ent
- realname : 真实姓名
- password : 密码 使用MD5+盐加密,后面会详细介绍
- user_status : 用户状态 1为可用,0为不可用
- gender : 性别
- paviate_salt : 盐,用于加密
- tel : 电话
2、 角色表(tb_role)
- id : 主键
- name : 角色名称
- code : 角色代码
- intro : 角色介绍
3、权限表(tb_permission)
- id : 主键
- name : 权限名称
- code : 权限代码
- url : 可跳转url
4、用户-角色中间表(tb_admin_role)
说明:例如一号用户ye是用户管理员
5、角色-权限中间表(tb_role_perm)
说明:2号角色仓库管理员可以有权限表中的12345权限
二、springboot项目创建
2.1、引入依赖
核心依赖
- spring-boot-starter-web
- mysql-connector-java
- spring-boot-starter-data-redis
- spring-boot-starter-test
- lombok
- mybatisplus-spring-boot-starter
- mysql-connector-java
- shiro-spring
- junit-vintage-engine
- commons-lang3
- spring-boot-starter-thymeleaf
- thymeleaf-extras-shiro
- junit
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<!--<version>5.1.36</version>-->
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatisplus-spring-boot-starter</artifactId>
<version>${mybatisplus-starter.version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>${mybatisplus.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.8.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
2.2、domain
实体类创建,只展示用户表(tb_admin)使用@TableName注解作映射
@Data
@TableName("tb_admin")
public class Administrator implements Serializable {
@TableId(type = IdType.AUTO)
private Integer id;
private String username;
private String password;
private String realname;
private String gender;
private String privateSalt; //私有盐,用户密码加密
private String tel;
private String userStatus;
@TableField(exist = false)
private List<Role> roleList;
}
2.3、mapper
主要对数据库的sql语句实现,以用户表(tb_admin)为例
有三种方式
- 注解,在对应方法上使用注解
@Repository
public interface AdministratorMapper extends BaseMapper<Administrator> {
@Select("select distinct r.code" +
" from tb_role r,tb_admin u,tb_admin_role ur" +
" where r.id = ur.role_id and u.id = ur.admin_id and u.username = #{username}")
Set<String> findRolesByUsername(String username);
@Select("select distinct p.code " +
"from tb_role r,tb_admin u,tb_admin_role ur,tb_role_perm rp,tb_permission p " +
"where r.id = ur.role_id and u.id = ur.admin_id and rp.role_id = r.id and rp.perm_id = p.id " +
"and u.username = #{username}")
Set<String> findPermissionsByUsername(String username);
}
- xml 配置
namespace : 指定该xml配置文件的对应的mapper接口类,注意在java和resource包中mapper接口和xml包路径需要一致
<mapper namespace="com.yinfeng.wms.mapper.UserMapper">
<select id="getUserByName" resultType="com.yinfeng.wms.domain.User">
select id,name,password,role from users where name = #{name}
</select>
<select id="getRolesByIds" resultType="com.yinfeng.wms.domain.Role">
select id,role_name,permission from role where id in
<foreach collection="roleIds" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</select>
<select id="getPermissionsByIds" resultType="com.yinfeng.wms.domain.Permissions">
select id,permissions_name from permissions where id in
<foreach collection="permissions" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</select>
<select id="getUserVerifyByName" resultType="com.yinfeng.wms.domain.User">
select id,name,password from users where name = #{name}
</select>
</mapper>
- mapper-plus
//在mapper接口中继承BaseMapper<Administrator>类,里面封装了常用的sql语句
public interface AdministratorMapper extends BaseMapper<Administrator>
在mapper-plus中自带方法
4. service
以用户表为例,首先定义service的接口,在实现接口,目的为了解耦和便于调用
service接口中
@Service
public class AdminServiceImpl implements AdminService {
@Autowired
private AdministratorMapper administratorMapper;
@Override
public List<Administrator> findAll() {
return administratorMapper.selectList(null);
}
@Override
public void deleteById(Integer id) {
administratorMapper.deleteById(id);
}
@Override
public Administrator findUserByUsername(String username) {
Wrapper<Administrator> wrapper = new EntityWrapper<Administrator>();
wrapper.eq("username",username);
List<Administrator> adminList = administratorMapper.selectList(wrapper);//递增
if(adminList != null && adminList.size() > 0){
return adminList.get(0);
}
return null;
}
}
- controller
controller是与前端进行交互,以用户表为例,在前端执行/user/all就执行 findAll()方法
@RestController
@RequestMapping("/user")
public class AdminController {
@Autowired
private AdminService adminService;
@RequestMapping("/all")
public List<Administrator> findAll(){
return adminService.findAll();
}
@RequestMapping("/save")
public String save(Administrator administrator){
adminService.saveAdmin(administrator);
return "OK";
}
}
- 视图
<!DOCTYPE html>
<html lang="en" xmlns:th="https://www.thymeleaf.org/">
<head>
<meta charset="UTF-8">
<title>登录页面</title>
</head>
<body>
<h5 th:text="${errMessage}"></h5>
<form action="/backend/login" method="post">
<input name="username"/><br>
<input name="password"/><br>
<input type="submit" value="登录"/>
</form>
</body>
</html>