Spring Boot

SpringBoot是一个快速开发框架,可以迅速搭建一套基于Spring框架体系的应用,是SpringCloud的基础。

SpringBoot开启了各种自动装配,从而简化代码的开发,不需要编写各种配置文件,只需要引入相关的依赖就可以迅速搭建一个应用。

特点

1、不需要web.xml

2、不需要SpringMVC.xml

3、不需要tomcat,SpringBoot内嵌了一个tomcat

4、不需要配置JSON解析,支持REST架构

5、个性化配置非常简单

如何使用

1、创建一个Maven项目,pom.xml导入依赖

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.11</version>
</parent>

<dependencies>
    <!-- SpringBoot -->
    <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>3.2.0</version>
    </dependency>

    <!-- LomBok -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>

</dependencies>

2、创建实体类

package cn.soutprint.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class Student {
    private int id;
    private String name;
    private int age;
}

3、StudentRepository

package cn.soutprint.repository;

import cn.soutprint.pojo.Student;

import java.util.Collection;

public interface StudentRepository {
    public Collection<Student> findAll();
    public Student findById(int id);
    public void saveOrUpdate(Student student);
    public void deleteById(int id);
}

4、StudentRepositoryImpl

package cn.soutprint.repository.Impl;

import cn.soutprint.pojo.Student;
import cn.soutprint.repository.StudentRepository;
import org.springframework.stereotype.Repository;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

@Repository
public class StudentRepositoryImpl implements StudentRepository {

    private static Map<Integer,Student> map;

    static {
        map = new HashMap<>();
        map.put(1,new Student(1,"张三",22));
        map.put(2,new Student(2,"李四",13));
        map.put(3,new Student(3,"王五",16));
    }


    @Override
    public Collection<Student> findAll() {
        return map.values();
    }

    @Override
    public Student findById(int id) {
        return map.get(id);
    }

    @Override
    public void saveOrUpdate(Student student) {
        map.put(student.getId(),student);
    }

    @Override
    public void deleteById(int id) {
        map.remove(id);
    }
}

5、StudentHandler

package cn.soutprint.controller;

import cn.soutprint.pojo.Student;
import cn.soutprint.repository.StudentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Collection;

@RestController
@RequestMapping("/student")
public class StudentHandler {

    @Autowired
    private StudentRepository studentRepository;

    @GetMapping("/findAll")
    public Collection findAll(){
        return studentRepository.findAll();
    }

    @GetMapping("/findById/{id}")
    public Student findById(@PathVariable Integer id){
        return studentRepository.findById(id);
    }

    @PostMapping("/save")
    public void save(@RequestBody Student student){
        studentRepository.saveOrUpdate(student);
    }

    @PutMapping("/update")
    public void update(@RequestBody Student student){
        studentRepository.saveOrUpdate(student);
    }

    @DeleteMapping("/deleteById/{id}")
    public void deleteById(@PathVariable Integer id){
        studentRepository.deleteById(id);
    }

}

6、application.yml

server:
  port: 8888

7、启动类

package cn.soutprint;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class,args);
    }
}

@SpringBootApplication 表示当前类是SpringBoot的入口,Application类的存放位置必须是其他相关业务类的存放位置的父级。

SpringBoot整合JSP

1、创建Maven项目、添加pom.xml配置


<parent>
  <artifactId>spring-boot-starter-parent</artifactId>
  <groupId>org.springframework.boot</groupId>
  <version>2.7.11</version>
</parent>

<dependencies>
  <!-- Web -->
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <!-- JSP -->
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
  </dependency>
  <dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
  </dependency>

  <!-- JSTL -->
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
  </dependency>

  <!-- lombok -->
  <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.30</version>
  </dependency>
</dependencies>

2、创建实体类

package cn.soutprint.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class Student {
    private int id;
    private String name;
    private int age;
}

3、StudentRepository

package cn.soutprint.repository;

import cn.soutprint.pojo.Student;

import java.util.Collection;

public interface StudentRepository {
    public Collection<Student> findAll();
    public Student findById(int id);
    public void saveOrUpdate(Student student);
    public void deleteById(int id);
}

4、StudentRepositoryImpl

package cn.soutprint.repository.Impl;

import cn.soutprint.pojo.Student;
import cn.soutprint.repository.StudentRepository;
import org.springframework.stereotype.Repository;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

@Repository
public class StudentRepositoryImpl implements StudentRepository {

    private static Map<Integer,Student> map;

    static {
        map = new HashMap<>();
        map.put(1,new Student(1,"张三",22));
        map.put(2,new Student(2,"李四",13));
        map.put(3,new Student(3,"王五",16));
    }


    @Override
    public Collection<Student> findAll() {
        return map.values();
    }

    @Override
    public Student findById(int id) {
        return map.get(id);
    }

    @Override
    public void saveOrUpdate(Student student) {
        map.put(student.getId(),student);
    }

    @Override
    public void deleteById(int id) {
        map.remove(id);
    }
}

5、StudentHandler

package cn.soutprint.controller;

import cn.soutprint.pojo.Student;
import cn.soutprint.repository.StudentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
@RequestMapping("student")
public class StudentHandler {

    @Autowired
    private StudentRepository studentRepository;

    @GetMapping("/findAll")
    public ModelAndView findAll(){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("selectAll");
        modelAndView.addObject("list",studentRepository.findAll());
        return modelAndView;
    }

    @GetMapping("/findById/{id}")
    public ModelAndView findById(@PathVariable("id") int id){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("update");
        modelAndView.addObject("student",studentRepository.findById(id));
        return modelAndView;
    }

    @GetMapping("/deleteById/{id}")
    public String deleteById(@PathVariable("id") int id){
        studentRepository.deleteById(id);
        return "redirect:/student/findAll";
    }

    @PostMapping("/update")
    public String update(Student student){
        studentRepository.saveOrUpdate(student);
        return "redirect:/student/findAll";
    }

    @PostMapping("/save")
    public String save(Student student){
        studentRepository.saveOrUpdate(student);
        return "redirect:/student/findAll";
    }

}

6、JSP页面

Save

<%--
  Created by IntelliJ IDEA.
  User: DELL
  Date: 2024/1/8
  Time: 20:29
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

        <form action="/student/save" method="post">
            编号:<input type="text" name="id"><br>
            姓名:<input type="text" name="name"><br>
            年龄:<input type="text" name="age"><br>
            <input type="submit" value="提交">
        </form>

</body>
</html>

Update

<%--
  Created by IntelliJ IDEA.
  User: DELL
  Date: 2024/1/8
  Time: 20:29
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

    <form action="/student/update" method="post">
        编号:<input type="text" name="id" value="${student.id}" readonly><br>
        姓名:<input type="text" name="name" value="${student.name}"><br>
        年龄:<input type="text" name="age" value="${student.age}"><br>
        <input type="submit" value="提交">
    </form>

</body>
</html>

Select

<%--
  Created by IntelliJ IDEA.
  User: DELL
  Date: 2024/1/8
  Time: 20:14
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>查询所有</title>
</head>
<body>

    <table>
        <tr>
            <th>编号</th>
            <th>姓名</th>
            <th>年龄</th>
            <th>操作</th>
        </tr>
        <c:forEach items="${list}" var="student">
            <tr>
                <td>${student.id}</td>
                <td>${student.name}</td>
                <td>${student.age}</td>
                <td>
                    <a href="/student/findById/${student.id}">修改</a>
                    <a href="/student/deleteById/${student.id}">删除</a>
                </td>
            </tr>
        </c:forEach>

    </table>
    <a href="/save.jsp">添加学生</a>

</body>
</html>

7、application.yml配置

server:
  port: 9090
spring:
  mvc:
    view:
      prefix: /
      suffix: .jsp

Spring Boot HTML

Spring Boot可以结合Thymeleaf模板来整合HTML,使用原生的HTML作为视图。

Thymeleaf模板是面向Web和独立环境的Java模板引擎,能够处理HTML、XML、JavaScript、Css等。

<p th:text="${message}"></p>

1、pom.xml添加依赖

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.11</version>
</parent>

<dependencies>
    <!-- SpringBoot -->
    <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>3.2.0</version>
    </dependency>

    <!-- LomBok -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>

</dependencies>

2、application.yml配置

server:
  port: 8888
spring:
  thymeleaf:
    prefix: classpath:/templates/
    suffix: .html
    mode: HTML5
    encoding: UTF-8

3、Handler

package cn.soutprint.controller;

import cn.soutprint.pojo.Student;
import cn.soutprint.repository.StudentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.ArrayList;
import java.util.List;

@Controller
@RequestMapping("/index")
public class IndexHandler {

    @RequestMapping("/test")
    public String index(Model model){
        List<Student> list = new ArrayList<>();
        list.add(new Student(1,"张三",14));
        list.add(new Student(2,"李四",16));
        list.add(new Student(3,"王五",19));
        model.addAttribute("list",list);
        return "index";
    }

}

4、HTML

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"></html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <table>
      <tr>
        <th>学生编号</th>
        <th>学生姓名</th>
        <th>学生年龄</th>
      </tr>
      <tr th:each="student:${list}">
        <td th:text="${student.id}"></td>
        <td th:text="${student.name}"></td>
        <td th:text="${student.age}"></td>
      </tr>
    </table>
</body>
</html>

如果希望客户端可以直接访问HTML资源,将这些资源放置在static路径下即可,否则必须通过Handler的后台映射才可以访问静态资源。

Thymeleaf常用语法

拼接和赋值


@RequestMapping("/test2")
public String concat(Map<String,String> map){
    map.put("name","张三");
    return "concat";
}
<p th:text="${name}"></p>
<p th:text="'我是' + ${name}"></p>
<p th:text="|我是${name}|"></p>

条件判断if/unless


@GetMapping("/test3")
public String test3(Map<String,Boolean> map){
    map.put("flag",true);
    return "concat";
}
<p th:if="${flag == true}" th:text="if判断成立"></p>
<p th:unless="${flag == true}" th:text="unless判断不成立"></p>

循环

@GetMapping("/test")
public String index(Model model){
    List<Student> list = new ArrayList<>();
    list.add(new Student(1,"张三",14));
    list.add(new Student(2,"李四",16));
    list.add(new Student(3,"王五",19));
    model.addAttribute("list",list);
    return "index";
}
<table>
  <tr>
      <th>index</th>
      <th>count</th>
    <th>学生编号</th>
    <th>学生姓名</th>
    <th>学生年龄</th>
  </tr>
  <tr th:each="student,status:${list}" th:style="'background-color:'+@{${status.odd}?'#f2f2f2'}">
      <td th:text="${status.index}"></td>
      <td th:text="${status.count}"></td>
    <td th:text="${student.id}"></td>
    <td th:text="${student.name}"></td>
    <td th:text="${student.age}"></td>
  </tr>
</table>

status是状态变量,属性有以下:

URL

Thymeleaf对于URL的处理是通过@{....}进行处理,结合th:href、th:src

<a th:href="@{http://www.baidu.com}">跳转百度</a>
<a th:href="@{http://127.0.0.1:8888/index/url/{username}(username=${name})}">跳转2</a>

三元运算符

<input th:value="${age gt 18?'成年':'未成年'}">
  • gt:great than 大于

  • ge:great equal 大于等于

  • eq:equal 等于

  • lt:less than 小于

  • le:less equal 小于等于

  • ne:not equal 不等于

  • switch

@GetMapping("/test6")
public String test7(Model model){
    model.addAttribute("sex","男");
    return "concat";
}
<div th:switch="${sex}">
    <p th:case="女">女</p>
    <p th:case="男">男</p>
    <p th:case="*">未知</p>
</div>
  • 基本对象

    • #ctx:上下文对象

    • #vars:上下文变量

    • #locale:区域对象

    • #request:HttpServletRequest对象

    • #response:HttpServletResponse对象

    • #session:HttpSession对象

    • #servletContext:ServletContext对象

  • 内嵌对象

    • dates:java.utlil.Date的功能方法

    • calendars:java.util.Calendar的功能方法

    • numbers:格式化数字

    • strings:java.lang.String的功能方法

    • objects:object的功能方法

    • bools:对布尔求值的方法

    • arrays:操作数组的功能方法

    • lists:操作集合的功能方法

    • sets:操作集合的功能方法

    • maps:操作集合的功能方法

@GetMapping("/test7")
public String test8(Model model){
    model.addAttribute("name","张三");
    model.addAttribute("data",new Date());
    model.addAttribute("list",new ArrayList<>());
    return "concat";
}
<!--  格式化时间  -->
<p th:text="${#dates.format(data,'yyyy-MM-dd HH:mm:ss')}"></p>
<!--  创建当前时间,精确到天  -->
<p th:text="${#dates.createToday()}"></p>
<!--  创建当前时间,精确到秒  -->
<p th:text="${#dates.createNow()}"></p>
<!--  判断是否为空  -->
<p th:text="${#strings.isEmpty(name)}"></p>
<!--  判断list集合是否为空  -->
<p th:text="${#lists.isEmpty(list)}"></p>
<!--  输出字符串长度  -->
<p th:text="${#strings.length(name)}"></p>
<!--  拼接字符串  -->
<p th:text="${#strings.concat(name,name)}"></p>
<!--  创建自定义字符串  -->
<p th:text="${#strings.randomAlphanumeric(10)}"></p>

SpringBoot数据校验

@GetMapping("/test8")
public void test9(@Valid User user, BindingResult bindingResult){
    System.out.println(user);
    if (bindingResult.hasErrors()){
        List<ObjectError> list = bindingResult.getAllErrors();
        for (ObjectError objectError: list) {
            System.out.println(objectError.getCode() + "--" + objectError.getDefaultMessage());
        }
    }
}
package cn.soutprint.pojo;

import lombok.Data;

import javax.validation.constraints.Min;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;

@Data
public class User {
    @NotNull(message = "编号不能为空")
    private int id;
    @NotEmpty(message = "姓名不能为空")
    private String name;
    @Min(value = 16, message = "年龄不能小于16")
    private int age;
}

Spring JDBC

1、pom.xml添加依赖


<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.11</version>
</parent>

<dependencies>
    <!-- SpringBoot -->
    <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>3.2.0</version>
    </dependency>

    <!-- LomBok -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>

    <!--  数据校验  -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>

    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.47</version>
    </dependency>


</dependencies>

2、实体类

package cn.soutprint.pojo;

import lombok.Data;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;

@Data
public class User {
    @NotNull(message = "编号不能为空")
    private int uid;
    @NotEmpty(message = "姓名不能为空")
    private String username;
    @NotEmpty(message = "性别不能为空")
    private String sex;
    @NotEmpty(message = "地址不能为空")
    private String address;
    @NotEmpty(message = "生日不能为空")
    private String brithday;
}

3、Repository

package cn.soutprint.repository;

import cn.soutprint.pojo.User;

import java.util.List;

public interface UserRepository {
    public List<User> findAll();
    public User findById(int id);
    public void save(User user);
    public void update(User user);
    public void deleteById(int id);
}

4、RepositoryImpl

package cn.soutprint.repository.Impl;

import cn.soutprint.pojo.User;
import cn.soutprint.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public class UserRepositoryImpl implements UserRepository {

    @Autowired(required = false)
    private JdbcTemplate jdbcTemplate;

    @Override
    public List<User> findAll() {
        return jdbcTemplate.query("select * from userinfo",new BeanPropertyRowMapper<>(User.class));
    }

    @Override
    public User findById(int id) {
        return jdbcTemplate.queryForObject("select * from userinfo where uid = ?",new BeanPropertyRowMapper<>(User.class),id);
    }

    @Override
    public void save(User user) {
        jdbcTemplate.update("insert into userinfo(username,sex,address,brithday) values(?,?,?,?)",user.getUsername(),user.getSex(),user.getAddress(),user.getBrithday());
    }

    @Override
    public void update(User user) {
        jdbcTemplate.update("update userinfo set username=?,sex=?,address=?,brithday=? where uid = ?",user.getUsername(),user.getSex(),user.getAddress(),user.getBrithday(),user.getUid());
    }

    @Override
    public void deleteById(int id) {
        jdbcTemplate.update("delete from userinfo where uid = ?",id);
    }
}

5、Handler

package cn.soutprint.controller;

import cn.soutprint.pojo.User;
import cn.soutprint.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/user")
public class UserHandler {

    @Autowired
    private UserRepository userRepository;

    @GetMapping("/findAll")
    public List<User> findAll(){
        return userRepository.findAll();
    }

    @GetMapping("/findById/{id}")
    public User findById(@PathVariable("id") int id){
        return userRepository.findById(id);
    }

    @PostMapping("/save")
    public void save(@RequestBody User user){
        userRepository.save(user);
    }

    @PutMapping("/update")
    public void update(@RequestBody User user){
        userRepository.update(user);
    }

    @DeleteMapping("/deleteById/{id}")
    public void deleteById(@PathVariable("id") int id){
        userRepository.deleteById(id);
    }

}

SpringBoot整合Mybatis

1、创建Maven项目,在pom.xml引入相关依赖

<!--  SpringBoot父类  -->
<parent>
    <artifactId>spring-boot-starter-parent</artifactId>
    <groupId>org.springframework.boot</groupId>
    <version>2.7.11</version>
</parent>

<dependencies>
    <!--   SpringBoot Web     -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--    Mybatis    -->
    <!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter -->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.2.2</version>
    </dependency>
    <!--    jdbc    -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.47</version>
    </dependency>
    <!--    lombok    -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.30</version>
    </dependency>
</dependencies>

2、创建实体类

package cn.soutprint.pojo;

import lombok.Data;

import java.util.Date;

@Data
public class Student {
    private int id;
    private String name;
    private int age;
    private Date birthday;
}

3、编写Repository接口

package cn.soutprint.repository;

import cn.soutprint.pojo.Student;

import java.util.List;

public interface StudentRepository {
    public List<Student> findAll();
    public Student findById(int id);
    public int insertStudent(Student student);
    public int updateStudent(Student student);
    public int deleteById(int id);
}

4、编写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为映射的根节点-->
<!-- mapper为映射的根节点,namespace指定Dao接口的完整类名
mybatis会依据这个接口动态创建一个实现类去实现这个接口,
而这个实现类是一个Mapper对象-->
<mapper namespace="cn.soutprint.repository.StudentRepository">
    <!--id ="接口中的方法名"
  parameterType="传入的参数类型"
  resultType = "返回实体类对象,使用包.类名" -->
    <select id="findAll" resultType="Student">
        select *
        from student
   </select>

    <select id="findById" parameterType="int" resultType="Student">
        select * from student where id = #{id}
    </select>

    <insert id="insertStudent" parameterType="Student">
        insert into student(name,age,birthday) values(#{name},#{age},#{birthday})
    </insert>

    <update id="updateStudent" parameterType="Student">
        update student
        <set>
            <if test="name != null and name != ''">
                name = #{name},
            </if>
            <if test="age != null and age != ''">
                age = #{age},
            </if>
            <if test="birthday != null">
                birthday = #{birthday},
            </if>
        </set>
        where id = #{id}
    </update>

    <delete id="deleteById" parameterType="int">
        delete from student where id = #{id}
    </delete>
</mapper>

5、编写application.yml文件

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/xiaoshuodb?useUnicode=true&characterEncoding=UTF-8
    username: root
    password: xxxxx
    driver-class-name: com.mysql.jdbc.Driver
mybatis:
#  扫描resources资源下的Mappers目录下的所有xml文件
  mapper-locations: classpath:/Mappers/*.xml
#  给实体类取别名
  type-aliases-package: cn.soutprint.pojo

6、编写Controller

package cn.soutprint.controller;

import cn.soutprint.pojo.Student;
import cn.soutprint.repository.StudentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/student")
public class StudentHandler {

    @Autowired
    private StudentRepository studentRepository;

    @GetMapping("/findAll")
    public List<Student> findAll(){
        return studentRepository.findAll();
    }

    @GetMapping("/findById/{id}")
    public Student findById(@PathVariable("id") int id){
        return studentRepository.findById(id);
    }

    @PostMapping("/insert")
    public void insertStudent(@RequestBody Student student){
        studentRepository.insertStudent(student);
    }

    @PutMapping("/update")
    public void updateStudent(@RequestBody Student student){
        studentRepository.updateStudent(student);
    }

    @DeleteMapping("/deleteById/{id}")
    public void deleteById(@PathVariable("id") int id){
        studentRepository.deleteById(id);
    }

}

7、编写启动类

package cn.soutprint;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
//自动加载这个包下的所有接口
@MapperScan("cn.soutprint.repository")
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class,args);
    }
}

SpringBoot整合Redis

1、pom.xml引入相关依赖

<groupId>org.example</groupId>
<artifactId>SpringBootAndRedis</artifactId>
<version>1.0-SNAPSHOT</version>

<parent>
    <artifactId>spring-boot-starter-parent</artifactId>
    <groupId>org.springframework.boot</groupId>
    <version>2.7.11</version>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-pool2</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
</dependencies>

2、创建实体类继承Serializable

package cn.soutpring.pojo;

import lombok.Data;

import java.io.Serializable;
import java.util.Date;

//Serializable序列化
@Data
public class Student implements Serializable {
    private Integer id;
    private String name;
    private Double score;
    private Date birthday;
}

3、Handler

package cn.soutpring.controller;

import cn.soutpring.pojo.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/student")
public class StudentHandler {

//    操作Redis对象
    @Autowired
    private RedisTemplate redisTemplate;

    @PostMapping("/set")
    public void set(@RequestBody Student student){
        redisTemplate.opsForValue().set("student",student);
    }

    @GetMapping("/get/{key}")
    public Student get(@PathVariable("key") String key){
        return (Student) redisTemplate.opsForValue().get(key);
    }

    @DeleteMapping("/delete/{key}")
    public boolean delete(@PathVariable("key") String key){
        redisTemplate.delete(key);
        return redisTemplate.hasKey(key);
    }

}

4、application.yml配置文件

spring: redis: dataspring:
  redis:
    database: 0
    host: localhost

5、启动类

package cn.soutpring;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class,args);
    }
}

Shiro安全框架

是一款主流的Java安全框架,不依赖任何容器,可以运行在Java SE和JavaEE项目中,它的主要作用是对访问系统的用户进行身份认证、授权、会话管理、加密等操作。

Shiro就是用来解决安全管理的系统化框架

Shiro核心组件

用户、角色、权限

给角色赋予权限,给用户赋予角色

  1. UsernamePasswordToken,Shiro用来封装用户登录信息,使用用户的登录信息来创建令牌Token。

  2. SecurityManager,Shiro的核心部分,负责安全认证和授权。

  3. Subject,Shiro的一个抽象概念,包含了用户信息。

  4. Realm,开发者自定义的模块,根据项目的需求,验证和授权的逻辑全部卸载Realm中。

  5. AuthenticationInfo,用户的角色信息集合,认证时使用。

  6. AuthorizationInfo,角色的权限信息集合,授权时使用。

  7. DefaultWebSecurityManger,安全管理器,开发者自定义的Realm需要注入DefaultWebSecurityManger进行管理才能生效。

  8. ShiroFilterFactoryBean,过滤器工厂,Shiro的基本运行机制是开发者定制规则,Shiro取执行,具体的执行操作就是由ShiroFilterFactoryBean创建一个个Filter对象来完成。

Spring Boot整合Shiro

创建Spring Boot应用,集成shiro相关组件

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-spring -->
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-spring</artifactId>
        <version>1.13.0</version>
    </dependency>


    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.2.2</version>
    </dependency>

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.47</version>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

自定义过滤器


public class EmployeeRealm extends AuthorizingRealm {

    @Autowired
    private EmployeeService employeeService;

    /**
     * 授权
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        return null;
    }

    /**
     * 认证
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        Employee employee = employeeService.findByName(token.getUsername());
        if (employee != null){
            return new SimpleAuthenticationInfo(employee,employee.getPwd(),getName());
        }
        return null;
    }
}

配置

package com.southwind.config;

import com.southwind.realm.EmployeeRealm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ShiroConfig {

    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager manager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(manager);
        return shiroFilterFactoryBean;
    }

    @Bean
    public DefaultWebSecurityManager securityManager(@Qualifier("employeeRealm") EmployeeRealm employeeRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(employeeRealm);
        return securityManager;
    }

    @Bean
    public EmployeeRealm employeeRealm(){
        return new EmployeeRealm();
    }


}

编写认证和授权规则

  1. 认证过滤器

    1. anon:无需认证

    2. authc:必须认证

    3. authcBasic:需要通过HTTPBasic认证

    4. user:不一定通过认证,只要曾经被Shiro记录即可,比如:记住我

  2. 授权过滤器

    1. perms:必须拥有某个权限才能访问

    2. roles:必须拥有某个角色才能访问

    3. port:请求的端口必须是指定值才可以

    4. rest:请求必须基于RESTful、POST、PUT、GET、DELETE

    5. ssl:必须是安全的URL请求,协议HTTPS