1.Shiro整合MyBatis
在上一篇博客中,我们为了通过账号+密码认证,直接就在realm中的AuthenticationInfo()中伪造了一个账户+密码,但是真正情况下我们应该从数据库中将数据查询出来,所以这一篇博客我们来整合Shiro+MyBatis,实现一个真正项目中的用户认证功能首先导入依赖
<dependency>
<groupId>mysql
</groupId>
<artifactId>mysql-connector-java
</artifactId>
<version>5.1.47
</version>
</dependency>
<dependency>
<groupId>com.alibaba
</groupId>
<artifactId>druid
</artifactId>
<version>1.1.24
</version>
</dependency>
<dependency>
<groupId>log4j
</groupId>
<artifactId>log4j
</artifactId>
<version>1.2.17
</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot
</groupId>
<artifactId>mybatis-spring-boot-starter
</artifactId>
<version>2.1.3
</version>
</dependency>
配置数据库连接4大参数+spring boot整合Druid数据源
spring:
datasource:
username: root
password: 123
url: jdbc
:mysql
://localhost
:3306/mybatis
?useSSL=false
&useUnicode=true
&characterEncoding=utf
-8
&serverTimezone=Asia/Shanghai
driver-class-name: com.mysql.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
filters: stat
,wall
,log4j
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
spring boot整合mybatis,将mybatis配置写在application中即可
mybatis:
type-aliases-package: com.thhh.pojo
mapper-locations: classpath
:mybatis/mapper/*.xml
创建pojo,创建resource文件夹下的mybatis/mapper/*.xml文件
package com
.thhh
.pojo
;
import lombok
.AllArgsConstructor
;
import lombok
.Data
;
import lombok
.NoArgsConstructor
;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private Integer id
;
private String name
;
private String pwd
;
}
有一个pojo就创建一个mapper/dao
package com
.thhh
.mapper
;
import com
.thhh
.pojo
.User
;
import org
.apache
.ibatis
.annotations
.Mapper
;
import org
.apache
.ibatis
.annotations
.Param
;
import org
.springframework
.stereotype
.Repository
;
import java
.util
.List
;
@Mapper
@Repository
public interface UserMapper {
public User
queryUserByName(@Param("username") String name
);
}
有一个mapper就去编写一个mapper.xml,注意:在spring boot中我们统一将mapper.xml放在resource文件夹下
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.thhh.mapper.UserMapper">
<select id="queryUserByName" resultType="user">
SELECT * FROM mybatis.user
WHERE name = #{username}
</select>
</mapper>
创建service层(完善这个项目的架构)
package com
.thhh
.service
;
import com
.thhh
.pojo
.User
;
public interface UserService {
public User
queryUserByName(String name
);
}
service层的实现
package com
.thhh
.service
;
import com
.thhh
.mapper
.UserMapper
;
import com
.thhh
.pojo
.User
;
import org
.springframework
.beans
.factory
.annotation
.Autowired
;
import org
.springframework
.stereotype
.Service
;
@Service
public class UserServiceImpl implements UserService{
@Autowired
private UserMapper mapper
;
@Override
public User
queryUserByName(String name
) {
return mapper
.queryUserByName(name
);
}
}
在业务足够简单的情况下,我们可以直接在controller层调用mapper/dao层,而省略service层,但是为了项目结构的合理性和可扩展性,我们最好写上service层测试service是否能够成功获取数据
package com
.thhh
;
import com
.thhh
.pojo
.User
;
import com
.thhh
.service
.UserService
;
import org
.junit
.jupiter
.api
.Test
;
import org
.springframework
.beans
.factory
.annotation
.Autowired
;
import org
.springframework
.boot
.test
.context
.SpringBootTest
;
@SpringBootTest
class ShiroSpringbootApplicationTests {
@Autowired
private UserService userService
;
@Test
void contextLoads() {
User user
= userService
.queryUserByName("张三");
System
.err
.println(user
);
}
}
改造上一篇博客中编写的realm获取数据的过程
@Override
protected AuthenticationInfo
doGetAuthenticationInfo(AuthenticationToken token
) throws AuthenticationException
{
System
.out
.println("执行了认证========>doGetAuthenticationInfo");
UsernamePasswordToken usernamePasswordToken
= (UsernamePasswordToken
) token
;
User user
= userService
.queryUserByName(usernamePasswordToken
.getUsername());
if (user
==null
){
return null
;
}
return new SimpleAuthenticationInfo("",user
.getPwd(),"");
}
测试 测试成功!注意:此时我们并没有在realm中伪造数据,我们的数据都是从数据库中查询出来的但是我们在使用spring security的时候,在认证阶段给我们报了一个错误,即强制要求我们将密码进行加密,否则不能正常使用 shiro中也可以对密码进行加密,这里先不展开讲,后面补上