前言
上一次我们实现了SpringSecurity的前后端分离,这次我们把里面的内存数据源改成数据库。
一、整合mybatis
1、pom.xml里面引入jar包
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot.</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
2、application配置文件
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name: com.mysql.jdbc.Driver
spring.datasource.url: jdbc:mysql://localhost:3306/security?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
spring.datasource.username: root
spring.datasource.password: yuanyuan
mybatis.mapper-locations= classpath:mapper/*.xml
mybatis.type-aliases-package=com.spring.security/entity
logging.level.com.spring.security=debug
3、业务代码
1、mapper.xml代码如下:
<mapper namespace="com.spring.security2.dao.UserDao">
<select id="loaduserbyusername" resultType="com.spring.security2.entity.User">
select id,username,password,enabled,accountNonExpired,accountNonLocked,credentialsNonExpired
from user where username=#{username}
</select>
<select id="getrolebyuserid" resultType="com.spring.security2.entity.Role">
select a.id,a.name,a.name_zh
from role a
left join user_role b on a.id=b.rid
where b.uid=#{uid}
</select>
</mapper>
2、dao层代码如下:
@Mapper
public interface UserDao {
User loaduserbyusername(String name);
List<Role> getrolebyuserid(int uid);
}
3、service代码如下:
@Service
public class UserServiceImpl implements UserDetailsService {
@Autowired
private UserDao userDao;
@Override
public UserDetails loadUserByUsername(String name) {
User user = userDao.loaduserbyusername(name);
if(ObjectUtils.isEmpty(user)){
throw new UsernameNotFoundException("用户名不正确");
}else{
user.setList(userDao.getrolebyuserid(user.getId()));
}
return user;
}
}
这里UserServiceImpl 要实现UserDetailsService 接口,因为我们要用我们自定义的
UserServiceImpl 代替之前的InMemoryUserDetailsManager,
InMemoryUserDetailsManager也是实现的UserDetailsService 。
4、实体类,代码如下:
public class User implements Serializable,UserDetails {
private static final long serialVersionUID = 1L;
private int id;
private String username;
private String password;
private boolean accountNonExpired;
private boolean accountNonLocked;
private boolean credentialsNonExpired;
private boolean enabled;
private List<Role> list = new ArrayList<>();
public Collection<GrantedAuthority> getAuthorities() {
Set authorities = new HashSet();
list.forEach(role->{
SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(role.getName());
authorities.add(simpleGrantedAuthority);
});
return authorities;
}
public int getId() {
return id;
}
public void setId(int 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 boolean isAccountNonExpired() {
return accountNonExpired;
}
public void setAccountNonExpired(boolean accountNonExpired) {
this.accountNonExpired = accountNonExpired;
}
public boolean isAccountNonLocked() {
return accountNonLocked;
}
public void setAccountNonLocked(boolean accountNonLocked) {
this.accountNonLocked = accountNonLocked;
}
public boolean isCredentialsNonExpired() {
return credentialsNonExpired;
}
public void setCredentialsNonExpired(boolean credentialsNonExpired) {
this.credentialsNonExpired = credentialsNonExpired;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public List<Role> getList() {
return list;
}
public void setList(List<Role> list) {
this.list = list;
}
}
实体类继承UserDetails
public class Role implements Serializable {
private static final long serialVersionUID = 1L;
private int id;
private String name;
private String nameZh;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNameZh() {
return nameZh;
}
public void setNameZh(String nameZh) {
this.nameZh = nameZh;
}
}
public class UserRole implements Serializable {
private static final long serialVersionUID = 1L;
private int id;
private int uid;
private int rid;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public int getRid() {
return rid;
}
public void setRid(int rid) {
this.rid = rid;
}
}
5、数据库
4、Security配置
引入我们自定义的UserServiceImpl ,并把auth.userDetailsService(userDetailService())替换成auth.userDetailsService(userServiceImpl)
代码如下:
@Autowired
private UserServiceImpl userServiceImpl;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userServiceImpl);
}
二、测试
可以看到把数据源改成数据库成功了
总结
改完了数据库,下次就该到验证码了,毕竟我们登录都是有验证码的。
完整代码地址:https://pan.baidu.com/s/1EPlg81uW0hbCQBGRkrjJow
提取码:xxgz
我的个人博客地址:http://www.dbhx.vip