Springboot2.5学习笔记-1

三更草堂

参考三更老师笔记,仅供学习使用,侵删。


1.Springboot是什么?

  • 简化ssm
  • 对spring的进一步封装。
  • 提供了新特性:内嵌web容器,准备好的特性:指标,健康检查,外部化配置。
  • 最大特点:自动装配,起步依赖。

2.文档

  • 推荐学习新技术的快速入门
  • 不要通读文档,许多用不到

3.清理Maven的小脚本(小技巧)

  • 当网络不好或者其他原因时,maven下载的依赖不全或出错,进而导致项目出现问题。

  • 所以需要这个小脚本来清理lastupdated文件夹,省去自己操作的繁琐。

  • 如何使用?:创建.bat脚本文件,将代码换成自己的本地仓库地址,运行。

  • @echo off
    rem create by NettQun

    rem 这里写你的仓库路径(只有这里需要更改)
    set REPOSITORY_PATH=E:\Develop\maven_rep
    rem 在搜索..
    for /f “delims=” %%i in (‘dir /b /s “%REPOSITORY_PATH%*lastUpdated*”‘) do (
    echo %
    del /s /q “%%i”
    )
    rem 搜索完毕
    pause


4.创建工程以及准备环境

  1. 创建empty project
  2. 创建模块moudle,选择maven
  3. 注意java8,maven3.5以上版本

5.快速入门

  1. 继承父工程

    1
    2
    3
    4
    5
    <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.5.0</version>
    </parent>
  2. 添加依赖

    1
    2
    3
    4
    5
    6
    <dependencies>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    </dependencies>
  3. 创建启动类

    • 创建一个包com.xxx

    • 在包中创建一个类并且加上@SpringBootApplication注解,标识为启动类

    1
    2
    3
    4
    5
    6
    @SpringBootApplication
    public class HelloApplication{
    public static void main(string[]args){
    SpringApplication.run (HelloApplication.class,args);
    }
    }

    SpringApplication.run (类名(字节码对象),args(main方法中的参数))

    1. 各种层要创建在启动类所在的包及其子包下

    2. 在各种层加上注解,如控制层就为@controller

    3. 在控制层内的方法上添加注解@ResultMapping("/xxx")指定请求地址

    4. 小细节:如果一个方法返回字符串,默认是会跳转到这个页面的,如果不想让他跳转而只想显示字符串内容:在方法上再添加@ResponseBody注解。

      • 还可以优化一下:如果所有返回字符串的方法都想显示在网页上,可以在类上添加注解@controller
      • 还可以优化,此时这个类上有@controller和@ResponseBody两个注解,可以优化成@RestController注解。
    5. 启动,输入localhost:8080/+@RestController中的路径,发送请求。

    6. 因为加上了@Response注解,所有响应的值会在响应体中看到,浏览器f12即可查看。

      • controller层:
      1
      2
      3
      4
      5
      6
      7
      @RestController
      public class HelloController{
      @RequestMapping("/hel1o")
      public string hello(){
      return "hello";
      }
      }
    7. 运行启动类的main方法即可


6.常见问题以及解决方法

  1. 404无法访问:controller放在启动类所在包及其子包下
  2. 依赖爆红:配置阿里云镜像

7.SpringBoot打包部署方式

  1. 添加maven插件
1
2
3
4
5
6
7
8
9
<build>
<plugins>
<!--springboot打包插件-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
  1. maven生命周期package打包,提示build success打包成功,去找打的包所在位置
  2. 在jar包所在的目录下进行cmdjava -jar jar包名称命令进行打包
    • 如果在打包过程中不小心点击到哪儿导致进度暂停(因为开启了快速编辑模式,点击页面使cmd认为要进行快速编辑),按下ctrl+c可继续进行

8.SpringBoot项目的快速搭建

  1. 在项目中创建新模块(moudle),选择Spring Initializr
  2. 选择default(本质是spring官方提供的快速生成网站),next,设置对应信息
  3. next,选择要添加的依赖Lombok,spring web, jdbc等。完成。
  4. 更推荐之前的方式

9.起步依赖:依赖冲突及解决方案

  1. 依赖冲突:一般程序在运行时发生类似于java.lang.ClassNotFoundException,Method not found:’…….’,或者莫名其妙的异常信息,这种情况一般很大可能就是j包依赖冲突的问题引起的了。一般在是A依赖C(低版本),B也依赖C(高版本)。都是他们依赖的又是不同版本的C的时候会出现。

  2. 解决方案:

    • 如果出现了类似于java.lang.ClassNotFoundException,Method not found:这些异常检查相关的依赖冲突问
      题,排除掉低版本的依赖,留下高版本的依赖。
    • 点击maven的image-20221226231940947图标,即可查看依赖关系,会有红线方便排查项目。
    • maven helper插件,在idea底部也可以显示:进入插件,选中红色报错,右键exclude即可解决。image-20221226232426284
    • 然后refresh刷新
    • 原理?->添加exclusions排除标签
  3. 版本锁定:

    • 比如:以下这个依赖没有写版本号,为什么呢?

    • ```xml

      org.springframework.boot spring-boot-starter-parent 2.5.1 org.springframework.boot spring-boot-starter-web
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16

      - 因为父工程的dependency父工程已经规定好了,避免依赖冲突,并且好写。默认用父工程版本号

      - 也可以在子工程依赖中添加version标签,或者子工程properties标签下的xxx.version标签规定版本号,一般来说用父工程版本就行了。

      ```xml
      <properties>
      <aspectj.version>1.7.2</aspectj.version
      </properties>

      <dependencies>
      <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      </dependency>
      </dependencies>
  4. starter机制

    • 当我们需要使用某种功能时只需要引入对应的starterl即可。一个starter针对一种特定的场景,其内部引入了该
      场景所需的依赖。这样我们就不需要单独引入多个依赖了。

    • 命名规律:

      • 官方starter都是以spring-boot-starter开头后面跟上场景名称。例如:spring-boot-starter-data-jpa

      • 非官方starterl则是以场景名-spring-boot-starter的格式,例如:mybatis-spring-boot-starter

      • 官方不加版本号,非官方加

      • 比如:下面这个starter包含许多依赖

      • ```xml

        org.springframework.boot spring-boot-starter-web
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28

        -----

        ## 10.自动配置

        1. 约定优于配置:自动进行默认配置,不用做大量配置
        2. 如果有需要想要修改默认配置,可以修改这部分配置
        3. 如何自定义?源码解析

        ---

        ## 11.YAML/YML

        1. 简介:.yml后缀文件,序列化格式,专门用来写配置文件的语言,完成xml的任务,更简洁。

        2. 语法:

        - `k: v`的键值对关系,**冒号后必须跟一个空格**。

        - 空格缩进表示层级,缩进多少不重要,**左对齐的一列数据是同一层级数据。**

        如:

        ```yaml
        student:
        name: sangeng
        age: 15
        #name和age就是同一层级
    • 大小写敏感,缩进不允许tab,只允许空格,idea可以空格。

    • java的驼峰命名,再yml中和-一样:lastName=last-name

    • 单引号不专义(只转义特殊字符),双引号转义。

    • 日期: 年/月/日

    • 对象:属性和值,Map:键值对

      1
      2
      3
      4
      5
      6
      7
      #多行写法
      student:
      name: sangeng
      age: 15

      #行内写法
      student: {name: zhangsan,age: 20}
    • 数组,list,set

      1
      2
      3
      4
      5
      6
      7
      8
      9
      # 多行写法
      pets:
      - dog
      - pig
      - cat
      # 行内
      pets: [dog,pig,cat]

      #注意 - xxx的空格,注意pets: []的空格
    • 对象数组、对象list、对象set

      1
      2
      3
      4
      5
      6
      students:
      - name: zhangsan #多行
      age: 22
      - name: lisi
      age: 20
      - {name: wangwu,age: 18} #行内
    • 占位符赋值

      使用 ${key:defaultValue} 的方式来赋值,若key不存在,则会使用defaultValue来赋值。

      1
      2
      3
      4
      server:
      port: ${myPort:88}

      myPort: 80

    12.SpringBoot读取YML配置

    1. @Value注解:此注解只能获取简单类型的值(8种基本数据类型及其包装类,String,Date)

      1
      2
      student:
      lastName: liming
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      @RestController
      public class TestController {
      @Value("${student.lastName}")
      private String lastName;
      @RequestMapping("/test")
      public String test(){
      System.out.println(lastName);
      return "hi";
      }
      }

      注意:加了@Value的类必须是交由Spring容器管理的(也就是说,必须有@RestController注解)

    2. @ConfigurationProperties注解:解决了@Value注解单个单个标注的弊端。 在类上添加注解@Component(将这个类注册到spring容器中)和@ConfigurationProperties(prefix = “配置前缀”)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      @Data
      @AllArgsConstructor
      @NoArgsConstructor
      @Component
      @ConfigurationProperties(prefix = "student")
      public class Student {
      private String lastName;
      private Integer age;
      }

      注意事项:要求对应的属性要有set/get方法,并且key要和成员变量名一致才可以对应的上。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      @RestController
      public class TestController {
      @Autowired
      private Student student;
      @RequestMapping("/test")
      public String test(){
      System.out.println(student);
      return "hi";
      }
      }
    3. lombok小使用

      • 安装插件,导入依赖
      • 以下注解放在实体类上
      • @Data:生成getter/setter方法
      • @AllArgsConstructor:提供全参构造
      • @NoArgsConstructor:提供无参构造
    4. yml小细节:

      • yaml和properties可以相互转换,转换网站:https://www.toyaml.com/index.html

      • 配置提示:springboot会提醒你加配置提示

        image-20221228160110149

        1
        2
        3
        4
        5
        6
        <!--打开网站添加注解-->
        <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
        <optional>true</optional>
        </dependency>

        添加了之后重启一下项目(运行一下程序)就会有yml配置提示

      • 工作中最常用的是配置其他框架的配置:千万注意数据类型!配置时ctrl按住左键,点进去,查看数据类型,填写正确的数据类型。

12.热部署

  1. dev-tools:启动时间短,重启更快

  2. idea自动编译打开,然后允许程序运行期间自动重启

  3. 添加依赖

    1
    2
    3
    4
    5
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <optional>true</optional>
    </dependency>
  4. 触发自动编译:打开其他软件(比如浏览器)小小等待一下,idea在后台自动编译。

  5. 没触发的话build project或者ctrl+f9

13.SpringBoot整合Junit

  1. 添加依赖

    1
    2
    3
    4
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
    1. 编写测试类:写在test文件夹下的java文件夹中创建包,要与启动类的结构一致(因为SpringBoot是从启动类所在的路径开始扫描文件的)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    import com.sangeng.controller.HelloController;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;

    @SpringBootTest//如果测试类放的包的位置不对可以将注解改成指定启动类如:@SpringBootTest(classes = Application.class)
    public class ApplicationTest {

    @Autowired
    private HelloController helloController;

    @Test
    public void testJunit(){
    System.out.println(1);
    System.out.println(helloController);
    }
    }
    1. 测试类的作用:就是从spring容器中获取mapper或者service来测试功能,需要获取一下:就是@Autowired或者@Resource自动注入一下。后面一般是测试service。

    2. 如何兼容老版本?(junit4和junit5差别较大):2.2.0之前的springboot就是默认junit4,怎么兼容呢?—>

    • 将原来的import的路径删掉,引入旧的。
    • @SpringBootTest注解下添加一个@RunWith(SpringRunner.class)注解,才能在容器中获取的到

    老版本如何兼容新版本?

    image-20221229102118768image-20221229103255010

    • 所以我们需要添加vintage依赖来兼容

      1
      2
      3
      4
      5
      <dependency>
      <groupId>org.junit.vintage</groupId>
      <artifactId>junit-vintage-engine</artifactId>
      <scope>test</scope>
      </dependency>
    • 加好了之后,老版本自动兼容,直接运行就好

    • 总之:org.junit.Test对应的是Junit4的版本,就搭配@RunWith注解来使用。使用场景:之前代码是老版本不想做过多修改就用这套方法。新项目不用管。

14.SpringBoot整合MyBatis

  1. 准备工作:创建数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    /*Table structure for table `user` */
    DROP TABLE IF EXISTS `user`;
    CREATE TABLE `user` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `username` varchar(50) DEFAULT NULL,
    `age` int(11) DEFAULT NULL,
    `address` varchar(50) DEFAULT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;

    /*Data for the table `user` */

    insert into `user`(`id`,`username`,`age`,`address`) values (2,'pdd',25,'上海'),(3,'UZI',19,'上海11'),(4,'RF',19,NULL),(6,'三更',14,'请问2'),(8,'test1',11,'cc'),(9,'test2',12,'cc2');

    /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
    /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
    /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
    /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
  2. 创建对应实体类

  3. 整合mybatis

    • 添加依赖:注意需要自己写版本号(因为不是官方的),查看官方文档写版本号,github: https://github.com/mybatis/spring-boot-starter/

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      <!--mybatis启动器-->
      <dependency>
      <groupId>org.mybatis.spring.boot</groupId>
      <artifactId>mybatis-spring-boot-starter</artifactId>
      <version>2.2.0</version>
      </dependency>
      <!--mysql驱动-->
      <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <scope>runtime</scope>
      </dependency>
    • 在yaml配置数据库信息:

      1
      2
      3
      4
      5
      6
      spring:
      datasource:
      url: jdbc:mysql://localhost:3306/test?characterEncoding=utf-8&serverTimezone=UTC
      username: root
      password: root
      driver-class-name: com.mysql.cj.jdbc.Driver
    • 配置mybatis相关配置:

      1
      2
      3
      mybatis:
      mapper-locations: classpath:mapper/*Mapper.xml # mapper映射文件路径
      type-aliases-package: com.sangeng.domain # 配置哪个包下的类有默认的别名
    • 写接口在com.xxx.mapper包中:注意加上@Mapper 和@Repository这俩注解

      1
      2
      3
      4
      5
      6
      //注意加上这俩注解
      @Repository
      @Mapper
      public interface UserMapper {
      public List<User> findAll();
      }
    • 编写/mybatisx插件生成在resource/mapper文件夹中,编写mapper接口对应的xml文件xxMapper

      1
      2
      3
      4
      5
      6
      7
      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
      <mapper namespace="com.sangeng.mapper.UserMapper">
      <select id="findAll" resultType="com.sangeng.domain.User">
      select * from user
      </select>
      </mapper
    • 编写junit测试:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      @SpringBootTest(classes = HelloApplication.class)
      public class SpringMyTest {

      @Autowired
      UserMapper userMapper;


      @Test
      public void tesMapper(){
      System.out.println(userMapper.findAll());
      }
      }
    • 注:idea小问题(虽然运行没问题)–>因为视频在测试的时候mapper接口没有添加**@Repository注解,springboot找不到注入的对应的bean,实际上mybatis整合包帮我们自动注入了已经。—>解决方法,加@Repository注解**:标识是什么层(比如controller加@Controller注解),把对应的对象放到spring容器中。

      image-20221229120554458