

applicat.properties:
 server.port=80  可以更改运行端口号
在resource文件夹中加入banner.text网上搜springboot的运行图行,添加进去就可以改变运行出来的图形了。banner.text:
         /"        |\ /|
        |   |
        | ~ |
        |   |
     /‘\|   |/‘ /"\|   |   |   | |   [ @ ]   |   |  |   |   |   |   |   | ~ ~  ~  ~ |    )   |                   /
 \                 /
  \               /
   \    _____    /
    |– //‘‘`\ – |
    | (( =+= )) |
    |– \\_|_//– |
我们来看pom.xml文件,其中它主要是依赖一个父项目:
<parent>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-parent</artifactId>
   <version>2.1.9.RELEASE</version>
   <relativePath/> <!-- lookup parent from repository -->
</parent>
进入父项目:
<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-dependencies</artifactId>
  <version>2.1.9.RELEASE</version>
  <relativePath>../../spring-boot-dependencies</relativePath>
</parent>
将resource文件夹下的配置文件删掉,换成application.yaml的yaml文件,格式为:key:(空格)vlue。
语法:空格缩进极其严格,类似python
#key: value
name: lisi
#对象
student:
	name: lisi
	age: 10
#或者
student: {name: lisi,age: 10}
#数组
pets:
	- cat
	- dog
	- pig
#或者
pets: [cat,dog,pig]
通过yaml给类属性赋值:
//绑定yaml文件,yaml文件中赋值
@ConfigurationProperties(prefix = "person")
Person.java类:
package com.it.pojo;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import javax.xml.crypto.Data;
import java.util.Date;
import java.util.List;
import java.util.Map;
@lombok.Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Component
//绑定yaml文件,yaml文件中赋值
@ConfigurationProperties(prefix = "person")
public class Person {
    private String name;
    private Integer age;
    private Boolean happy;
    private Date birth;
    private Map<String,Object> maps;
    private List<Object> lists;
    private Dog dog;
}
application.yaml:
#名字不能大写和类名一样,类名的小写就可以用
#也可以 age: ${random.int}生成随机的数字串
#也可以 name: ${person.hello:111}如果hello不存在那么name=111,如果存在name就等于存在的值,也就是旺财
#松散绑定:pojo中写lastName,yaml中可以携程last-name,同样可以赋值
person:
  name: lisi 
  age: 3
  happy: false
  birth: 2020/01/01
  maps: {k1: v1,k2: v2}
  lists:
    - code
    - music
    - girl
  dog:
    name: 旺财
  age: 3
@Component
@ConfigurationProperties(prefix = "person")
@Validated  //开启校验模式
public class Person {
  //lastName必须是邮箱格式
  @Email(message="邮箱格式错误") //验证是否邮箱格式,并提示信息
  //@Value("${person.last‐name}") 
  private String lastName; 
  //@Value("#{11*2}")
    private Integer age;
    //@Value("true")
    private Boolean boss;
    private Date birth;
    private Map<String,Object> maps;
    private List<Object> lists;
    private Dog dog;
}
/* 空检查?
@Null 验证对象是否为null?
@NotNull 验证对象是否不为null, 无法查检长度为0的字符串?
@NotBlank 检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.?
@NotEmpty 检查约束元素是否为NULL或者是EMPTY.
Booelan检查?
@AssertTrue 验证 Boolean 对象是否为 true?
@AssertFalse 验证 Boolean 对象是否为 false
长度检查?
@Size(min=, max=) 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内?
@Length(min=, max=) Validates that the annotated string is between min and max included.
日期检查?
@Past 验证 Date 和 Calendar 对象是否在当前时间之前,验证成立的话被注释的元素一定是一个过去的日期?
@Future 验证 Date 和 Calendar 对象是否在当前时间之后 ,验证成立的话被注释的元素一定是一个将来的日期?
@Pattern 验证 String 对象是否符合正则表达式的规则,被注释的元素符合制定的正则表达式,regexp:正则表达式 flags: 指定 Pattern.Flag 的数组,表示正则表达式的相关选项。
数值检查?
建议使用在Stirng,Integer类型,不建议使用在int类型上,因为表单值为“”时无法转换为int,但可以转换为Stirng为”“,Integer为null?
@Min 验证 Number 和 String 对象是否大等于指定的值?
@Max 验证 Number 和 String 对象是否小等于指定的值?
@DecimalMax 被标注的值必须不大于约束中指定的最大值. 这个约束的参数是一个通过BigDecimal定义的最大值的字符串表示.小数存在精度?
@DecimalMin 被标注的值必须不小于约束中指定的最小值. 这个约束的参数是一个通过BigDecimal定义的最小值的字符串表示.小数存在精度?
@Digits 验证 Number 和 String 的构成是否合法?
@Digits(integer=,fraction=) 验证字符串是否是符合指定格式的数字,interger指定整数精度,fraction指定小数精度。?
@Range(min=, max=) 被指定的元素必须在合适的范围内?
@Range(min=10000,max=50000,message=”range.bean.wage”)?
@Valid 递归的对关联对象进行校验, 如果关联对象是个集合或者数组,那么对其中的元素进行递归校验,如果是一个map,则对其中的值部分进行校验.(是否进行递归验证)?
@CreditCardNumber信用卡验证?
@Email 验证是否是邮件地址,如果为null,不进行验证,算通过验证。?
@ScriptAssert(lang= ,script=, alias=)?
@URL(protocol=,host=, port=,regexp=, flags=) */
源码位置:

application.yaml中:
server:     #默认第一个环境
  port: 8080
spring:
  profiles:
    active: text2    #选择text2环境
      
      
---         #第二个环境
server:
  port: 8001
spring:
  profiles: text2   #环境名字
---         #第三个环境
server:
  port: 8081
spring:
  profiles: text1    #环境名字




版本控制:
 <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.7.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
yaml:
#关闭默认图标
spring.mvc.favicon.enabled=false
ico图片放到resource文件夹下的public问价
pom依赖:
<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring5</artifactId>
</dependency>
<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>
导入:
<html lang="en" xmlns:th="http://www.thymeleaf.org">
将页面写在templates文件夹下面,然后localhost8080/文件名,即可直接访问到
templates文件夹下的html页面:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--所有的HTML元素都可被Thymeleaf替换接管,th:元素名-->
<div th:text="${msg}"></div>
</body>
</html>
controller.java:
package com.it.controller;
        import org.springframework.stereotype.Controller;
        import org.springframework.ui.Model;
        import org.springframework.web.bind.annotation.GetMapping;
        import org.springframework.web.bind.annotation.RequestMapping;
        import org.springframework.web.bind.annotation.RestController;
@Controller
public class IndexController {
    @RequestMapping("/h")
    public String hello(Model model){
        model.addAttribute("msg","hellwspringboot");
        return "test";
    }
}
<!--Java中:model.addAttribute("list",Arrays.asList("hahaha","hehehe","xixixi","lalala"));  
-->
<!--引入thymeleaf命名空间-->
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--utext可转义HTML语句,text不可转义
<div th:utext="${msg}"></div>
<div th:text="${msg}"></div>-->
<!--遍历集合-->
<div th:each="list:${list}" th:text="${list}"></div>
</body>
</html>
接管并扩展springmvc,视图解析器:
package com.it.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.Locale;
//接管并扩展springmvc,视图解析器
@Configuration
//不能写@EnableWebMvc
public class MyMvcConfig implements WebMvcConfigurer {
    @Bean
    public ViewResolver myVierResolver(){
        return new MyViewResolver();
    }
    //实现了视图解析接口的类ViewResolver,就是视图解析器
    //自定义了一个视图解析器
    public static class MyViewResolver implements ViewResolver{
        @Override
        public View resolveViewName(String s, Locale locale) throws Exception {
            return null;
        }
    }
    
}
yaml:
# 自定义日期格式化,默认位dd/MM/yyy
#spring:
#  mvc:
#    date-format:
#1.自定义日期格式化,默认位dd/MM/yyy
#spring:
#  mvc:
#    date-format: dd-MM-yyy
#2.关闭模板引擎的缓存
#spring:
#  thymeleaf:
#    cache: false
#3.国际化,配置文件的真实路径spring: 要添加国际化的的字段,在标签内添加,例如th:text="#{login.tip}"
#spring:
#  messages:
#    basename: i18n.login 在那个页面实现就 . 那个页面
#4.所有页面的静态资源都需要使用thymeleaf接管,本地href用@{/../../}
#设置首页路径,路径变为localhost:8080/it/index.html或者localhost:8080/it
#server:
#  servlet:
#    context-path: /it
spring:
  thymeleaf:
    cache: false
  messages:
    basename: i18n.login
package com.it.dao;
import com.it.pojo.Department;
import com.it.pojo.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@Repository
public class EmployeeDao {
    //    模拟数据库中的数据
    private static Map<Integer,Employee> employees =null;
    @Autowired
    private DepartmentDao departmentDao;
    static {
        employees = new HashMap<Integer, Employee>();
        employees.put(1001,new Employee(1001,"AA","11111111@qq.com",0,new Department(101,"教学部")));
        employees.put(1002,new Employee(1002,"BB","22222222@pp.com",1,new Department(102,"信息部")));
        employees.put(1003,new Employee(1003,"CC","33333333@qq.com",1,new Department(103,"科研部")));
        employees.put(1004,new Employee(1004,"DD","11131111@qq.com",1,new Department(104,"美术部")));
        employees.put(1005,new Employee(1005,"EE","11111711@qq.com",0,new Department(105,"体育部")));
    }
//    主键自增
    private static Integer initId = 1006;
//    增加一个员工
    public void add(Employee employee){
        if (employee.getId() == null){
            employee.setId(initId++);
        }
        employee.setDepartment(departmentDao.getDepartmentById(employee.getDepartment().getId()));
        employees.put(employee.getId(),employee);
    }
//    通过id查询员工
    public Employee select(Integer id){
        return employees.get(id);
    }
//    删除一个员工
    public void delete(Integer id){
        employees.remove(id);
    }
//    获得所有员工
    public Collection<Employee> getAll(){
        return employees.values();
    }
}
在resource文件夹下,创建一个i18n文件夹创建login.properties。然后再建一个login_en_US.properties。二者自动合并,然后再直接输入zh_CN,创建一个login_zh_CN.properties。
前端页面:
<html lang="en" xmlns:th="http://www.thymeleaf.org"> 
用th:接管
<h1 th:text="#{login.tip}">Please sign in</h1>
<input type="password" name="password" th:placeholder="#{login.password}" required="">
<input type="checkbox" value="remember-me">[[#{login.remember}]]
</html>
首页,点击中文或者英文,自动跳转:
()为传参数
<a class="btn btn-sm" th:href="@{/index.html(l=‘zh_CN‘)}">中文</a>
<a class="btn btn-sm" th:href="@{/index.html(l=‘en_US‘)}">English</a>
com.it.config的MyLocaleResolver.java中:
package com.it.config;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.LocaleResolver;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
public class MyLocaleResolver implements LocaleResolver {
    //        自制添加一个国际化解析器
    
    public Locale resolveLocale(HttpServletRequest httpServletRequest) {
        //获取请求中的语言参数
        String language = httpServletRequest.getParameter("l");
        //如果没有就用默认的
        Locale locale = Locale.getDefault();
        //如果带有了国际化请求参数
        if (!StringUtils.isEmpty(language)){
            //zh_CN分割
            String[] s = language.split("_");
            locale = new Locale(s[0], s[1]);
        }
        return locale;
    }
    public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {}
}
com.it.config的MyMvcConfig.java中:装配到bean:
package com.it.config;
        import org.springframework.context.annotation.Bean;
        import org.springframework.context.annotation.Configuration;
        import org.springframework.web.servlet.HandlerInterceptor;
        import org.springframework.web.servlet.LocaleResolver;
        import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
        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("/").setViewName("index");
                registry.addViewController("/index.html").setViewName("index");
//                如果路径写main,就跳转到dashboard.html
                registry.addViewController("/main").setViewName("dashboard");
        }
    
        //自定义的国际化组件就生效了
        @Bean
        public LocaleResolver localeResolver(){
             return new MyLocaleResolver();
        }
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
                registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**").excludePathPatterns("/","/index.html","/user/login","/css/*","/js/*","/img/*");
        }
}
yaml中:
spring:
  thymeleaf:
    cache: false
  messages:
    basename: i18n.login
com.it.config的MyMvcConfig.java中:直接装配到bean
package com.it.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
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("/").setViewName("index");
                registry.addViewController("/index.html").setViewName("index");
//                如果路径写main,就跳转到dashboard.html
                registry.addViewController("/main").setViewName("dashboard");
        }
}
com.it.config的LoginHandlerInterceptor.java中:
package com.it.config;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
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 usersession = request.getSession().getAttribute("usersession");
        if (usersession == null){
            request.setAttribute("msg","没有权限,请先登录");
            request.getRequestDispatcher("/index.html").forward(request,response);
            return false;
        }else {
            return true;
        }
    }
}
com.it.config的MyMvcConfig.java中:装配到bean:
package com.it.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    //意思就是添加那个拦截,排除那个拦截
        public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**").excludePathPatterns("/","/index.html","/user/login","/css/*","/js/*","/img/*");
        }
}
private Date birth;
public Employee() {
//默认的创建日期
this.birth = new Date();
}
1.同样的路径,不同的请求方式,会有不同的代码,不同的效果
@RequestMapping("/emps")@GetMapping("/emp")@PostMapping("/emp")
    
2.后台:@RequestMapping("/emp/{id}")
    public String toUpdate(Model model,@PathVariable("id") Integer id) {
        return "";
    }
  前端:<a th:href="@{/emp/}+${emp.getId()}">编辑</a>  传一个参数id
再templates下创建commons创建commons.html,用来装公共的页面代码
commons.html公共部分:
要添加th:fragment=""
<nav th:fragment="topbar"> </nav>
将公共部分连接到页面:
<!--使用抽取公共的-->
<div th:replace="~{commons/commons.html::topbar}"></div>
href,src,action用th接管:
<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet">
<img th:src="@{/img/bootstrap-solid.svg}">
<form th:action="@{/updateEmp}" method="post">
判断是否空:
<!--如果msg不为空就显示该代码-->
<p th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>
在进行update的时候:
<!--一到update修改,就要添加id的隐藏域-->
<input type="hidden" name="id" th:value="${emp.getId()}">
<div>
<label>LastName</label>
<!--update修改,就给修改页面的字段赋值-->
<input th:value="${emp.getLastName()}" type="text" name="lastName">
</div>
在add添加遇到下拉框数据时,给下拉一个具体的id,每一个部门的id不同,最后提交的是id:
<select class="form-control" name="department.id">
<option th:each="dep:${department}" th:text="${dep.getDepartmentName()}" th:value="${dep.getId()}"></option>
</select>
遍历+三目运算符+三目运算符:
<!--遍历  遍历的名字emp:${emps}后端传来的对象-->
<tr th:each="emp:${emps}">
    <td th:text="${emp.getId()}"></td>
    <td>[[${emp.getLastName()}]]</td>
    <td th:text="${emp.getEmail()}"></td>、
<!--三目运算符-->
    <td th:text="${emp.getGender()==0?‘女‘:‘男‘}"></td>
    <td th:text="${emp.getDepartment()}"></td>
<!--三目运算符-->
    <td th:text="${#dates.format(emp.getBirth(),‘yyy-MM-dd HH:mm:ss‘)}"></td>
</tr>
点一个连接高亮:
<a th:class="${active==‘main.html‘?‘nav-link active‘:‘nav-link‘}" th:href="@{/index.html}">
error页面:只需要在templates下创建error文件夹,加入error.html,即可
com.it.config:DruidConfig.java:
package com.it.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.apache.catalina.manager.StatusManagerServlet;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.Filter;
import javax.servlet.FilterRegistration;
import javax.servlet.Servlet;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class DruidConfig {
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource dataSource(){
        return new DruidDataSource();
    }
    @Bean
    public ServletRegistrationBean servletRegistrationBean(){
        ServletRegistrationBean<Servlet> bean = new ServletRegistrationBean<>(new StatViewServlet(),"/druid/*");
//        账号密码配置
        Map<String, String> map = new HashMap<>();
//        增加配置loginUsername,loginPassword固定的
        map.put("loginUsername","admin");
        map.put("loginPassword","123456");
//        允许谁可以访问,逗号后面加谁就允许谁,不写就是都能访问
        map.put("allow","");
//        禁止谁能访问  map.put("91566","192.168..");
        bean.setInitParameters(map);
        return bean;
    }
    @Bean
    //        Filter
    public FilterRegistration filterRegistration(){
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new WebStatFilter());
//        可以过滤那些请求?
        Map<String, String> map = new HashMap<>();
//        这些东西不进行统计
        map.put("exclusions","*.js,*.css,/druid/*");
        bean.setInitParameters(map);
        return (FilterRegistration) bean;
    }
}
com.it.controller:JDBCController.java:
package com.it.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;
//        xxxx Template : springboot已经配置好的bean模板。直接用
@RestController
public class JDBCController {
    @Autowired
    JdbcTemplate jdbcTemplate;
//    查询数据库的所有信息
//    没有实体类,数据库的东西怎么获取,万能的Map
    @GetMapping("/userList")
    public List<Map<String,Object>> userList(){
        String sql = "select * from user";
        List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
        return maps;
    }
    @GetMapping("/addUser")  //自动提交事务
    public String addUser(){
        String sql = "insert into user (id,name,pwd) value (7,‘ssss‘,‘323232‘)";
        jdbcTemplate.update(sql);
        return "OK";
    }
    @GetMapping("/updateUser/{id}")  //自动提交事务
    public String updateUser(@PathVariable("id") int id){
        String sql = "update user set name=?,pwd=? where id=" + id;
        Object[] objects = new Object[2];
        objects[0] = "小明";
        objects[1] = "11111";
        jdbcTemplate.update(sql,objects);
        return "OK";
    }
    @GetMapping("/deleteUser/{id}")  //自动提交事务
    public String deleteUser(@PathVariable("id") int id){
        String sql = "delete from user where id=?";
        jdbcTemplate.update(sql,id);
        return "OK";
    }
}
pom依赖:
<dependencies>
        <!--Thymeleaf-->
        <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.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    </dependencies>
结构:

application.yaml:
spring:
  datasource:
    username: root
    password: 3105311
    url: jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.cj.jdbc.Driver
    #\u6574\u5408mybatis
mybatis:
  type-aliases-package: com.it.pojo
  mapper-locations: classpath:mybatis/mapper/*.xml
pojo User.java:
package com.it.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private int id;
    private String name;
    private String pwd;
}
mapper UserMapper.java:
package com.it.mapper;
import com.it.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import java.util.List;
//这个注解表示了这是一个mybatis 的mapper类
@Mapper
@Repository
public interface UserMapper {
    List<User> queryUserList();
    User queryById(int id);
    int addUser(User user);
    int updateUser(User user);
    int deleteUserById(int id);
}
resource.mybatis.mapper UserMapper.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">
<!--namespace 绑定一对应的Dao/Mapper接口 -->
<!--namespace中的名要和UserMapper.xml的接口一致-->
<mapper namespace="com.it.mapper.UserMapper">
<!--    <>中加入useCache="true",开启缓存-->
    <select id="queryUserList" resultType="User">
        select * from user
    </select>
    <select id="queryById" resultType="User">
        select * from user where id = #{id}
    </select>
    <insert id="addUser" parameterType="User">
        insert into user (id,name,pwd) value (#{id},#{name},#{pwd})
    </insert>
    <update id="updateUser" parameterType="User">
        update user set id = #{id},name = #{name},pwd = #{pwd}
    </update>
    <delete id="deleteUserById" parameterType="int">
        delete from user where id = #{id}
    </delete>
</mapper>
service UserService.java:
package com.it.service;
import com.it.pojo.User;
import java.util.List;
public interface UserService {
    List<User> queryUserList();
    User queryById(int id);
    int addUser(User user);
    int updateUser(User user);
    int deleteUserById(int id);
}
service UserServiceImpl.java:
package com.it.service;
import com.it.mapper.UserMapper;
import com.it.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Override
    public List<User> queryUserList() {
        List<User> userList = userMapper.queryUserList();
        return userList;
    }
    @Override
    public User queryById(int id) {
        return null;
    }
    @Override
    public int addUser(User user) {
        return 0;
    }
    @Override
    public int updateUser(User user) {
        return 0;
    }
    @Override
    public int deleteUserById(int id) {
        return 0;
    }
}
controller UserController.java:
package com.it.controller;
import com.it.pojo.User;
import com.it.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@Controller
public class UserController {
    @Autowired
    private UserService userService;
    @RequestMapping("/a")
    public String queryUserList(){
        List<User> userList = userService.queryUserList();
        return "";
    }
}
这样写文件夹下的页面都可以显示
加入依赖:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!--Thymeleaf-->
<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring5</artifactId>
</dependency>
<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>
yaml开启不保存缓存:
spring:
  thymeleaf:
    cache: false
com.it.config SecurityConfig.java:
package com.it.config;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//    授权的规则
    @Override
    protected void configure(HttpSecurity http) throws Exception {
//        首页所有人可以访问,功能页vip1,2,3有权限的人可以访问
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/level1/**").hasRole("vip1")
                .antMatchers("/level2/**").hasRole("vip2")
                .antMatchers("/level3/**").hasRole("vip3");
        //都要打开源码看其中的方法
        
//        没有权限,默认到login.html登录页面,需要开启登陆页面loginPage。设置前端用户名密码参数名
        http.formLogin().loginPage("/toLogin")
            .passwordParameter("password")
            .usernameParameter("username");
        
//        开启了注销功能,点注销到首页
        http.logout().logoutSuccessUrl("/");
                
//        防止网站攻击
        http.csrf().disable();
        
//        开启记住我功能,接受前端参数,实现前端自定义名字。<input type="checkbox" name="remember"> 记住我
        http.rememberMe().rememberMeParameter("remember");
        
    }
//    认证规则,inMemoryAuthentication()从内存中取,自定义了几个数据,正常是可以在数据库取。
//	  roles 授权vip1,2,3
//    密码编码:passwordEncoding,就是密码要加密
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                    .withUser("admin").password(new BCryptPasswordEncoder().encode("123")).roles("vip1","vip2")
                    .and()
                    .withUser("root").password(new BCryptPasswordEncoder().encode("123")).roles("vip3");
    }
}
pom依赖:
thymeleaf-extras-springsecurity4,需要springboot2.0.9一下
thymeleaf-extras-springsecurity5,需要springboot2.1.0以上
<!-- thymeleaf-extras-springsecurity4 -->
<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-springsecurity5</artifactId>
    <version>3.0.4.RELEASE</version>
</dependency>
命名空间:
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
html:
 <!--如果未登录,就显示登陆-->
<div sec:authorize="!isAuthenticated()">
    <a class="item" th:href="@{/toLogin}">
        <i class="address card icon"></i> 登录
    </a>
</div>
<!--如果登录,就显示登录注销-->
<div sec:authorize="isAuthenticated()">
    <a class="item" th:href="@{/logout}">
        <i class="sign-out icon"></i> 注销
    </a>
</div>
<!--如果登录,就显示用户名角色-->
<div sec:authorize="isAuthenticated()">
    用户名:<span sec:authentication="name"></span></div>
<!--如果权限是vip1,就显示第一个div,以此类推-->
<div class="column" sec:authorize="hasRole(‘vip1‘)"></div>
<div class="column" sec:authorize="hasRole(‘vip2‘)"></div>
<div class="column" sec:authorize="hasRole(‘vip3‘)"></div>
pom依赖:
    <dependencies>
        <!--Subject:用户
        SecurityManage:管理所有用户
        Realm:连接数据-->
        <!-- shiro-spring整合 -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.5.1</version>
        </dependency>
        <dependency>
            <!-- thymeleaf -->
            <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>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
config包 UserRealm.java:
package com.it.config;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
//自定义的Realm
public class UserRealm extends AuthorizingRealm {
//    授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("授权");
        return null;
    }
//    认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("认证");
        return null;
    }
}
config包 ShiroConfig.java:
package com.it.config;
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 {
//    Subject:用户 -> ShiroFilterFactoryBean:3
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
//        关联DefaultWebSecurityManager
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
        return shiroFilterFactoryBean;
    }
//    SecurityManage:管理所有用户 -> DefaultWebSecurityManager:2
    @Bean //也可以写成@Bean(name = " "),通过name就可以获取到它了
    public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
//        关联Realm
        defaultWebSecurityManager.setRealm(userRealm);
        return defaultWebSecurityManager;
    }
//    Realm:连接数据 -> 创建realm对象:1
    @Bean
    public UserRealm userRealm(){
        return new UserRealm();
}
}
原文:https://www.cnblogs.com/DavisSamuel/p/13599953.html