Spring Boot (轻松创建基于Spring的应用程序)

文章目录

1、 SpringBoot基本介绍

1、官网:https://spring.io/projects/spring-boot

2、SpringBoot是什么?

第一句话: Spring Boot可以轻松创建独立的、生产级的基于Spring的应用程序
第二句话: Spring Boot直接嵌入Tomcat、Jetty或Undertow,可以"直接运行"Spring Boot应用程序

3.SpringBoot快速入门

需求:构建一个SpringBoot项目,浏览器发送/hello请求[http: //localhost:8080/hello],响应"Hello Word"

  1. 确认开发环境是jdk 8或以上,maven在3.5+,idea2022
  2. 创建空的maven项目
    在这里插入图片描述
  3. pom.xml引入SpringBoot父工程和web项目场景启动器
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.lxc</groupId>
    <artifactId>spring-boot</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <!--导入springboot父工程-规定写法[mybatis用过]-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.12</version>
    </parent>
    <!--导入web项目场景启动器:会自动导入和web开发相关的所有依赖【库/jar】-->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

</project>
  1. 创建 D:\lxc\javaProject\spring-boot\src\main\java\com\codeSE\springboot\MainApp.java
package com.codeSE.springboot;

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

/*
*
* @SpringBootApplication: 表示这是一个springboot应用/项目
 * */
@SpringBootApplication
public class MainApp {
    public static void main(String[] args) {
        //启动springboot应用程序/项目
        SpringApplication.run(MainApp.class,args);
    }
}

  1. 创建D:\lxc\javaProject\spring-boot\src\main\java\com\codeSE\springboot\controlller\helloController.java
package com.codeSE.springboot.controlller;

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

@Controller
public class HelloController {

    @RequestMapping("/hello")
    @ResponseBody
    public String hello(){
        return "hello spring boot";
    }
}

  1. 启动@SpringBootApplication
    在这里插入图片描述
    在这里插入图片描述
    快速入门小结
    1.SpringBoot 比较传统的SSM开发,简化整合步骤,提高开发效率
    2.简化了Maven项目的pom.xml依赖导入,可以说是一键导入,如图.
    在这里插入图片描述
    在这里插入图片描述

4.Spring、SpringMVC和SpringBoot的关系

4.1 梳理关系

  1. 他们的关系大概是:Spring Boot > Spring > Spring MVC
  2. Spring MVC只是Spring 处理WEB层请求的一个模块/组件,Spring MVC的基石是Servlet
  3. Spring 的核心是IOC和AOP,IOC提供了依赖注入的容器,AOP解决了面向切面编程
  4. Spring Boot是为了简化开发,推出的封神框架(约定优于配置,简化了Spring项目的配置流程),SpringBoot包含很多组件/框架,Spring就是最核心的内容之一,也包含Spring MVC
  5. Spring家族,有众多衍生框架和组件例如 boot、security、jpa等,他们的基础都是Spring

4.2 如何理解-约定优于配置

1、约定优于配置(Convention over Configuration/COC),又称按约定编程,是一种软件设计规范。本质上是对系统、类库或框架中一些东西假定一个大众化合理的默认值(缺省值)
2、例如在模型中存在一个名为User的类,那么对应到数据库会存在一个名为user的表,只有在偏离这个约定时才需要做相关的配置(例如你想将表名命名为t_user等非user时才需要写关于这个名字的配置)
3、简单来说就是假如你所期待的配置与约定的配置一致,那么就可以不做任何配置,约定不符合期待时,才需要对约定进行替换配置
4、约定优于配置理念:
约定其实就是一种规范,遵循了规范,那么就存在通用性,存在通用性,那么事情就会变得相对简单,程序员之间的沟通通成本会降低,工作效率会提升,合作也会变得更加简单

2、依赖管理和自动配置

1. 依赖管理

什么是依赖管理
1.spring-boot-starter-parent还有父项目,声明了开发中常用的依赖的版本号
2.并且进行自动版本仲裁,即如果程序员没有指定某个依赖jar的版本,则以父项目指定的版本为准
在这里插入图片描述
修改自动仲裁/默认版本号

  1. 需求说明:将SpringBoot mysql驱动修改成5.1.49
  2. 查看spring-boot-dependencies.pom里面规定当前依赖的版本对应的 key,这里是mysql.version
  3. 修改D:\lxc\javaProject\spring-boot\pom.xml重写配置,当更新Maven时,就依赖到新的mysql驱动. 也可以直接在spring-boot-dependencies.pom修改版本。
    在这里插入图片描述

2.starter场景启动器

starter场景启动器基本介绍

  1. 开发中我们引入了相关场景的starter,这个场景中所有的相关依赖都引入选来了,比如我们做web开发引入了,该starter将导入与web开发相关的所有包
  2. 依赖树∶可以看到spring-boot-starter-web,帮我们引入了spring-webmvc,spring-web开发模块,还引入了spring-boot-starter-tomcat场景,spring-boot-starter-json场景,这些场景下面又引入了一大堆相关的包,这些依赖项可以快速启动和运行一个项目,提高开发效率.
  3. 所有场景启动器最基本的依赖就是spring-boot-starter,前面的依赖树分析可以看到,这个依赖也就是SpringBoot自动配置的核心依赖

介绍

1.在开发中我们经常会用到spring-boot-starter-xxx,比如spring-boot-starter-web,该场景是用作web开发,也就是说xXX是某种开发场景。
2.我们只要引入starter,这个场景的所有常规需要的依赖我们都自动引入。
3.SpringBoot2支持的所有场景如下:
https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.build-systems.starters

第三方starter

1.SpringBopt也支持第三方starter
2.第三方starter不要从spring-boot开始,因为这是官方spring-boot保留的命名方式的。第三方启动程序通常以项目名称开头。例如,名为thirdpartyproject的第三方启动程序项目通常被命名为:
thirdpartyproject-spring-boot-starter。
3.也就是说:xxx-spring-boot-starter是第三方为我们提供的简化开发的场景启动器

3.自动配置

自动配置基本介绍

  1. 学习SSM整合时,需要配置Tomcat 、配置SpringMVC、配置如何扫描包、配置字符过滤器、配置视图解析器、文件上传等,非常麻烦。而在SpringBoot中,存在自动配置机制,提高开发效率
  2. 简单回顾以前SSM整合的配置.

SpringBoot自动配置了哪些?

  1. 自动配置Tocat
  2. 自动配置SpringMvc
  3. 自动配置Web常用功能:比如字符过滤器,提示:通过获取ioc容器,查看容器创建的组件来验证,修改
    D:\lxc\javaProject\spring-boot\src\main\java\com\codeSE\springboot\MainApp.java,运行
    在这里插入图片描述
    4.自动配置:默认扫描包结构,官方文档:
    https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.structuring-your-code.using-the-default-package
    在这里插入图片描述
    1说明:默认主程序所在的包及其子包下会被扫描
    2这就是为什么,没有配置扫描包,HelloController也会被扫描

4.修改默认配置

4.1 如何修改默认扫描包结构

1.需求:要求能扫描com.codeSE包下的HiController.java应该如何处理?
2创建: D:\lxc\javaProject\spring-boot\src\main\java\com\codeSE\HiController.java,并测试,这时是访问不到的.

package com.codeSE.springboot.controlller;

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

@Controller
public class HelloController {

    @RequestMapping("/hello")
    @ResponseBody
    public String hello(){
        return "hello spring boot";
    }
}

在这里插入图片描述

3.修改MainApp.java,增加扫描的包,并完成测试.
在这里插入图片描述

4.2 配置大全

resources\application.properties配置大全
SpringBoot项目最重要也是最核心的配置文件就是application.properties,所有的框架配置都可以在这个配置文件中说明

#修改server的监听端口
server.port=10000

#应用的上下文路径(项目路径)
server.servlet.context-path=/abc

# 修改文件上传
# 会映射/关联到MultipartProperties
# 把光标放在该属性,输入ctrl+b就可以定位这个属性是管理到哪个类(属性类)
spring.servlet.multipart.max-file-size=1024MB


# 自定义配置属性
my.website=https://www.baidu.com

...

4.3 自定义配置属性

  • 还可以在properties文件中自定义配置,通过@Value("$}")获取对应属性值
    在这里插入图片描述

在这里插入图片描述

4.4 解读SpringBoot读取配置文件application.properties

在这里插入图片描述

4.5 自动配置-—遵守按需加载原则

基本说明
1.自动配置遵守按需加载原则:也就是说,引入了哪个场景starter就会加载该场景关联的jar包,没有引入的starter则不会加载其关联jar
2. SpringBoot所有的自动配置功能都在spring-boot-autoconfigure 包里面
3.在SpringBoot的自动配置包,一般是XxxAutoConfiguration.java,对应XxxxProperties.java,如图
在这里插入图片描述

3、容器功能

1.Spring 注入组件的注解

@Component、@Controller 、@service、@Repository
说明:这些在Spring中的传统注解仍然有效,通过这些注解可以给容器注入组件

2. @Configuration

说明:演示在SpringBoot,如何通过@Configuration 创建配置类来注入组件
创建一个Monster的实体类

1.创建D:\lxc\javaProject\spring-boot\src\main\java\com\codeSE\springboot\config\BeanConfig.java

package com.codeSE.springboot.config;

import com.codeSE.springboot.bean.Monster;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

/*
* 1. @Configuration标识这是一个配置类,等价于配置文件
* 2.通过@Bean注解注入bean对象到容器,替代了原来spring使用beanXXx.xml的配置文件
* 3.当一个类被@Configuration标识,该类-Bean也会注入容器
* */
@Configuration
public class BeanConfig {

    /*
    * 1. @Bean : 给容器添加组件,就是Monster bean
    * 2. monster01() : 默认你的方法名monster01作为Bean的名字/id
    * 3. Monster : 注入类型,注入bean 的类型是Monster
    * 4. new Monster(200,"牛魔王",500,"牛魔拳"):注入到容器中具体的Bean信息
    * 5. @Bean(name = "monster-nmw") 在配置、注入Bean指定名字/id为monster-nmw
    * 6. 默认是单例注入
    * 7. 通过@Scope( "prototype")可以每次返回新的对象,就多例
     * */
    @Bean(name = "monster-nmw")
    //@Scope("prototype")
    public Monster monster01(){
        return new Monster(100,"牛魔王",545,"牛魔拳");
    }
}


测试:
在这里插入图片描述
Configuration注意事项和细节:

  1. 配置类本身也是组件,因此也可以获取,测试修改MainApp.java
    在这里插入图片描述

  2. SpringBoot2新增特性: proxyBeanMethods 指定Full模式和Lite模式
    在这里插入图片描述
    在这里插入图片描述

  3. 配置类可以有多个,就和Spring可以有多个ioc配置文件是一个道理。

package com.codeSE.springboot.config;

import com.codeSE.springboot.bean.Monster;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/*
* 第2个bean
*
* */
@Configuration
public class Configuration02 {
    @Bean
    public Monster monster02(){
        return new Monster(200,"蜘蛛精",188,"吐丝的");
    }
}

在这里插入图片描述

3. @import

先创建Cat.java和Dog.java实体类
在配置类加入
在这里插入图片描述
在这里插入图片描述

4. @Conditional介绍

1.条件装配: 满足Conditional指定的条件,则进行组件注入
2.@Conditional是一个根注解,下面有很多扩展注解

应用实例:
1.要求:演示在SpringBoot,如何通过@ConditionalOnBean来注入组件
2.只有在容器中有name = monster_fish组件时,才注入fish01,代码如图
在这里插入图片描述

5 @lmportResource

1.需求:将beans.xml导入到BeanConfig.java配置类,并测试是否可以获得beans.xml注入的组件

2.创建新的BeanConfig3.java(建议创建新的配置类)来测试,使用ImportResource导入beans.xml

package com.codeSE.springboot.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;

/*
* 导入beans.xml 文件,就T获取到beans.xml中配置bean
 *
* */
@Configuration
@ImportResource(locations = {"classpath:beans.xml","classpath:beans02.xml"})
public class BeanConfig3 {
}

3.在MainApp.java测试
··

6.配置绑定

一句话:使用Java读取到SpringBoot核心配置文件
application.properties的内容,并且把它封装到JavaBean中
应用实例
1.需求:将application.properties指定的k-v和 JavaBean 绑定

2.创建bean\Furn.java,加入注解
在这里插入图片描述

3.将application.properties指定的k-v和 JavaBean 绑定
在这里插入图片描述
4.注入到HiConreoller容器中
在这里插入图片描述
5,启动,在浏览器测试
在这里插入图片描述
6.配置绑定还有第2种方式,完成测试,效果一样,
注意:注销@Component需要在BeanConfig.java(说明:也可以是其它配置类)配置@EnableConfigurationProperties(Furn.class),否则会提示错误
在这里插入图片描述
在这里插入图片描述
注意事项和细节
1.如果application.properties有中文,需要转成unicode编码写入,否则出现乱码
去网上转码一下

2.使用@ConfigurationProperties(prefix = “furn01”)会提示如下信息,但是不会影响使用

4、【新增】分析SpringBoot底层机制【Tomcat启动分析+Spring容器初始化+Tomcat 如何关联Spring容器】

5、Lombok

  • Lombok作用
    1.简化JavaBean开发,可以使用Lombok的注解让代码更加简洁
    2.Java项目中,很多没有技术含量又必须存在的代码:POJO的getter/setter/toString;异常处理;I/O流的关闭操作等等,这些代码既没有技术含量,又影响着代码的美观,Lombok应运而生

  • SpringBoot和IDEA官方支持
    1.IDEA 2020已经内置了Lombok插件
    2.SpringBoot 2.1.x之后的版本也在Starter中内置了Lombok依赖

Lombok常用注解:
@Data注解在类上;提供类所有属性的getting 和setting方法,此外还提供了equals、canEqual、hashCode、toSting方法·
@Setter :注解在属性上;为属性提供setting方法
@Gettter注解在属性上;为属性提供getting方法
@Log4j:注解在类上;为类提供一个属性名为log 的 log4j日志对象@NoArgsConstructor :注解在类上;为类提供一个无参的构造方法
@AllArgsConstructor:注解在类上;为类提供一个全参的构造方法
@Cleanup:可以关闭流
@Builder :被注解的类加个构造者模式
@Synchronized : 加个同步锁
@SneakyThrows :等同于trylcatch捕获异常
@NonNull :如果给参数加个这个注解参数为null会抛出空指针异常
@Value :注解和@Data类似,区别在于它会把所有成员变量默认定义为private final修饰,并且不会生成set方法。

1.在pom.xml引入lombok
引入lombok,版本在spring-boot-dependencies-2.5.3.pom指定了,把光标放在lombok ctrl+b可以看到
在这里插入图片描述在这里插入图片描述

2修改Furn.java使用Lombok注解简化代码,提示:可以通过idea自带的反编译功能,看Furn.class的源码,就可以看到生成的完整代码.
在这里插入图片描述

在这里插入图片描述

3.在我们写controller或者Service层的时候,需要注入很多的mapper接口或者另外的service接口,这时候就会写很多的@Autowired注解,代码看起来很乱。
lombok提供了一个注解:
@RequiredArgsConstructor(onConstructor =@(@Autowired))
写在类上可以代替@Autowired注解,需要注意的是在注入时需要用final定义,或者使用@notnull注解

4.在idea安装lombok插件
-不装插件也可以用基本的注解,比如@Data @Getter 等
-但是不能使用其扩展功能,比如日志输出log.info()、log.debugger()…,所以我们还是安装一下,也比较简单
在这里插入图片描述

6、Spring Initailizr

  • spring Initailizr作用
    1.程序员通过Maven Archetype来生成Maven项目,项目原型相对简陋,需要手动配置,比较灵活.
    2.通过Spring官方提供的Spring Initializr 来构建Maven项目,能完美支持IDEA和Eclipse,让程序员来选择需要的开发场景(starter),还能自动生成启动类和单元测试代码
    3.Spring Initailizr对Idea版本有要求同时还要走网络,我自己还是习惯用,Maven Archetype来生成Maven项目

需求:使用Spring Initailizr创建SpringBoot项目,并支持web应用场景,支持MyBatis

方式1:IDEA创建
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

方式2: start.spring.io创建

使用官网的模板:https://start.spring.io/在这里插入图片描述

7、yaml

1 基本说明

1、YAML是"YAML Ain’t a Markup Language"(YAML不是一种标记语言)的递归缩写。在开发的这种语言时,YAML的意思其实是:“Yet Another Markup Language”(仍是一种标记语言),是为了强调这种语言以数据做为中心,而不是以标记语言为重点,而用反向缩略语重命名【百度百科】

  • 解读
    1、YAML以数据做为中心,而不是以标记语言为重点
    2、YAML仍然是一种标记语言,但是和传统的标记语言不一样,是以数据为中心的标记语言.
    3、YAML非常适合用来做以数据为中心的配置文件,【springboot : application.yml】

官方文档 https://yaml.org/
参考文档https://www.cnblogs.com/strongmore/p/14219180.html

2 yaml基本语法

1.形式为key: value;注意:后面有空格 id: 1000
2.区分大小写
3.使用缩进表示层级关系
4.缩进不允许使用tab,只允许空格〔有些地方也识别tab,推荐使用空格]
5.缩进的空格数不重要,只要相同层级的元素左对齐即可
6.字符串无需加引号

3 yaml数据类型

  • 字面量
    1.字面量:单个的、不可再分的值。date、boolean、string、number、null
    2.保存形式为key: value
monster:
	id: 100
	name:牛魔王
	age: 500
	isHarried: truebirth: 2000/10/10
	car:
	  name:宝马
	  price: 999999.9
	
  • 对象
    1.对象:键值对的集合,比如 map、 hash、set、object
#行内写法:
k: {k1:v1,k2:v2,k3:v3}
monster: {id: 100,name:牛魔王}
#或换行形式
k:
 k1: v1
 k2: v2
 k3: v3
 monster:
   id: 100
   name:牛魔王

  • 数组
    1。数组:一组按次序排列的值,比如 array、list、queue
#行内写法:
k: [v1,v2,v3]
hobby: [中国人,军人,]
#或换行形式
k:
 -v1
 -v2
 -v3
hobby:
  -中国人
  -军人
  -

应用实例:
1.创建一个新的SpringBoot项目- configuration,使用灵活配置方式创建项目
2。在pom.xml引入lombok,并切换一下springboot版本
在这里插入图片描述
3.在bean目录下新建Car.java和Monster.java

package com.codeSE.springboot02.bean;

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

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ConfigurationProperties(prefix = "monster")
@Component
@Data
public class Monster {
    private Integer id;
    private String name;
    private Integer age;
    private Boolean isMarried;
    private Date birth;
    private Car car;
    private String[] skill;
    private List<String> hobby;
    private Map<String, Object> wife;
    private Set<Double> salaries;
    private Map<String, List<Car>> cars;

}

package com.codeSE.springboot02.bean;


import lombok.Data;

@Data
public class Car {
    private String name;
    private Double price;

}

4.controller目录下新建HiController.java

package com.codeSE.springboot02.controller;

import com.codeSE.springboot02.bean.Monster;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
public class HiController {
    @Resource
    private Monster monster;

    @RequestMapping("getMonster")
    public Monster getMonster(){

        return  monster;
    }
}

5.创建入口文件

package com.codeSE.springboot02;


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);
    }
}

6.resources创建application.yml
加入这个依赖,有提示的功能在这里插入图片描述

monster:
  id: 100
  name: 猪八戒
  age: 565
  isMarried: false
  birth: 1200/12/12

  # 对象
  #car: { name: 宝马, price: 2000000}
  car:
    name: 宝马
    price: 2000000

  # 数组
  #skill: [九齿钉耙,照妖镜]
  skill:
    - 九齿钉耙
    - 照妖镜
  # list
  #hobby: [调戏,暧昧,痴情]
  hobby:
    - 调戏
    - 暧昧
    - 痴情
  # map
  #wife: {no1: 嫦娥, no2: 高小姐}
  wife:
    no1: 嫦娥
    no2: 高小姐

  # set
  #salaries: [15000,20000]
  salaries:
    - 15000
    - 20000
  # 复杂类型
  cars:
    group1:
      - {name: 奔驰,price: 300000}
      - name: 保时捷
        price: 400000
    group2:
      - { name: 坦克,price: 995000 }
      - name: 飞机
        price: 4540000




测试结果
在这里插入图片描述
注意事项和细节
1.如果application.properties和 application.yml有相同的前缀值绑定,则application.properties优先级高,开发时,应当避免
2.字符串无需加引号,如果你用’'或者""包起来,也可以的
3.解决yaml配置文件,不提示字段信息问题
在这里插入图片描述
4.如果还没有提出提示,可以安装一个yaml插件来搞定

8、WEB开发-静态资源访问

基本介绍

  1. 只要静态资源放在类路径(resources)下:/static、/public 、/resources、/META-INF/resources可以被直接访问-对应文件WebProperties.java 看源码
    在这里插入图片描述

  2. 常见静态资源:JS、css、图片(.jpg .png .gif .bmp .svg)、字体文件(Fonts)等

  3. 访问方式:默认:项目根路径/+静态资源名比如 http://localhost:8080/hi.html —设置WebMvcProperties.java

快速入门:
先创建这几个文件

在这里插入图片描述

启动,在浏览器访问
在这里插入图片描述
静态资源访问注意事项和细节:

  1. 静态资源访问原理: 静态映射是/**,也就是对所有请求拦截,请求进来,先看Controller能不能处理,不能处理的请求交给静态资源处理器,如果静态资源找不到则响应404页面
  2. 改变静态资源访问前缀,比如我们希望http://localhost:8080/codeSE/* 去请求静态资源,应用场景:静态资源访问前缀和控制器请求路径冲突
    (1)在application.yml加入
    在这里插入图片描述

(2)改了路径,测试
在这里插入图片描述
3. 改变默认的静态资源路径,比如希望在类路径下增加lxcing目录作为静态资源路径,并完成测试.

  1. 创建一个文件夹,

  2. 新增
    在这里插入图片描述

3)测试,浏览器输入http://localhost:8080/codeSE/科技.jpg[提示:没错就是这样访问pen.jpg,不是/lxcimg/pen.jpg形式,另外因为科技.jpg还是拷贝来的,一定要保证工作目录target有pen.jpg ,如果没有,请rebulid下项目,再重启项目]
4)如果你配置static-locations,原来的访问路径就被覆盖,如果需要保留,需要你再指定一下

9、Rest风格请求处理

1.Rest风格支持(使用HTTP请求方式动词来表示对资源的操作)

新建一个MonsterController.java

package com.codeSE.springboot02.controller;

import com.codeSE.springboot02.bean.Monster;
import org.springframework.web.bind.annotation.*;

@RestController
public class MonsterController {

    @RequestMapping(value = "/monster",method = RequestMethod.GET)
    public String getMonster(){
        return "GET--查询";
    }
    @PostMapping(value = "/monster")
    public String saveMonster(){
        return "POST--添加";
    }
    @PutMapping(value = "/monster")
    public String putMonster(){
        return "POST--修改";
    }
    @DeleteMapping(value = "/monster")
    public String delMonster(){
        return "POST--删除";
    }
}

测试:
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

Rest风格请求-注意事项和细节
1、客户端是PostMan可以直接发送Put、delete等方式请求,可不设置Filter
2、如果要SpringBoot支持页面表单的Rest功能,则需要注意如下细节:
1)Rest风格请求核心Filter;HiddenHttpMethodFilter,表单请求会被HiddenHttpMethodFilter拦截,获取到表单_method的值,再判断是PUT/DELETE/PATCH(注释:PATCH方法是新引入的,是对PUT方法的补充,用来对已知资源进行局部更新:https:// segmentfault.com/q/ 1010000005685904)
2)如果要SpringBoot支持页面表单的Rest功能,需要在application.yml启用filter功能,否则无效
3)修改application.yml启用filter功能

在这里插入图片描述
3.如何响应一个页面呢?
1)在任意静态资源文件目录下新建html页面
2)@RestController改为@Controller,然后
在这里插入图片描述

3)修改配置文件
描述
4)测试
在这里插入图片描述

10、接收参数相关注解

1.基本介绍

1.SpringBoot接收客户端提交数据/参数会使用到相关往解
2.详解 @PathVariable、@RequestHeader、@ModelAttribute、@RequestParam、CookieValue、@RequestBody

2. 应用实例

需求:演示各种方式提交数据/参数给服务器,服务器如何使用注解接收

package com.codeSE.springboot02.controller;

import com.codeSE.springboot02.bean.Monster;
import com.codeSE.springboot02.bean.Person;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;

@RestController
//@Controller
public class AcceptParamsController {
    /*
     /monster/{id}/{name}解读:
    1. /monster/{id}/{name}构成完整请求路径
    2. {id} {name}就是占位变量
    3. @PathVariable( "name"):这里name和name
    4. String name_这里自定义,老师故意这样写下
    5. @PathVariable Map<String,String> map把所有传递的值传入map

    * */

    @GetMapping("/monster/{id}/{name}")
    public String pathVariable(@PathVariable("id") Integer id1,
                               @PathVariable("name") String username,
                               @PathVariable Map<String, String> map) {

        System.out.println("id==" + id1);
        System.out.println("name==" + username);
        System.out.println("map==" + map);
        return "Success";

    }

    @GetMapping("/requestHeader")
    public String requestHeader(@RequestHeader("Host") String host,
                                @RequestHeader("accept") String accept,
                                @RequestHeader Map<String, String> map) {
        System.out.println("host==" + host);
        System.out.println("accept==" + accept);
        System.out.println("map==" + map);
        return "Success";
    }


    @GetMapping("/requestParam")
    public String requestParam(@RequestParam("user") String username,
                               @RequestParam("pwd") String password,
                               @RequestParam("fruit") List list,
                               @RequestParam Map<String, String> map) {
        System.out.println("username==" + username);
        System.out.println("password==" + password);
        System.out.println("list==" + list);
        System.out.println("map==" + map);
        return "Success";
    }

    /*
    * 说明
    * 1. value = "cookie_key”表示接收名字为 cookie_key 的cookie
      2.如果浏览器携带来对应的cookie,那么后面的参数是String,则接收到的是对应对vαlue
      * 3.后面的参数是Cookie ,则接收到的是封装好的对应的cookie
      *
      * 可以在浏览器手动填入cookie来测试

    * */
    @GetMapping("/requestCookie")
    public String requestCookie(@CookieValue(value = "cookie_value", required = false) String cookie,
                                @CookieValue(value = "username", required = false) String username,
                                HttpServletRequest request) {


        System.out.println("cookie==" + cookie);
        System.out.println("username==" + username);

        //也可以用原生的servlet
        Cookie[] cookies = request.getCookies();
        for (Cookie cookie1 : cookies) {
            System.out.println("使用原生servlet" + cookie1.getValue());
        }

        return "Success";
    }

    /*
    用于获取post提交请求体body的信息,
    */
    @PostMapping("/requestBody")
    public String requestBody(@RequestBody String content) {
        System.out.println("content==" + content);
        return "Success";
    }

    /*
     *  获取RequestAttribute和SessionAttribute域中的属性
     * */
    @GetMapping("/login")
    public String login(HttpServletRequest request) {
        request.setAttribute("str1", "hello123中国");
        request.getSession().setAttribute("website", "https:www.baidu.com");

        return "forward:ok";
    }

    @GetMapping("/ok")
    @ResponseBody
    public String ok(@RequestAttribute(value = "str1", required = false) String user,
                     @SessionAttribute(value = "website", required = false) String website) {
        System.out.println("RequestAttribute域中的属性==" + user);
        System.out.println("SessionAttribute域中的属性==" + website);
        return "Success";
    }

    //复复杂类:响应一个注册请求
    @GetMapping("/register")
    public String register(Map<String, Object> map,
                           Model model,
                           HttpServletResponse response) {
        // 如果一个注册请求,会将注册数据封装到map或者model
        // map中的数据和model的数据,会被放入到request中
        map.put("user", "codeSE");
        map.put("job", "java架构师");
        model.addAttribute("sal", 80000);

        //我们演示创建cookie ,并通过response添加到浏览器/客户端
        Cookie cookie = new Cookie("email", "2343323@qq.com");
        response.addCookie(cookie);

        return "forward:/registerOk";

    }

    @GetMapping("/registerOk")
    @ResponseBody
    public String registerOk(HttpServletRequest request) {
        System.out.println(request.getAttribute("user"));
        System.out.println(request.getAttribute("job"));
        System.out.println(request.getAttribute("sal"));
        return "Success";

    }
    //自定义参数接收返回数据的封装
    @PostMapping("/savePerson")
    public String savePerson(Person person){
        System.out.println("person---"+person);
        return "Success";

    }


}

3.复杂参数

基本介绍

1.在开发中,SpringBoot在响应客户端请求时,也支持复杂参数
2.MapModel、Errors/BindingResult、RedirectAttributes、ServletResponse、
SessionStatus、UriComponentsBuilder、ServletUriComponentsBuilder、HttpSession
3.Map、Model数据会被放在request域,到时Debug一下
4.RedirectAttributes重定向携带数据

4.自定义对象参数-自动封装

基本介绍

1.在开发中,SpringBoot在响应客户端/浏览器请求时,也支持自定义对象参数
2.完成自动类型转换与格式化
3.支持级联封装

11、转换器

基本介绍
1.SpringBoot在响应客户端请求时,将提交的数据封装成对象时,使用了内置的转换器
2.SpringBoot也支持自定义转换器,这个内置转换器在debug的时候,可以看到,100多个内置转换器.看下源码GenericConverter-ConvertiblePair
在这里插入图片描述

新建一个配置类WebConfig.java例如

package com.codeSE.springboot02.config;

import com.codeSE.springboot02.bean.Car;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.format.FormatterRegistry;
import org.springframework.util.ObjectUtils;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/*
*
* GConfiguration(proxyBeanMethods = false)
* 1.表示WebConfig是一个配置类
* 2. proxyBeanMethods = false使用Lite模式
* */
@Configuration(proxyBeanMethods = false)
public class WebConfig {
    //注入bean WebMvcConfigurer
    @Bean
    public WebMvcConfigurer webMvcConfigurer(){
        return new WebMvcConfigurer(){

            public void addFormatters(FormatterRegistry registry){
                 /*
                1.在addFormatters方法中,增加一个自定义的转换器
                2.增加自定义转换器String -> Car
                3.增加的自定义转换器会注册到converters容器中
                4. converters底层结构是ConcurrentHashMap内置有124或以上转换器
                * */
                registry.addConverter(new Converter<String, Car>() {
                    public Car convert(String source){
                        if(!ObjectUtils.isEmpty(source)){
                            Car car = new Car();
                            String[] split = source.split(",");
                            car.setName(split[0]);
                            car.setPrice(Double.parseDouble(split[1]));
                            return car;
                        }
                        return  null;
                    }
                });

            }
        };
    }
}


在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

具体略,较复杂

12、处理JSON

1.SpringBoot支持返回JSON格式数据,在启用WEB开发场景时,已经引入了相关依赖
在这里插入图片描述

import com.codeSE.springboot02.bean.Car;
import com.codeSE.springboot02.bean.Monster;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;

@RestController
public class ResponseJSONController {
    @GetMapping("/get/monster")
    @ResponseBody
    public Monster getMonster() {
        //开发中,monster对象是从DB获取
        Monster monster = new Monster();
        monster.setId(1002);
        monster.setName("豹子精");
        monster.setAge(677);
        monster.setIsMarried(false);
        monster.setBirth(new Date());
        Car car = new Car();
        car.setName("奔驰");
        car.setPrice(800000.98);
        monster.setCar(car);

        return monster;
    }
}

在这里插入图片描述

13、内容协商

  • 基本介绍
    1.根据客户端接收能力不同,SpringBoot返回不同媒体类型的数据
    2.比如:客户端Http请求Accept:application/xml则返回xml数据,客户端Http请求 Accept:application/json则返回json数据。

应用实例:
比如:要返回xml格式,先引入一个包

在这里插入图片描述
在这里插入图片描述
这个是浏览器默认的,
在这里插入图片描述
注意事项和使用细节
1.Postman可以通过修改Accept 的值,来返回不同的数据格式
2.对于浏览器,我们无法修改其Accept的值,怎么办?
解决方案:开启支持基于请求参数的内容协商功能
1)修改application.yml,开启基于请求参数的内容协商功能
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

14、Thymeleaf

官方英文文档:https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html

1. 基本介绍

Thymeleaf是什么?
1.Thymeleaf是一个跟VelocityFreeMarker类似的模板引擎,可完全替代JSP
2.Thymeleaf是一个java类库,他是一个xml/xhtml/html5的模板引擎,可以作为mvc的web应用view层

●Thymeleaf的优点
1.实现JSTL、OGNL表达式效果,语法相似, java程序员上手快
2.Thymeleaf模版页面无需服务器渲染,也可以被浏览器运行,页面简洁。
3.SpringBoot支持FreeMarker、Thymeleaf、veocity

●Thymeleaf的缺点
1.Thymeleaf:Thymeleaf is a modern server-side Java template engine for both web andstandalone environments
2.缺点:并不是一个高性能的引擎,适用于单体应用
3.说明:如果要做一个高并发的应用,选择前后端分离更好,但是作为SpringBoot推荐的模板引擎,还是要讲解Thymeleaf使用,这样在工作中使用到,也能搞定
4.后面还要讲Vue + ElementPlus + Axios + SpringBoot前后端分离

2. Thymeleaf机制说明

1.Thymeleaf 是服务器渲染技术,页面数据是在服务端进行渲染的
2.比如: manage.html中一段thymeleaf代码,是在用户请求该页面时,有thymeleaf模板引擎完成处理的(在服务端完成),并将结果页面返回.

3. Thymeleaf基本语法

  • 表达式

1.表达式一览

表达式名字语法用途
变量取值${…}获取请求域、session域、对象等值
选择变量*{…}获取上下文对象值
消息#{….}获取国际化等值
链接@{…}生成链接
片段表达式{~.….}jsp:include作用,引入公共页面片段

2.字面量
文本值: ‘hsp edu’, ‘hello’,…
数字:10 ,7,36.8 ,…
布尔值: true , false
空值: null
变量: name,age,…变量不能有空格
3.文本操作

字符串拼接:+
变量替换:lage= ${age}l

  • 运算符
    1.数学运算
    运算符:+,-,*,/,%
    2.布尔运算
    运算符:and , or
    一元运算:!, not
    3.比较运算
    比较: >,<, >=,<= ( gt , lt , ge , le )等式:== , != ( eq , ne )
    4.条件运算
    If-then: (if) ? (then)
    If-then-else: (if) ? (then) : (else)
    Default: (value) ?: (defaultvalue)
  • th属性

html有的属性,Thymeleaf基本都有,而常用的属性大概有七八个。其中th属性执行的优先级从1~8,数字越低优先级越高

th:text:设置当前元素的文本内容,相同功能的还有th:utext,两者的区别在于前者不会转义html标签,后者会。优先级不高: order=7
th:value:设置当前元素的value值,类似修改指定属性的还有th:src,th:href。优先级不高: order=6
th:each:遍历循环元素,和th:text或th:value一起使用。注意该属性修饰的标签位置,详细往后看。优先级很高: order=2
th:if:条件判断,类似的还有th:unless,th:switch,th:case。优先级较高: order=3
th:insert:代码块引入,类似的还有th:replace,th:include,三者的区别较大,若使用不恰当会破坏html结构,常用于公共代码块提取的场景。优先级最高: order=1
th:fragment:定义代码块,方便被th:insert引用。优先级最低: order=8
th:object:声明变量,一般和*{}一起配合使用,达到偷懒的效果。优先级一般: order=4
th:attr:修改任意属性,实际开发中用的较少,因为有丰富的其他th属性帮忙,类似的还有th:attrappend,th:attrprepend。优先级一般: order=5

  • 迭代
    在这里插入图片描述

  • 条件运算
    在这里插入图片描述

  • 使用Thymeleaf属性需要注意点

1、若要使用Thymeleaf语法,首先要声明名称空间: xmIns:th="http://www.thymeleaf.org"
2、设置文本内容 th:text,设置input的值 th:value,循环输出 th:each,条件判断 th:if,插入代码块th:insert,定义代码块th:fragment,声明变量th:object
3、th:each的用法需要格外注意,打个比方:如果你要循环一个div中的p标签,则th:each属性必须放在p标签上.。若你将th:each属性放在div上,则循环的是将整个div。
4、变量表达式中提供了很多的内置方法,该内置方法是用#开头,请不要与#{}消息表达式弄混。

4. Thymeleaf综合案例

需求说明
说明:使用SpringBoot + Thymeleaf完成简单的用户登录-列表功能
在这里插入图片描述
在静态资源新建templates目录,加入adminLogin.html、manage.html

<!DOCTYPE html>
<!--这里需要加命名空间-->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>adminLogin</title>
</head>
<body style="background-color: #cdd0fd">
<div style="text-align: center">
    <h1>用户登陆</h1>
    <form action="#" th:action="@{/adminLogin}" method="post">
        <label style="color: red" th:text="${msg}"></label><br/>
        用户名:<input type="text" style="width:150px" name="name"/><br/>
        密码:<input type="password" style="width:150px;margin: 20px 0" name="password"/><br/>
        <input type="submit" value="登录"/>
        <input type="reset" value="重新填写"/>
    </form>
</div>

</body>
</html>
<!DOCTYPE html>
<!--这里需要加命名空间-->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>manage</title>
</head>
<body>
<a href='#'>遽回管理界面</a>
<a href='#' th:href="@{/}">安全退出</a>
欢迎您:[[${session.loginInfo.name}]]

<hr/>
<div style="text-align: center">
    <h1>管理雇员~</h1>
    <table border="1px" cellspacing="0" bordercolor="green" style="width: 1600px">
        <tr bgcolor="pink">
            <td>id</td>
            <td>name</td>
            <td>pwd</td>
            <td>age</td>
            <td>email</td>
        </tr>
        <tr bgcolor="#6eb1fd" th:each="user:${users}">
            <td th:text="${user.id}">a</td>
            <td th:text="${user.name}">a</td>
            <td th:text="${user.password}">a</td>
            <td th:text="${user.age}">a</td>
            <td th:text="${user.email}">a</td>

        </tr>

    </table>


</div>

</body>
</html>

bean:
在这里插入图片描述
在这里插入图片描述

controller:

package com.codeSE.springboot02.controller;

import com.codeSE.springboot02.bean.Admin;
import com.codeSE.springboot02.bean.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

import javax.servlet.http.HttpSession;
import java.util.ArrayList;

@Controller
public class AdminController {
    //响应用户的登录请求
    @PostMapping("/adminLogin")
    public String login(Admin admin, HttpSession session, Model model) {

        System.out.println(admin);
        //将登录用户保存到session
        session.setAttribute("loginInfo",admin);


        //合法
        if (StringUtils.hasText(admin.getName()) && "666".equals(admin.getPassword())) {
            //不使用请求转发是防止刷新页面会重复提交
            //manage.html表示要去找方法的映射路径为manage.html
            return "redirect:/manage.html";

            //不合法
        } else {
            model.addAttribute("msg","账号/用户错误");
            return "adminLogin";
        }

    }

    //处理用户的请求到manage .html
    @GetMapping("manage.html")
    public String mainPage(Model model,HttpSession session) {

        System.out.println("管理页面");
        Object loginInfo = session.getAttribute("loginInfo");
        //登录过
        if(null!=loginInfo){
            //可以这里集合-模拟用户数据,放入到request域中,并显示
            ArrayList<User> users = new ArrayList<>();
            users.add(new User(1, "关羽~", "66k666", 20, "gy@sohu.com"));
            users.add(new User(2, "张飞", "666666", 30, "zf@sohu.com"));
            users.add(new User(3, "赵云", "666666 ", 22, "zy@sohu.com "));
            users.add(new User(4, "马超", "666666", 28, " mc @sohu.com"));
            users.add(new User(5, "黄忠", "666666", 50, "hz@sohu.com"));
            model.addAttribute("users", users);
            return "manage";//这里才是我们的视图解析到/templates/manage.html
        }else { //没有的登陆过
            model.addAttribute("msg","你没有登录/请登永\n");
            return  "adminLogin";
        }


    }
}


在这里插入图片描述

在这里插入图片描述

15、拦截器-Handlerlnterceptor

1.基本介绍

1.在Spring Boot项目中,拦截器是开发中常用手段,要来做登陆验证、性能检查日志记录等。
2.基本步骤:
√编写一个拦截器实现HandlerInterceptor接口
√拦截器注册到配置类中(实现WebMvcConfigureraddInterceptors)
√指定拦截规则
√回顾SpringMVC中讲解的Interceptor

注意事项和细节

1、URI和URL的区别
URI = Universal Resource Identifier
URL = Universal Resource Locator
Identifier:标识符Locator:定位器从字面上来看,URI可以唯一标识一个资源,URL可以提供找到该资源的路径
说明:
String requestURI= request.getRequestURI();
String requestURL = request.getRequestURL().toString();
2、注册拦截器,依然可以如下方式
在这里插入图片描述

16、文件上传

先来一个上传页面

<!DOCTYPE html>
<html lang="en"  xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>upload</title>
</head>
<body>
<div style="text-align: center">
    <h1>注册用户~</h1>
    <form action="#" th:action="@{/upload}" method="post" enctype="multipart/form-data">
        用户名;<input type="text" style="width:150px" name="name"/><br/><br/>
        电邮:<input type="text" style="width:150px" name="email" /><br/><br/>
        年龄:<input type="text" style="width:150px" name="age"/><br/><br/>
        职﹐位:<input type="text" style="width:150px" name="job"/><br/><br/>
        头像:<input type="file" style="width:150px" name="header"><br/><br/>
        宠物:<input type="file" style="width:150px" name="photos" multiple><br/><br/>
        <input type="submit" value="注册"/>
        <input type="reset" value="重新填写"/></form>

</div>

</body>
</html>

controller:

package com.codeSE.springboot02.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;

@Controller
@Slf4j
public class UploadController {

    //处理转发到用户注册-可以完成文件上传页面
    @GetMapping("/upload.html")
    public String gotoRegister() {
        log.info("注册上传页面");
        return "upload";
    }

    //处理用户的注册请求包括文件上传
    @PostMapping("/upload")
    @ResponseBody
    public String upload(@RequestParam("name") String name,
                         @RequestParam("email") String email,
                         @RequestParam("age") Integer age,
                         @RequestParam("job") String job,
                         @RequestParam("header") MultipartFile header,
                         @RequestParam("photos") MultipartFile[] photos
    ) throws IOException {
        log.info("上传数据");
        log.info("上传的信息: name={} email={} age={} job={} header={} photos={}",
                name, email, age, job, header, photos);


        //如果信息都成功得到,我们就将文件保存到指定的目录,比如D://temp_upload
        // 1.我们先将文件保存到指定的目录比如D://temp_upload
        // 2.把文件保存到动态创建的目录.如:
        // D:\lxc\javaProject\spring-boot02\target\classes\static\images\temp_upload

        //得到运行是路径
        String path = ResourceUtils.getURL("classpath:").getPath();
        log.info("path={}",path);// path=/D:/lxc/javaProject/spring-boot02/target/classes/

        File file = new File(path + "static/images/temp_upload/");
        if(!file.exists()){ //如果目录不存在,我们就创建
            file.mkdirs();

        }

        //处理头像图片
        if(!header.isEmpty()){
            String originalFilename = header.getOriginalFilename();
            //header.transferTo(new File("D:\\temp_upload\\"+originalFilename));
            log.info("保存文件的绝对路径=" +file.getAbsolutePath());
            header.transferTo(new File(file.getAbsolutePath()+"/"+originalFilename));
        }
        //处理多个图片
        if(photos.length>0){
            for (MultipartFile photo : photos) {
                if(!photo.isEmpty()){
                    String originalFilename = photo.getOriginalFilename();
                    //photo.transferTo(new File("D:\\temp_upload\\"+originalFilename));
                    photo.transferTo(new File(file.getAbsolutePath()+"/"+originalFilename));
                }
            }
        }

        return "注册用户成功/文件上传成功";
    }
}

如果用了前面的拦截器,就需要加入放行
在这里插入图片描述
注意:
SpringBoot默认上传文件大小不能超过1MB,超过之后会报以下异常,需要配置大小限制

Request processing failed; nested exception is org.springframework.web.multipart.MaxUploadSizeExceededException: Maximum upload size exceeded; nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.impl.FileSizeLimitExceededException: The field header exceeds its maximum permitted size of 1048576 bytes.] with root cause

解决后效果:
在这里插入图片描述

17、异常处理

介绍

1.默认情况下,Spring Boot提供/error处理所有错误的映射,也就是说当出现错误时,SpringBoot底层会请求转发到/error这个映射
2.比如使用浏览器访问不存在接口(路径映射),响应一个"whitelabel"错误视图,以HTML格式呈现的给用户,
在这里插入图片描述

3.SpringBoot底层默认由DefaultErrorViewResolve处理错误-Debug一下.
在这里插入图片描述

拦截器和过滤器

1、使用范围不同
1)过滤器实现的是javax.servlet.Filter接口,而这个接口是在Servlet规范中定义的,也就是说过滤器Filter的使用要依赖于Tomcat等容器,Filter只能在web程序中使用
2)拦截器(Interceptor)它是一个Spring组件,并由Spring容器管理,并不依赖Tomcat等容器,是可以单独使用的。不仅能应用在web程序中,也可以用于Application等程序中
2、过滤器和拦截器的触发时机也不同,看下边这张图
在这里插入图片描述
1)过滤器Filter是在请求进入容器后,但在进入servlet之前进行预处理,请求结束是在servlet处理完以后
2)拦截器Interceptor 是在请求进入servlet后,在进入Controller之前进行预处理的,Controller中渲染了对应的视图之后请求结束
3、说明:过滤器不会处理请求转发,拦截器会处理请求转发,原因是请求转发是在servlet组件执行的。

自定义异常页面

需求:自定义404.html 500.html 4xx.html 5xx.html当发生相应错误时,显示自定义的页面信息
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>4xx</title>
</head>
<body>
<h1>我的自定义4xx页面</h1>
<a href='#' th:href="@{/}">返回主页面</a><br/>
状态码:
<h1 th:text=" ${status}"></h1><br/>
错误信息: <h1 th:text="${error}"></h1>
</body>
</html>

其余三个一样

controller:

package com.codeSE.springboot02.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

@Controller
public class MyErrorController {
    //模拟一个服务器内部错误500
    @GetMapping("/err")
    public String err() {
        int i = 10 / 0;
        return "manage";

    }
    @PostMapping("/err2")
    public String err2() {
        //..
        return "manage";

    }
}

在这里插入图片描述

全局异常

说明
1.@ControllerAdvice和@ExceptionHandler处理全局异常
2.底层是ExceptionHandlerExceptionResolver支持的
需求:
1.需求:演示全局异常使用,当发生ArithmeticException、NullPointerException时,不使用默认机制匹配的xxx.html,而是显示全局异常机制指定的错误页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>自定义全局异常</title>
</head>
<body>
 <h1>
     自定义全局异常----
 </h1>
<h2 th:text="${msg}">

</h2>
</body>
</html>
package com.codeSE.springboot02.exception;

import lombok.extern.slf4j.Slf4j;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
/*
* @ControllerAdvice:使用它可以标识一个全局异常处理器/对象,并注入容器
* */
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

    /*
      //1、编写方法,处理指定异常,比如我们处理算术异常
      //2.这里要处理的异常,由程序员来指定
      //3.Exception e :表示异常发生后,传递的异常对象
      //4.Model model:可以将我们的异常信息,放入model,并传递给显示页面

    * */
    @ExceptionHandler({ArithmeticException.class,NullPointerException.class})
    public String handleAritException(Exception e, Model model) {

        log.info("异常信息={}",e.getMessage());
        //将发生的异常信息放入到model,可以再错误页面取出显示
        model.addAttribute("msg",e.getMessage());
        return "/error/global";

    }
}

注意:
1.因为全局异常处理优先级≥默认异常处理机制
2.所以会进人到global.html而不是500.html
在这里插入图片描述

自定义异常

说明
1.如果Spring Boot提供的异常不能满足开发需求,程序员也可以自定义异常.
2.@ResponseStatus + 自定义异常
3.底层是ResponseStatusExceptionResolver,底层调用response.sendError(statusCode,resolvedReason);
4.当抛出自定义异常后,仍然会根据状态码,去匹配使用xxx.html显示,当然也可以将自定义异常,放在全局异常处理器去处理
应用实例:
1、需求:自定义一个异常AccessException,当用户访问某个无权访问的路径时,抛出该异常,显示自定义异常状态码2、执行效果如图,浏览器http:// localhost:8080/err3

package com.codeSE.springboot02.exception;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
/*
* value = HttpStatus .FORBIDDEN:表示发生AccessException异常,我们通过http协议返回的状态码
* 这个状态码和自定义异常的对应关系是由程序员来决定[尽量合理来设置]

 * */
@ResponseStatus(value = HttpStatus.FORBIDDEN)
public class AccessException extends RuntimeException{
    public AccessException(){}

    //提供一个构造器,可以指定信息
    public AccessException(String message) {
        super(message);
    }
}

在这里插入图片描述在这里插入图片描述
注意事项和细节
1、如果把自定义异常类型,放在全局异常处理器,那么仍然走全局异常处理机制

18、注入Servlet、Filter、Listener

1、基本介绍

1.考虑到实际开发业务非常复杂和兼容,Spring-Boot支持将Servlet、Filter、
Listener注入Spring容器,成为Spring bean
2.也就是说明Spring-Boot开放了和原生WEB组件(Servlet、Filtei、Listener)的兼容

2、应用实例1,使用注解注入Servlet、Filter、Listener

2.1 注入Servlet

package com.codeSE.springboot02.servlet;

import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/*
1.通过继承HttpServlet 来开发原生的Servlet
2.@WebServlet标识将Servlet_对象/bean注入到容器
3. (urlPatterns = {"/servlet01", " /servlet02"} ,对servlet配置了url-pattern
4.提示:注入的原生的Servlet_,不会被spring-boot的拦截器拦截
5.对于开发的原生的Servlet ,需要使用@ServletComponentScan指定要扫描的原生Servlet包及子包
*
* */
@WebServlet(urlPatterns = {"/servlet01","/servlet02"})
public class Servlet_ extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("hello,servlet!!!");
    }
}

在启动类加入

package com.codeSE.springboot02;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;

///要求扫描com.codeSE.springboot02包/子包下的原生方式注入的Servlet
@ServletComponentScan(basePackages = "com.codeSE.springboot02")
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        ApplicationContext ioc = SpringApplication.run(Application.class, args);
        System.out.println(ioc);
    }
}

测试:
2

2.2、注入Filter

package com.codeSE.springboot02.servlet;

import lombok.extern.slf4j.Slf4j;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/*
* 1. @WebFilter表示Filter_是一个过滤器,并注入容器
* 2. urlPatterns = {" /css/*","/images/*"} 请求 该匹配的
* 3.是直接放行后,在经过拦截器,拦截器是否拦截要根据拦截器的拦截规财

 *
* */
@Slf4j
@WebFilter(urlPatterns = {"/css/*","/images/*","/test"})
public class Filter_ implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
       log.info("Filter_------init()执行");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("Filter_------doFilter()执行");

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        log.info("过滤器处理的uri={}",request.getRequestURI());

        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {
        log.info("Filter_------destroy()执行");

    }
}

在这里插入图片描述

2.3 注入Listener

package com.codeSE.springboot02.servlet;

import lombok.extern.slf4j.Slf4j;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

@Slf4j
@WebListener
public class Listener_ implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        log.info("Listener_....contextInitialized() 初始化OK");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        log.info("Listener_.....contextDestroyed 销毁OK");

    }
}

在这里插入图片描述

应用实例2-使用RegistrationBean注入

首先注释方式1的注解方式

package com.codeSE.springboot02.config;


import com.codeSE.springboot02.servlet.Filter_;
import com.codeSE.springboot02.servlet.Listener_;
import com.codeSE.springboot02.servlet.Servlet_;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Arrays;

/*
 * RegisterConfig_ :一个配置类
 * (proxyBeanMethods = true 默认是单例返回bean
 * */
@Configuration(proxyBeanMethods = true)
public class RegisterConfig_ {
    //注入Servlet
    /*
     *以使用RegistrationBean方式注入Servlet
     * */
    @Bean
    public ServletRegistrationBean servlet_() {
        //创建原生的Servlet对象
        Servlet_ servlet_ = new Servlet_();
        //把servlet_对象关联到ServletRegistrationBean 对象
        //"servlet01","/servlet02"就是注入的Servlet的url-pattern
        return new ServletRegistrationBean(servlet_, "/servlet01", "/servlet02");
    }

    //注入filter
    public FilterRegistrationBean filter_() {
        Filter_ filter_ = new Filter_();
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(filter_);
        //设置filter的url-pattern
        filterRegistrationBean.setUrlPatterns(Arrays.asList("/css/*", "/images/*", "/test"));

        return filterRegistrationBean;
    }

    //注入Listener
    @Bean
    public ServletListenerRegistrationBean listener_() {
    //创建原生的Listener
        Listener_ listener_ = new Listener_();
        return new ServletListenerRegistrationBean(listener_);
    }

}

请求Servlet时,为什么不会到达拦截器
1.请求Servlet时,不会到达DispatherServlet,因此也不会达到拦截器
2.原因分析
√注入的Servlet会存在Spring容器
√DispatherServlet也存在Spring容器
在这里插入图片描述
3.Tomcat在对Servlet url匹配的原则,多个servlet都能处理优先原则/最长前缀匹配原则.

19、内置Tomcat配置和切换

基本介绍
1.SpringBoot支持的webServer,Tomcat, Jetty, or Undertow
2.SpringBoot应用启动是Web应用时。web场景包-导入tomcat
3.支持对Tomcat(也可以是Jetty . Undertow)的配置和切换

内置Tomcat常用配置:
在这里插入图片描述
通过类来配置Tomcat
1.通过类来配置Tomcat(说明:配置文件可配置的更全.)

package com.codeSE.springboot02.config;

import org.springframework.boot.web.server.ConfigurableWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.stereotype.Component;

/*
* 通过类来配置Tomcat
 * */
@Component
public class CustomizationBean implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {

    @Override
    public void customize(ConfigurableServletWebServerFactory server) {
        server.setPort(10000);//设置端口
        //其他还有更多...
    }
}

2 切换undertow

在这里插入图片描述
在这里插入图片描述

20、数据库操作

springboot默认是用jdbc+HikariDataSource来操作数据库
说明:HlikariDataSource:目前市面上非常优秀的数据源,是springboot2默认数据源

1、Jdbc HiKariDatasource实例:

1.进行数据库开发,在pom.xml引入data-jdbc-starter
2.Spring Boot不知道项目要操作Mysql还是Oracle ,需要在pom.xml指定导入数据库驱动,并指定对应版本.
在这里插入图片描述

3.配置文件

在这里插入图片描述

4.如何要开发springboot测试类,我们需要引入 test starter
在这里插入图片描述
测试

package com.codeSE.springboot02;
/*
 * Springboot开发测试类
 *
 * */

import com.codeSE.springboot02.bean.Furn;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.annotation.Resource;
import java.util.List;

@SpringBootTest
public class ApplicationTests {
    @Resource
    private JdbcTemplate jdbcTemplate;

    @Test
    public void contextLoads() {
        BeanPropertyRowMapper<Furn> rowMapper = new BeanPropertyRowMapper<>(Furn.class);
        List<Furn> furnList = jdbcTemplate.query("SELECT * FROM furn", rowMapper);
        for (Furn furn : furnList) {
            System.out.println(furn);
        }
		//看看底层使用的是什么数据源类型[HiKariDatasource]
        System.out.println(jdbcTemplate.getDataSource().getClass());
    }
}

在这里插入图片描述

2. 整合Druid到spring

Druid:性能优秀,Druid提供性能卓越的连接池功能外【Java基础】,还集成了SQL监控,黑名单拦截等功能,强大的监控特性,通过Druid提供的监控功能,可以清楚知道连接池和SQL的工作情况,所以根据项目需要,我们也要掌握Druid和SpringBoot整合

官方文档:https://github.com/alibaba/druid/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98

来一个配置类DruidDataSourceConfig.java

package com.codeSE.springboot02.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

/*
*  Druid 配置类
*
* */
@Configuration
public class DruidDataSourceConfig {
    @ConfigurationProperties("spring.datasource")
    @Bean
    public DataSource dataSource(){
        //1.配置了@ConfigurationProperties( "spring.datasource" )就可以读取到application.yml的配置
        //2.我们就不需要调用DruidDataSource对象的setXxx,会自动关联
        DruidDataSource druidDataSource = new DruidDataSource();

        return druidDataSource;
    }
}


在这里插入图片描述

3.Durid监控功能

-SQL监控 -Web关联监控 -SQL防火墙 -Session监控

● 方式1:自定义方式

package com.codeSE.springboot02.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
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.sql.DataSource;
import java.sql.SQLException;
import java.util.Arrays;

/*
 *  Druid 配置类
 *
 * */
@Configuration
public class DruidDataSourceConfig {
    @ConfigurationProperties("spring.datasource")
    @Bean
    public DataSource dataSource() throws SQLException {
        //1.配置了@ConfigurationProperties( "spring.datasource" )就可以读取到application.yml的配置
        //2.我们就不需要调用DruidDataSource对象的setXxx,会自动关联
        DruidDataSource druidDataSource = new DruidDataSource();

        //加入监控功能、sql防火墙功能
        druidDataSource.setFilters("stat,wall");
        return druidDataSource;
    }

    //配置druid的监控页功能
    @Bean
    public ServletRegistrationBean statViewServlet() {
        //创建StatViewServlet
        StatViewServlet statViewServlet = new StatViewServlet();
        ServletRegistrationBean<StatViewServlet> registrationBean = new ServletRegistrationBean<>(statViewServlet, "/druid/*");

        //
        registrationBean.addInitParameter("loginUsername", "root");
        registrationBean.addInitParameter("loginPassword", "123456");

        return registrationBean;
    }

    //配置WebStatFilter,用于采集web-jdbc关联的监控数据
    @Bean
    public FilterRegistrationBean webStatFilter() {

        //创建WebStatFilter
        WebStatFilter webStatFilter = new WebStatFilter();
        FilterRegistrationBean<WebStatFilter> filterRegistrationBean =
                new FilterRegistrationBean<>(webStatFilter);
        //默认对所有的url请求进行监控
        filterRegistrationBean.setUrlPatterns(Arrays.asList("/*"));
        //排除指定的url
        filterRegistrationBean.addInitParameter("exclusions", ".js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");

        return filterRegistrationBean;
    }
}

controller:

package com.codeSE.springboot02.controller;

import com.codeSE.springboot02.bean.Furn;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.util.List;

@Controller
public class DruidsqlController {

    @Resource
    private JdbcTemplate jdbcTemplate;

    @ResponseBody
    @GetMapping("/sql")
    public List<Furn> crudDB(){

        BeanPropertyRowMapper<Furn> rowMapper = new BeanPropertyRowMapper<>(Furn.class);

        List<Furn> furnList = jdbcTemplate.query("SELECT * from furn", rowMapper);
        for (Furn furn : furnList) {
            System.out.println(furn);
        }

        return furnList;
    }

}

浏览器访问:http://localhost:8080/druid/index.html 登录
在这里插入图片描述
在这里插入图片描述

● 方式二:引入starter方式
具体实现
1.修改pom.xml注销druid的依赖
在这里插入图片描述

2.注销/config/DruidDataSourceConfig.java
3. 引入starter 依赖
文档:https://github.com/alibaba/druidhttps://github.com/alibaba/druid/tree/master/druid-spring-boot-starter
在这里插入图片描述
在配置文件application.yml中加入
在这里插入图片描述
浏览器访问,依然能
在这里插入图片描述

21、Spring Boot整合MyBatis

1.引入mybatis依赖
在这里插入图片描述
2.新建D:\lxc\javaProject\spring-boot02\src\main\resources\mapper\FurnMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.codeSE.springboot02.mapper.FurnMapper">
<select id="getFurnById" parameterType="Integer" resultType="Furn">
    select * from furn where id=#{id}
</select>
    <select id="getFurnAll" resultType="Furn">
        select * from furn
    </select>
</mapper>


3.新建D:\lxc\javaProject\spring-boot02\src\main\java\com\codeSE\springboot02\mapper\FurnMapper.java

package com.codeSE.springboot02.mapper;

import com.codeSE.springboot02.bean.Furn;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

/*
*在EMapper接口使用@Mapper就会扫描,并将Mapper接口对象注入
 * */
@Mapper
public interface FurnMapper {

    public Furn getFurnById(Integer id);

    public List<Furn> getFurnAll ();
}

4.在配置文件
在这里插入图片描述

5、service层

package com.codeSE.springboot02.service;

import com.codeSE.springboot02.bean.Furn;

import java.util.List;

public interface FurnService {
    public Furn getFurnById(Integer id);
    public List<Furn> getFurnAll();
}

package com.codeSE.springboot02.service.impl;

import com.codeSE.springboot02.bean.Furn;
import com.codeSE.springboot02.mapper.FurnMapper;
import com.codeSE.springboot02.service.FurnService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

@Service
public class FurnServiceImpl implements FurnService {

    //装配FurnMapper
    @Resource
    private FurnMapper furnMapper;

    @Override
    public Furn getFurnById(Integer id) {
        return furnMapper.getFurnById(id);
    }

    @Override
    public List<Furn> getFurnAll() {
        return furnMapper.getFurnAll();
    }
}

6.测试类


package com.codeSE.springboot02;
/*
 * Springboot开发测试类
 *
 * */

import com.codeSE.springboot02.bean.Furn;
import com.codeSE.springboot02.mapper.FurnMapper;
import com.codeSE.springboot02.service.FurnService;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;

import javax.annotation.Resource;
import java.util.List;

@SpringBootTest
public class ApplicationTests {
    @Resource
    private JdbcTemplate jdbcTemplate;

    @Resource
    private FurnMapper furnMapper;

    @Resource
    private FurnService furnService;

    @Test
    public void t1() {
        BeanPropertyRowMapper<Furn> rowMapper = new BeanPropertyRowMapper<>(Furn.class);
        List<Furn> furnList = jdbcTemplate.query("SELECT * FROM furn", rowMapper);
        for (Furn furn : furnList) {
            System.out.println(furn);
        }
        //看看底层使用的是什么数据源类型[HiKariDatasource]
        System.out.println(jdbcTemplate.getDataSource().getClass());

    }
    @Test
    public void getFurnById(){
        Furn furn = furnMapper.getFurnById(30);
        System.out.println("furn=="+furn);
    }
    @Test
    public void getFurnById2(){
        Furn furn = furnService.getFurnById(1);
        System.out.println("furn=="+furn);
    }
}

7.controller层

package com.codeSE.springboot02.controller;

import com.codeSE.springboot02.bean.Furn;
import com.codeSE.springboot02.service.FurnService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;

@RestController
public class FurnController {

    @Resource
    private FurnService furnService;

    @GetMapping("/getFurnById")
    public Furn getFurnById(@RequestParam(value = "id") Integer id){
       return furnService.getFurnById(id);
    }
    @GetMapping("/getFurnAll")
    public List<Furn> getFurnAll(){
        return furnService.getFurnAll();
    }
}

在这里插入图片描述

22、Spring Boot整合MyBatis-Plus

文档:https://baomidou.com/

1.基本介绍

1.MyBatis-Plus(简称MP)是一个MyBatis 的增强工具,在MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
2强大的 CRUD操作:内置通用Mapper、通用Service,通过少量配置即可实现单表大部分CRUD操作,更有强大的条件构造器,满足各类使用需求
在这里插入图片描述

2.新开一个maven空项目

1。引入必要的文件后,加入
在这里插入图片描述
2. 配置yml

server:
  port: 9090
spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8
    driver-class-name: com.mysql.jdbc.Driver
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  1. 新建bean
package codeSE.springBootMybatisPlus.bean;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;

import java.util.Date;
@Data
public class Monster {
    private Integer id;
    private Integer age;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    private Date birthday;
    private String email;
    private String name;
    private String gender;
    private Double salary;

}
  1. 新建mapper
package codeSE.springBootMybatisPlus.mapper;

import codeSE.springBootMybatisPlus.bean.Monster;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.mapper.Mapper;
/*
* 1.BaseMapper 已经默认提供了很多的crud方法,可以直接使用
* 2.如果BaseMapper提供的方法不能满足业务需求,我们可以再开发新的方法,并在MonsterMapper.xml进行
* 并在MonsterMapper.xml进行配置==>使用插件开发
* */
@org.apache.ibatis.annotations.Mapper
public interface MonsterMapper extends BaseMapper<Monster> {


}


  1. 新建测试
package codeSE.springBootMybatisPlus;

import codeSE.springBootMybatisPlus.bean.Monster;
import codeSE.springBootMybatisPlus.mapper.MonsterMapper;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;

@SpringBootTest
public class ApplicationTest {
    @Resource
    private MonsterMapper monsterMapper;

    @Test
    public void t1(){
        Monster monster = monsterMapper.selectById(1);
        System.out.println(monster);
    }
}


在这里插入图片描述
在mybatis-plus中service层的变化:

package codeSE.springBootMybatisPlus.service;

import codeSE.springBootMybatisPlus.bean.Monster;
import com.baomidou.mybatisplus.extension.service.IService;
import org.springframework.stereotype.Service;

/*
*
*  1.传统方式在接口中定义方法|声明方法,然后在实现类中进行实现
*  2.在mybatis-plus中,我们可以继承父接口 IService
*  3.这个IService接口声明很多方法,比如crud
*  4.如果默认提供方法不能满足需求,我们可以再声明需要的方法,然后在实现类中进行实现即可
* */

public interface MonsterService extends IService<Monster> {

}

package codeSE.springBootMybatisPlus.service.impl;

import codeSE.springBootMybatisPlus.bean.Monster;
import codeSE.springBootMybatisPlus.mapper.MonsterMapper;
import codeSE.springBootMybatisPlus.service.MonsterService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

/*
1.传统方式:在实现类中直接进行implements MonsterService
2.在mybatis-plus中,我们开发Service实现类,需要继承ServiceImpl
3.我们观察看到 ServiceImpl类实现IService接口
4. MonsterService接口他继承了IService接口
5.这里MonsterServiceImpl就可以认为是实现了MonsterService接口,
  这样MonsterServiceImpl,就可以使用IService接口方法,也可以理解成可以使用MonsterService方法
6,如果MonsterService接口中,声明了其它的方法自定义方法,那么我们依然需要在MonsterServiceImpl类,进行实现

*
* */
@Service
public class MonsterServiceImpl
        extends ServiceImpl<MonsterMapper, Monster>
        implements MonsterService {
}

在controller层:

import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.util.List;

@Controller
public class MonsterController {
    @Resource
    private MonsterService monsterService;

    @GetMapping("/monster")
    @ResponseBody
    public Monster getMonsterById(@RequestParam(value = "id") Integer id){

        return monsterService.getById(id);
    }
    @GetMapping("/monsterAll")
    @ResponseBody
    public List<Monster> getMonsterAll(){

        return monsterService.list();
    }
}

浏览器http://localhost:9090/monsterAll
在这里插入图片描述
@MapperScan使用
在这里插入图片描述

3.整合MyBatis-Plus注意事项和细节

  1. @TableName 作用
    在这里插入图片描述

如果这个类名Monste和表名monster一致,可以映射上,则@TableName可以省略如果这个类名Monster和表名不一致,不能映射上,则可以通过@TableName指定
2. MyBatis-Plus starter到底引入了哪些依赖?
在这里插入图片描述
3.为了开发方便,可以安装MyBatisX插件,
参考文档:https://baomidou.com/pages/ba5b24/
在这里插入图片描述

23、

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦境之冢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值