1、修改pom.xml文件,引入相关依赖。主要的依赖有mybatis、数据库驱动(我这里用的是access数据库,所以引入ucanaccess依赖,其他数据库应相应修改)、Spring security、fastjson(用于操作json)。所有依赖如下:
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>net.sf.ucanaccess</groupId> <artifactId>ucanaccess</artifactId> <version>5.0.1</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.7.0</version> </dependency> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.41</version> </dependency> </dependencies>
2、配置application.properties,在main/resources文件夹中创建或修改application.properties文件,写入数据库配置和mybatis配置,如下。第一行是数据库驱动。第二行是数据库地址。第三行是数据库密码,根据数据库类型,可能还需要配置数据库用户名。第四行是mybatis的mapper位置,其中的mappers/*.xml需要按照自己需要配置,此处我是在main/resources文件夹下建了一个mappers文件夹,所有与mybatis相关的.xml文件都放在这个文件夹里,程序编译后会在target/classes文件下生成mappers文件夹,这些xml文件也被导入,因此这里的路径写classpath:mappers/*.xml。最后一行是防止数据空值时出错,可以删除该行。
spring.datasource.driver-class-name = net.ucanaccess.jdbc.UcanaccessDriver
spring.datasource.url = jdbc:ucanaccess://D:/mybatis/test.mdb;openExclusive=false;ignoreCase
spring.datasource.password = 123456
mybatis.mapper-locations=classpath:mappers/*.xml
mybatis.configuration.call-setters-on-nulls=true
3、创建实体,按照上一篇的数据库结构设计,设计了五个数据表,但这里只需要建三个实体即可,即User、Role、Menu。代码分别如下。
public class User implements UserDetails{ /** * */ private static final long serialVersionUID = 1L; private String id; private String username; private String realname; private String email; private String password; private Boolean enabled; private Boolean accountNonExpired; private Boolean accountNonLocked; private Boolean credentialsNonExpired; List <Role> roles=new ArrayList<> (); @Override public String toString() { return "User{" + "id=" + id + ", username=‘" + username + ‘\‘‘ + ", password=‘" + password + ‘\‘‘ + ", enabled=" + enabled + ", accountNonExpired=" + accountNonExpired + ", accountNonLocked=" + accountNonLocked + ", credentialsNonExpired=" + credentialsNonExpired + ", roles=" + roles + ‘}‘; } @Override public Collection <? extends GrantedAuthority> getAuthorities(){ List <SimpleGrantedAuthority> authorities = new ArrayList<> (); for(Role role : roles) { authorities.add(new SimpleGrantedAuthority(role.getNameEn())); } return authorities; } @Override public boolean isAccountNonExpired() { return accountNonExpired; } @Override public boolean isAccountNonLocked() { return accountNonLocked; } @Override public boolean isCredentialsNonExpired() { return credentialsNonExpired; } @Override public boolean isEnabled() { return enabled; } public String getRealname() { return realname; } public void setRealname(String realname) { this.realname = realname; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public void setEnabled(Boolean enabled) { this.enabled = enabled; } public void setAccountNonExpired(Boolean accountNonExpired) { this.accountNonExpired = accountNonExpired; } public void setAccountNonLocked(Boolean accountNonLocked) { this.accountNonLocked = accountNonLocked; } public void setCredentialsNonExpired(Boolean credentialsNonExpired) { this.credentialsNonExpired = credentialsNonExpired; } public List<Role> getRoles() { return roles; } public void setRoles(List<Role> roles) { this.roles = roles; } @Override public boolean equals(Object obj) { if (obj instanceof User) { return this.username.equals(((User) obj).username); } return false; } @Override public int hashCode() { return this.username.hashCode(); } }
public class Menu { private Integer id; private String pattern; private List<Role> roles; public List<Role> getRoles() { return roles; } public void setRoles(List<Role> roles) { this.roles = roles; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getPattern() { return pattern; } public void setPattern(String pattern) { this.pattern = pattern; } }
public class Role { private String id; private String nameEn; private String nameZh; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getNameEn() { return nameEn; } public void setNameEn(String nameEn) { this.nameEn = nameEn; } public String getNameZh() { return nameZh; } public void setNameZh(String nameZh) { this.nameZh = nameZh; } }
这里面Role和Menu都很容易理解,在User实体中有两处代码需要注意:下面这段代码是指根据Role的英文名得到用户的权限信息,因为我在这里把权限和角色统一了,不再区分,所以增加了这段代码:
@Override public Collection <? extends GrantedAuthority> getAuthorities(){ List <SimpleGrantedAuthority> authorities = new ArrayList<> (); for(Role role : roles) { authorities.add(new SimpleGrantedAuthority(role.getNameEn())); } return authorities; }
在User实体中还需要注意,其中的enabled、accountNonExpired、accountNonLocked、credentialsNonExpired这几个字段使用isXXX()这样的方法,而不是用getXXX()这样的方法。
4、创建两个接口UserRepository和MenuRepository。代码如下:
@Mapper public interface UserRepository { public List <User> getAllUser(); public User getUserByUsername(String username); public List<Role> getRolesByUid(String id); }
@Mapper public interface MenuRepository { List <Menu> getAllMenu(); }
5、在mappers文件夹里创建MenuMapper.xml和UserMapper.xml,当然也可以只创建一个,把代码都写在一起。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.repository.MenuRepository"> <resultMap id="MenuResultMap" type="com.entity.Menu"> <id property="id" column="id" /> <result property="pattern" column="pattern"></result> <collection property="roles" ofType="com.entity.Role"> <id column="rid" property="id"/> <result column="rnameEn" property="nameEn" /> <result column="rnameZh" property="nameZh" /> </collection> </resultMap> <select id="getAllMenu" resultMap="MenuResultMap"> select m.*, r.id as rid, r.nameEn as rnameEn, r.nameZh as rnameZh from [menu] m left join [menu_role] mr on m.`ID`=mr.`mid` left join [role] r on r.`id`=mr.`rid` </select> </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.repository.UserRepository"> <!-- 获取所有用户 --> <select id="getAllUser" resultType="com.entity.User"> select * from [user] </select> <!-- 根据用户名查找用户 --> <select id="getUserByUsername" resultType="com.entity.User"> select * from [user] where username=#{username} </select> <!-- 根据id选择角色 --> <select id="getRolesByUid" resultType="com.entity.Role"> select r.* from [role]r,[user_role]ur where (ur.`uid`=#{id} and r.`id`=ur.`rid`) </select> </mapper>
MenuMapper.xml里的代码较难理解,主要是要理解两次用left join,多表联合查询,得到的结果为一个resultMap,在这个resultMap中,部分数据来自Menu实体,部分数据来自Role实体,其中的column是指实体中的字段(不是指数据库),property是指查询语句中select和from之间的字段名称,有as的按照as后的名称,没有as的话就按照数据库中的原字段名称。
前后端分离的Web应用程序中使用Spring Security+Mybatis+JWT非对称加密+动态权限管理(二):配置参数、创建实体和接口
原文:https://www.cnblogs.com/wwwzgy/p/14808022.html