【SpringBoot学习(六)整合 MyBatis、SpringSecurity体验】

整合 MyBatis

在之前不使用SpringBoot时,我们如果想使用 MyBatis来操作数据库需要一系列的准备工作

例如:

  • 写一个工具类

    • 在该工具类中完成 SqlSessionFactory的初始化,使我们能够通过该工具类,直接拿到 sqlSession实例
      • 该实例提供了在数据库执行 SQL 命令所需的所有方法
      • 你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句
  • 配置数据库连接信息

    • 在该文件中 配置你的 driverClassName,数据库 url,及数据库登录信息。
  • 编写 mapper接口

    • 该接口中书写具体的业务逻辑代码
  • 编写 MyBatis核心配置文件

    • 在该文件中 配置环境、配置MyBatis设置、配置别名、 数据库连接、mapper.xml文件映射…
  • 编写 mapper 配置文件

    • 在该文件中 解决实体类映射 接口方法绑定 自定义 sql…

正常情况,我们在完成上面这一系列操作后才可以使用 sqlSession实例封装的 JDBC方法来操作数据库

确实比原生 JDBC要方便一些,且功能更强大更主流

但经过一段时间的 SpringBoot使用后,我不禁觉得(变懒了),这些东西也有点繁琐…

使用 SpringBoot后上述操作,当然大部分是免不了的,但代码量却是大大减少了。

我知道这不一定是好事,毕竟上手门槛变低了 能吸收的东西更少了。


使用SpringBoot后还需要我们手动编写的东西有 :

  • 编写 SpringBoot配置文件

    • 在该文件中绑定 数据库连接信息、MyBatis配置
    • (没错,MyBatis核心配置文件现在要写在 SpringBoot配置文件中了,而且代码量更少)
  • 编写 mapper接口

    • 使用@Mapper@MapperScan注解标记为 MyBatis接口类(Mapper Scan相对于之前的扫描包)
    • 在该接口中编写业务逻辑代码
  • 编写 mapper.xml配置文件(一般不写在 mapper包下了,而是写到resources目录下)

    • 代码没什么变化

写完这些我们就可以直接调用业务方法了。

我们一个一个看

编写mapper接口

// 使用 @Mapper注解标记该接口为 MyBatis mapper接口
@Mapper
@Repository
public interface UserMapper {
    // 编写具体业务逻辑,查询所有用户
    List<User> query();
}

很简单的一个接口,没有什么需要多说的。

你如果不想每个接口都加上 @Mapper注解 ,也可以在SpringBoot主启动类中加上@MapperScan注解,绑定你的mapper包。

@SpringBootApplication
// 扫描该包下的所有接口,并标记为 MyBatis mapper接口
@MapperScan("com.molu.mapper")
public class SqlSpringbootApplication {
    public static void main(String[] args) {
        SpringApplication.run(SqlSpringbootApplication.class, args);
    }
}

两种方法都可以,看个人选择。

编写mapper.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.molu.mapper.UserMapper">

    <select id="query" resultType="User">
        select * from `user`
    </select>
</mapper>

SpringBoot配置文件

# 数据库连接信息
spring:
  datasource:
    username: root
    password: m*******
    # 高版本可能需要设置时区相关
    url: jdbc:mysql://localhost:3306/数据库名?useUnicode=true&characterEncoding=utf-8&useSSL=true
    driver-class-name: com.mysql.cj.jdbc.Driver
# 配置 MyBatis相关
mybatis:
  # 别名
  type-aliases-package: com.molu.pojo
  # mapper.xml映射
  mapper-locations: classpath:mybatis/mapper/*.xml

以上就是全部准备工作了,我们写一个 Controller在里面直接调用mapper接口中的方法,看看是否能够查询到数据库中的所有用户信息。

@RestController
public class UserController {
    @Autowired
    private UserMapper mapper;

    // 绑定查询方法访问路径
    @GetMapping("userList")
    public List<User> queryAll(){
        return mapper.query();
    }
}

访问该路径

【SpringBoot学习(六)整合 MyBatis、SpringSecurity体验】

成功查询到了数据库中的信息,不禁感叹 SpringBoot是真方便真偷懒.......

SpringSecurity初体验

SpringSecurity是针对 Spring项目的安全框架,也是 SpringBoot底层安全模块默认的技术选型。

它可以实现强大的 Web安全控制,让我们不用去写一些拦截器 过滤器的原生代码。

SpringSecurity的两个主要目标是 认证 和授权(访问控制)

我们仅需要引入 Spring-boot-starter-security模块进行少量的配置,即可实现强大的安全管理。

搭建环境

首先是依赖问题,这边只导了 web、security以及 thymeleaf。

这些在创建 SpringBoot项目时都可以勾选,当然你怕它给你导的版本或者兼容性方面存在问题你也可以手动导入。

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring5</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-java8time</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-springsecurity5</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
<!--        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>-->
    </dependencies>

写一个 html页面,该页面比较简陋 能够通过一些 a标签实现不同页面的跳转即可

【SpringBoot学习(六)整合 MyBatis、SpringSecurity体验】

大概是这样一个效果,相信这种页面应该难不倒你

当然了,页面在写完之后我们还需要配置 Controller来控制视图的跳转

@Controller
public class SecurityController {
    // 首页跳转
    @RequestMapping({"/","/index"})
    public String index(){
        return "index";
    }
    // 登录页跳转
    @RequestMapping({"/toLogin"})
    public String toLogin(){
        return "views/login";
    }
    // level1文件夹下不同的 html页面跳转
    @RequestMapping("/level1/{id}")
    // 通过 @PathVariable注解,将 id参数和路径请求的参数绑定
    // 路径请求的参数 可以通过 thymeleaf表达式 @{请求路径/参数} 携带
    public String level1(@PathVariable("id")int id){
        return "views/level1/"+id;
    }
    // 同上
    @RequestMapping("/level2/{id}")
    public String level2(@PathVariable("id")int id){
        return "views/level2/"+id;
    }
    // 同上
    @RequestMapping("/level3/{id}")
    public String level3(@PathVariable("id")int id){
        return "views/level3/"+id;
    }
}

这里有一点需要注意,好像高版本的 SpringSecurity会在你访问 localhost:8080 的时候,强制你登录

【SpringBoot学习(六)整合 MyBatis、SpringSecurity体验】

为了方便测试你可以先把 SpringSecurity相关的依赖注掉

当然了,如果你不嫌麻烦 在测试时也可以每次都登录一遍嘛 ~

SpringSecurity默认的用户名为 “User”,密码为 项目启动成功后,控制台中返回的字符串。

【SpringBoot学习(六)整合 MyBatis、SpringSecurity体验】

编写配置

环境搭建完毕后,准备动手写 SpringSecurity的配置了

和 拦截器类似,我们不需要改动原先的代码 可以以横切的方式配置 SpringSecurity。

在 SpringSecurity的包中也能看到导入了 aop相关的依赖

SpringSecurity的配置很简单,我们只需要写一个 Config来继承 WebSecurityConfigurerAdapter 并添加注解重写对应的方法即可。

骨架:

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        super.configure(auth);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
    }
}

默认配置设定了所有 HTTP请求, 都需要进行认证。

所以我们在访问localhost:8080的时候也会被拦截,但是实际情况下 有一些页面是可以被任何人访问的,例如首页。

或者自定义的登陆的等页面,这时候需要用自己定义一些用户授权的规则

可以在 参数为 HttpSecurity的 config方法中配置授权规则

@Override
protected void configure(HttpSecurity http) throws Exception {
    // 为 首页设置授权规则,规则为所有人都能访问
    http.authorizeRequests().antMatchers("/").permitAll();
}
  • 以下为 常用授权规则方法
    • permitAll():允许所有人访问
    • denyAll():拒绝所有访问
    • anonymous():允许匿名用户访问
    • authenticated():允许认证的用户进行访问
    • hasRole(String) :如果用户具备给定角色(用户组)的话,就允许访问
    • hasAnyRole(String…) :如果用户具有给定角色(用户组)中的一个的话,允许访问
    • rememberMe() :如果用户是通过Remember-me功能认证的,就允许访问
    • fullyAuthenticated():如果用户是完整认证的话(不是通过Remember-me功能认证的),就允许访问
    • hasAuthority(String):如果用户具备给定权限的话就允许访问
    • hasAnyAuthority(String…) :如果用户具备给定权限中的某一个的话,就允许访问
    • hasIpAddress(String):如果请求来自给定ip地址的话,就允许访问
    • not() :对其他访问结果取反

写完这一行授权规则后,我们重启服务器 再次访问 localhost:8080

【SpringBoot学习(六)整合 MyBatis、SpringSecurity体验】

确认授权生效后,我们继续往下完善授权规则。

    @Override
    protected void configure(HttpSecurity http) throws Exception {
       
        http.authorizeRequests()
             	// 为首页设置授权规则,规则为所有人都能访问
                .antMatchers("/").permitAll()
                // 角色为游客只能访问 level1下的所有页面
                .antMatchers("/level1/**").permitAll()
                // 角色为注册用户可以访问 level2下的所有页面
                .antMatchers("/level2/**").hasRole("logged")
                // 角色为管理员可以访问 level3下的所有页面
                .antMatchers("/level3/**").hasRole("admin");
    }
}

权限方面就搞定了,现在想要访问 首页下的某些路径,必须在登陆时 拿到特定的角色获得对应的权限。否则均无法访问

【SpringBoot学习(六)整合 MyBatis、SpringSecurity体验】

正常情况,应该在权限不够时跳转到登录页面才是 而不是跳转到 403页面

该功能需要我们手动开启,开启方式也很简单。

// 配置没有权限时的登录跳转
http.formLogin();

重启服务器,现在如果访问首页下的路径 在没有权限时会让你登录而不是给你跳到 403

好了 现在要你登录了 ,一般这种登录操作都应该涉及数据库。

但除了将登录信息放在数据库中 SpringSecurity还提供了从内存中获取登录信息的功能。

这就需要用到参数为 AuthenticationManagerBuilder的另一个 config方法了。

使用该方法来在内存中模拟一些用户登录信息,并认证。

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
            // 配置已登录用户信息及角色认证
            // 可以存在多个 使用 .and()方法连接即可
            .withUser("molu").password("*******").roles("logged").and()
            // 配置管理员登录信息及角色认证
            .withUser("admin").password("admin123").roles("logged","admin");
}

有了用户登录信息,我们就可以在 SpringSecurity重定向的 /login页面进行登录操作了。

但尝试登录后,我们有会碰到另一个问题

【SpringBoot学习(六)整合 MyBatis、SpringSecurity体验】

500错误,原因是 SpringSecurity认为你设置的密码 没有经过加密,是不安全的…

那没办法了,照它说的来 我们需要设置加密方式,为密码加密

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication()
            // 设置加密方式
            .passwordEncoder(new BCryptPasswordEncoder())
            .withUser("molu").password
            // 为 'molu'用户的密码加密
            (new BCryptPasswordEncoder().encode("******")).roles("logged").and()
            .withUser("admin").password
            // 为管理员用户的密码加密
            (new BCryptPasswordEncoder().encode("admin123")).roles("logged","admin");
}

测试效果

SpringSecurity配置都完善后,我们看看效果

【SpringBoot学习(六)整合 MyBatis、SpringSecurity体验】

没问题,以上为 SpringSecurity初体验的全部内容。


放松一下眼睛

【SpringBoot学习(六)整合 MyBatis、SpringSecurity体验】

原图P站地址

画师主页


上一篇:SpringSecurity(二): 自定义登录页面


下一篇:SpringSecurity