SpringBoot学习笔记

yaml 语法

# application.yml
people:
  name: _Nice
  age: 10
  happy: true
  birth: 2020/5/6
  maps: {k1: v1,k2: v2}
  lists:
    - code
    - music
    - girl
  dog:
    name: 旺财
    age: 3
// yml文件属性值注入
package com.kuang.pojo;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Component
@ConfigurationProperties(prefix = "people")
public class People {

    private String name;
    private Integer age;
    private Boolean happy;
    private Date birth;
    private Map<String, Object> maps;
    private List<Object> lists;
    private Dog dog;
    public People() {
    }

    public People(String name, Integer age, Boolean happy, Date birth, Map<String, Object> maps, List<Object> lists, Dog dog) {
        this.name = name;
        this.age = age;
        this.happy = happy;
        this.birth = birth;
        this.maps = maps;
        this.lists = lists;
        this.dog = dog;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Boolean getHappy() {
        return happy;
    }

    public void setHappy(Boolean happy) {
        this.happy = happy;
    }

    public Date getBirth() {
        return birth;
    }

    public void setBirth(Date birth) {
        this.birth = birth;
    }

    public Map<String, Object> getMaps() {
        return maps;
    }

    public void setMaps(Map<String, Object> maps) {
        this.maps = maps;
    }

    public List<Object> getLists() {
        return lists;
    }

    public void setLists(List<Object> lists) {
        this.lists = lists;
    }

    public Dog getDog() {
        return dog;
    }

    public void setDog(Dog dog) {
        this.dog = dog;
    }
    
}

image-20210729204804261.png

使用 @ConfigurationProperties 报红,但实际上可以正常运行。要想解决可以导入如下依赖(注意要有 @Component):

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-configuration-processor</artifactId>
   <optional>true</optional>
</dependency>

也可以通过外部 properties 文件和 SPEL 进行属性注入,但我这种方式注入中文乱码就很迷惑,如果不使用 SPEL 导入值就不会乱码,留坑。但大多数情况都是使用 yml 配置,这个了解即可。

name=哈哈哈
age=8
package com.kuang.pojo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Component
@PropertySource("classpath:people.properties")
public class People {

    @Value("${name}")
    // 使用 @Value("哈哈哈") 就不会乱码
    private String name;
    @Value("${age}")
    private Integer age;
    private Boolean happy;
    private Date birth;
    private Map<String, Object> maps;
    private List<Object> lists;
    private Dog dog;
    
    public People() {
    }

    public People(String name, Integer age, Boolean happy, Date birth, Map<String, Object> maps, List<Object> lists, Dog dog) {
        this.name = name;
        this.age = age;
        this.happy = happy;
        this.birth = birth;
        this.maps = maps;
        this.lists = lists;
        this.dog = dog;
    }

JSR303校验

处理一段业务逻辑,首先要确保数据输入的正确性,所以需要先对数据进行检查,保证数据在语义上的正确性,再根据数据进行下一步的处理。前端可以通过 js 程序校验数据是否合法,后端同样也需要进行校验。

JSR 303 使用 Bean Validation,即在 Bean 上添加相应的注解,去实现数据校验。这样在执行业务方法前,都会根据注解对数据进行校验,从而减少自定义的校验逻辑,减少代码冗余。下面是其中一部分注解。更高级用法参考其他相关博客。

@Null                  被指定的注解元素必须为 Null
@NotNull               任意类型,不能为 Null,但可以为空,比如空数组、空字符串。
@NotBlank              针对字符串,不能为 Null,且去除前后空格后的字符串长度要大于 0。
@NotEmpty              针对字符串、集合、数组,不能为 Null,且长度要大于 0。
@Size                   针对字符串、集合、数组,判断长度是否在给定范围内。
@Length                 针对字符串,判断长度是否在给定范围内。
@AssertTrue             针对布尔值,用来判断布尔值是否为 true
@AssertFalse            针对布尔值,用来判断布尔值是否为 false
@Max(value)         针对字符串、数值,用来判断是否小于等于某个指定值
@Min(value)         针对字符串、数值,用来判断是否大于等于某个指定值

配置文件位置

image-20210730123850347.png

配置文件可以放在以上四个位置,注意目录名和文件名是固定的不能改。不同版本的 SpringBoot 对于配置文件位置的优先级规定不同,可以自己测一下。

静态文件

image-20210730131255014.png

放在 public/resources/static 目录下的静态文件可以被访问到,SpringBoot 会去找这三个目录下的文件,如果不同目录下有同名文件,优先级自测。如 http://localhost:8080/3.js 就可以访问到 3.js 的内容

页面

.html 也可以放在 public/resources/static 目录下直接访问。如果将 .html 放在 templates 目录下,则不能直接访问,需要通过 controller 层访问,跟 springMVC 一样,下面是个例子:

package com.horizon.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class indexController {

    @RequestMapping("/test")
    public String test() {
        return "test";
    }
}

然后访问 http://localhost:8080/test 即可跳转到对应的 html 页面,其中在 thymeleafProperties 类中可以看到 thtmeleaf 的实现,其中就有定义路径拼接如下:

public static final String DEFAULT_PREFIX = "classpath:/templates/";
public static final String DEFAULT_SUFFIX = ".html";

index.html 除外,可以直接用 localhost:8080 访问,但不能用 localhost:8080/index.html 直接访问

拦截器

return true 代表放行,在配置类里配置拦截哪些请求,见下面扩展 SpringMVC。如果登录成功则在登录页面将登录信息存在 session 里,拦截器检查 session 是否有登录信息来判断是否放行

package com.horizon.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LoginHandlerInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        Object loginUser = request.getSession().getAttribute("loginUser");

        if(loginUser == null) {
            request.setAttribute("msg", "请先登录");
            request.getRequestDispatcher("/index.html").forward(request, response);
            return false;
        }

        return true;
    }

}

扩展SpringMVC

新建一个配置类,加上 @Configuration 注解并实现 WebMvcConfigurer 接口,然后重写里面方法即可实现扩展。注意不能加上 @EnableWebMvc 注解。下面的一个例子是通过 diy 视图控制来实现直接访问 localhost:8080/index.html来访问 templates 目录下的 index.html 页面

package com.horizon.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/index.html").setViewName("index");
    }
    
    // 配置拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(
            new LoginHandlerInterceptor()).addPathPatterns("/**").excludePathPatterns("/index.html", "/", "/user/login");
    }
}

thymeleaf模板引擎

首先导入配置

<html lang="en" xmlns:th="http://www.thymeleaf.org">

一些常用方法

<!--表单-->
<form th:action="@{/emp}" th:method="post"></form>

<!--循环,th:text为填充文本-->
<select name="department.id">
   <option th:each="dept:${dps}" th:text="${dept.getDepartmentName()}" th:value="${dept.getId()}">		 	</option>
</select>
    
<tr th:each="emp:${emps}">
    <td th:text="${emp.getId()}"></td>
    <td th:text="${emp.getLastName()}"></td>
    <td>
        <a th:href="@{/update(id=${emp.getId()})}">编辑</a>
        <a th:href="@{/delete(id=${emp.getId()})}">删除</a>
    </td>
</tr>
    
<!--是否选中(默认值)-->
<input th:checked="${emp.getGender()==1}" type="radio" name="gender" value="1"/>
<label>男</label>
<input th:checked="${emp.getGender()==0}" type="radio" name="gender" value="0"/>
<label>女</label>

<select name="department.id">
    <option th:selected="${emp.getDepartment().getId()==dept.getId()}" th:each="dept:${dps}"          		th:text="${dept.getDepartmentName()}" th:value="${dept.getId()}"></option>
</select>

其他用法见官方文档

整合JDBC

在 application.yml 文件里加入数据库配置

spring:
  datasource:
    username: root
    password: 123
    url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
    driver-class-name: com.mysql.cj.jdbc.Driver

然后直接使用 JDBCTemplate 即可,注意要自动装配

package com.kuang.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;

@RestController
public class JDBCController {

    @Autowired
    JdbcTemplate jdbcTemplate;

    @GetMapping("/query")
    public List<Map<String, Object>> query() {
        String sql = "select * from user";
        List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
        return maps;
    }

    @GetMapping("/update/{id}")
    public void update(@PathVariable("id") int id) {
        String sql = "update user set name=?,pwd=? where id=?";
        Object[] objects = new Object[3];
        objects[0] = "哈哈哈";
        objects[1] = "541258";
        objects[2] = id;
        jdbcTemplate.update(sql, objects);
    }
}

整合Mybatis

导入依赖

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

在 application.properties 或 application.yml 中配置数据库

# application.properties
spring.datasource.username=root
spring.datasource.password=123
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# application.yml
spring:
  datasource:
    username: root
    password: 123
    url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
    driver-class-name: com.mysql.cj.jdbc.Driver

定义接口,加上 @Mapper 注解

package com.kuang.mapper;

import com.kuang.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

import java.util.List;

@Mapper
@Repository
public interface UserMapper {

    List<User> queryUserList();

}

配置 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.kuang.mapper.UserMapper">

    <select id="queryUserList" resultType="user">
        select * from user;
    </select>
</mapper>

使用

package com.kuang.controller;

import com.kuang.mapper.UserMapper;
import com.kuang.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class UserController {

    @Autowired
    private UserMapper userMapper;

    @GetMapping("/query")
    public List<User> queryUserList() {
        return userMapper.queryUserList();
    }
}

目录结构

image-20210803210302905.png

可能的问题

pom.xml 中 maven 插件爆红,添加一个版本号刷新即可,版本号与 parent 版本号一样

<plugins>
	<plugin>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-maven-plugin</artifactId>
		<version>2.5.3</version>
	</plugin>
</plugins>
posted @ 2021-08-03 21:38  のNice  阅读(51)  评论(0编辑  收藏  举报