• Springboot学习笔记——3


    一、热部署

    1.1、手动启动热部署

    • 开启开发者工具
    <dependency>
    	<groupId>org.springframework.bootgroupId>
    	<artifactId>spring-boot-devtoolsartifactId>
    	<optional>trueoptional>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 激活热部署:Ctrl + F9

    • 关于热部署

      • 重启(Restart):自定义开发代码,包含类、页面、配置文件等,加载位置restart类加载器
      • 重载(ReLoad):jar包,加载位置base类加载器

    1.2、自动启动热部署

    • 设置自动构建项目
      在这里插入图片描述

    在这里插入图片描述

    • IDEA失去焦点5秒以后启动热部署

    1.3、热部署范围配置

    • 默认不触发重启的目录列表

      • /META-INF/maven
      • /META-INF/resources
      • /resources
      • /static
      • /public
      • /templates
    • 自定义不参与重启排除项

    devtools:
    	restart:
    		exclude: public/**,static/**
    
    • 1
    • 2
    • 3

    1.4、关闭热部署

    • 设置高优先级属性禁用热部署
    @SpringBootApplication
    public class SsmpApplication {
    	public static void main(String[] args) {
    		System.setProperty("spring.devtools.restart.enabled","false");
    		SpringApplication.run(SsmpApplication.class);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    二、配置高级

    2.1、第三方bean属性绑定

    • 使用@ConfigurationProperties为第三方bean绑定属性
    @Bean
    @ConfigurationProperties(prefix = "datasources")
    public DruidDataSource dataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        return dataSource;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    datasources:
      driverClassName: com.mysql.cj.jdbc.Driver
    
    • 1
    • 2
    • @EnableConfigurationProperties注解可以将使用@ConfigurationProperties注解对应的类加入Spring容器
    @SpringBootApplication
    @EnableConfigurationProperties(serverConfig.class)
    public class Springboot0701Application {
        @Bean
        @ConfigurationProperties(prefix = "datasources")
        public DruidDataSource dataSource(){
            DruidDataSource dataSource = new DruidDataSource();
            return dataSource;
        }
        public static void main(String[] args) {
            ConfigurableApplicationContext run = SpringApplication.run(Springboot0701Application.class, args);
            DruidDataSource dataSource= run.getBean(DruidDataSource.class);
            System.out.println(dataSource.getDriverClassName());
            serverConfig serverConfig = run.getBean(serverConfig.class);
            System.out.println(serverConfig.toString());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    //@Component
    @Data
    @ConfigurationProperties(prefix = "servers")
    public class serverConfig {
        private String ipAddress;
        private int port;
        private long timeout;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    注意事项

    @EnableConfigurationProperties和@Component不能同时使用

    • 解除使用@ConfigurationProperties注释警告
      在这里插入图片描述
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-configuration-processorartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4

    2.2、松散绑定

    • ConfigurationProperties绑定属性支持属性名宽松绑定
    public class serverConfig {
        private String ipAddress;
        private int port;
        private long timeout;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 以下格式都支持
    ip-Address: 189.176.0.1
    ip_Address: 189.176.0.1
    ipaddress: 189.176.0.1
    IPADDRESS: 189.176.0.1 # 常量模式
    ip-address: 189.176.0.1 # 烤肉串模式
    
    • 1
    • 2
    • 3
    • 4
    • 5

    注意事项

    宽松绑定不支持注解@Value引用单个属性的方式

    2.3、常用计量单位应用

    • Springboot支持JDK8提供的时间与空间计量单位
    @Component
    @Data
    @ConfigurationProperties(prefix = "servers")
    public class serverConfig {
        private String ipAddress;
        private int port;
        private long timeout;
        @DurationUnit(ChronoUnit.HOURS)
        private Duration serverTimeout;
        @DataSizeUnit(DataUnit.MEGABYTES)
        private DataSize dataSize;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

    2.4、bean属性校验

    • 开启数据校验有助于系统安全性,J2EE规范中JSR303规范定义了一组有关数据校验相关的API
    1. 添加3SR303规范坐标与Hibernate校验框架对应坐标
    <dependency>
        <groupId>javax.validationgroupId>
        <artifactId>validation-apiartifactId>
    dependency>
    
    <dependency>
        <groupId>org.hibernate.validatorgroupId>
        <artifactId>hibernate-validatorartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    1. 对Bean开启校验功能
    @Component
    @Data
    @ConfigurationProperties(prefix = "servers")
    //2. 开启对当前bean的属性注入校验
    @Validated
    public class serverConfig {
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1. 设置校验规则
    @Component
    @Data
    @ConfigurationProperties(prefix = "servers")
    //2. 开启对当前bean的属性注入校验
    @Validated
    public class serverConfig {
    
        private String ipAddress;
    
        //3.设置具体的规则
        @Max(value = 8888,message = "最大值不能超过8888")
        @Min(value = 202,message = "最小值不能小于202")
        private int port;
    
        private long timeout;
        @DurationUnit(ChronoUnit.HOURS)
        private Duration serverTimeout;
        @DataSizeUnit(DataUnit.MEGABYTES)
        private DataSize dataSize;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    2.5、进制数据转换规则

    • 字面值表达式导致出现问题
    int: 0123 # 会判断为八进制的123导致转换出现问题
    
    • 1

    注意yaml文件中对于数字的定义支持进制书写格式,如需使用字符串请使用引号明确标注

    string: "0123"
    
    • 1

    三、测试

    3.1、加载测试专用属性

    • 启动测试环境时可以通过properties参数设置测试环境专用的属性
    //properties属性可以为当前测试用例添加临时的属性配置
    @SpringBootTest(properties = {"test.prop=testValue2"})
    public class propertiesAndArgsTest {
        @Value("${test.prop}")
        private String msg;
        @Test
        void testProperties(){
            System.out.println(msg);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 优势:比多环境开发中的测试环境影响范围更小,仅对当前测试类有效
    • 在启动测试环境时可以通过args参数设置测试环境专用的传入参数
    //args属性可以为当前测试用例添加临时的命令行参数
    SpringBootTest(args = {"--test.prop=testValue3"})
    public class propertiesAndArgsTest {
        @Value("${test.prop}")
        private String msg;
    
        @Test
        void testProperties(){
            System.out.println(msg);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    3.2、加载测试类专用配置

    • 使用@Import注解加载当前测试类专用的配置
    @SpringBootTest
    @Import({MsgConfig.class})
    public class ConfigTest {
        @Autowired
        private String msg;
        @Test
        void test1(){
            System.out.println(msg);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 可以加载测试范围配置应用于小范围测试环境

    3.3、测试类中启动web环境

    • 模拟端口
    package com.smulll;
    
    import org.junit.jupiter.api.Test;
    import org.springframework.boot.test.context.SpringBootTest;
    
    @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
    class Springboot0801ApplicationTests {
    
        @Test
        void contextLoads() {
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3.4、发送虚拟请求

    • 虚拟请求测试
    @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
    //开启虚拟MVC调用
    @AutoConfigureMockMvc
    class Springboot0801ApplicationTests {
        @Test
        void testWeb(@Autowired MockMvc mvc) throws Exception {
            //创建虚拟请求,当前访问/books
            MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
            //执行请求
            ResultActions perform = mvc.perform(builder);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3.5、匹配响应执行状态

    • 虚拟请求状态匹配
    @Test
    void testStatus(@Autowired MockMvc mvc) throws Exception {
        //创建虚拟请求,当前访问/books
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        //执行请求
        ResultActions perform = mvc.perform(builder);
        //设置预期值与真实值进行比较,测试成功通过,失败测试停止
        //定义本次调用的预期值
        StatusResultMatchers status = MockMvcResultMatchers.status();
        //预计本次调用的成功值,状态200
        ResultMatcher ok = status.isOk();
        //添加预计值到本次调用过程中进行匹配
        perform.andExpect(ok);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    3.6、匹配响应体

    • 虚拟请求体匹配
    @Test
    void testBody(@Autowired MockMvc mvc) throws Exception {
        //创建虚拟请求,当前访问/books
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        //执行请求
        ResultActions perform = mvc.perform(builder);
        //设置预期值与真实值进行比较,测试成功通过,失败测试停止
        //定义本次调用的预期值
        ContentResultMatchers content = MockMvcResultMatchers.content();
        //预计本次调用执行结果
        ResultMatcher result = content.string("springboot");
        //添加预计值到本次调用过程中进行匹配
        perform.andExpect(result);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 虚拟请求体(json)匹配
    @Test
    void testJSON(@Autowired MockMvc mvc) throws Exception {
        //创建虚拟请求,当前访问/books
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        //执行请求
        ResultActions perform = mvc.perform(builder);
        //设置预期值与真实值进行比较,测试成功通过,失败测试停止
        //定义本次调用的预期值
        ContentResultMatchers content = MockMvcResultMatchers.content();
        //预计本次调用执行结果
        ResultMatcher result = content.json("{\n" +
                "    \"id\": 1,\n" +
                "    \"type\": \"springboot\",\n" +
                "    \"name\": \"springboot\",\n" +
                "    \"description\": \"springboot\"\n" +
                "}");
        //添加预计值到本次调用过程中进行匹配
        perform.andExpect(result);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    3.7、匹配响应头

    • 虚拟请求头匹配
    @Test
    void testContentType(@Autowired MockMvc mvc) throws Exception {
        //创建虚拟请求,当前访问/books
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        //执行请求
        ResultActions perform = mvc.perform(builder);
        //设置预期值与真实值进行比较,测试成功通过,失败测试停止
        //定义本次调用的预期值
        HeaderResultMatchers Header = MockMvcResultMatchers.header();
        //预计本次调用执行结果
        ResultMatcher string = Header.string("Content-Type", "application/json");
        //添加预计值到本次调用过程中进行匹配
        perform.andExpect(string);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    3.8、业务层测试事务回滚

    • 为测试用例添加事务,SpringBoot会对测试用例对应的事务提交操作进行回滚
    @SpringBootTest
    @Transactional
    public class TestSave {
        @Autowired
        private bookServer bookServer;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 如果想在测试用例中提交事务,可以通过@Rollback注解设置
    @SpringBootTest
    @Transactional
    @Rollback(false)
    public class TestSave {
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3.9、测试用例设置随机数据

    • 测试用例数据通常采用随机值进行测试,使用SpringBoot提供的随机数为其赋值
    testcase:
      book:
        id: ${random.int}
        name: ${random.value}		#随机字符串,MDS字符串,32位
        type: ${random.int(10,100)}
        uuid: ${random.uuid}		#随机uuid
        publishTime: ${random.long}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • ${random.int}表示随机整数
    • ${random.int(10)}表示10以内的随机数
    • ${random.int(10,20)}表示10到20的随机数
    • 其中()可以是任意字符,例如[]!!均可

    四、数据层解决方案

    4.1、SQL

    4.1.1、内置数据源

    • 现有数据层解决方案技术选型
    Druid + MyBatis-Plus + MySQL
    
    • 1
    • 数据源:DruidDataSource
    • 持久化技术:MyBatis-Plus+MyBatis
    • 数据库:MySQL
    • SpringBoot提供了3种内嵌的数据源对象供开发者选择
      • HikariCP:默认内置数据源对象
      • Tomcat提供DataSource:HikariCP不可用的情况下,且在web环境中,将使用tomcat服务器配置的数据源对象
      • Commons DBCP:Hikari不可用,tomcat数据源也不可用,将使用dbcp数据源
    spring:
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/springbootbase?serverTimezone=UTC
        username: root
        password: 123456
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 通用配置无法设置具体的数据源配置信息,仅提供基本的连接相关配置,如需配置,在下一级配置中设置具体设定
    spring:
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/springbootbase?serverTimezone=UTC
        username: root
        password: 123456
        hikari:
        	maximum-pool-size: 50
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    4.1.2、jdbcTemplate

    • 内置持久化解决方案——JdbcTemplate
    @SpringBootTest
    class Springboot0901ApplicationTests {
    
        @Test
        void testJdbc(){
            String sql = "select * from tb_book where id=1";
            List<Book> list = jdbcTemplate.query(sql, new RowMapper<Book>() {
                @Override
                public Book mapRow(ResultSet rs, int rowNum) throws SQLException {
                    Book book = new Book();
                    book.setId(rs.getInt("id"));
                    book.setName(rs.getString("name"));
                    book.setType(rs.getString("type"));
                    book.setDescription(rs.getString("description"));
                    return book;
                }
            });
            System.out.println(list);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-jdbcartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    spring:
    jdbc:
    	template:
    		query-timeout: -1	#查询超时时间
    		max-rows: 500		#最大行数
    		fetch-size: -1 		#缓存行数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    4.1.3、H2数据库

    • springBoot提供了3种内嵌数据库供开发者选择,提高开发测试效率

      • H2
      • HSQL
      • Derby
    • 导入H2相关坐标

    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-data-jpaartifactId>
    dependency>
    <dependency>
        <groupId>com.h2databasegroupId>
        <artifactId>h2artifactId>
        <scope>runtimescope>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 设置当前项目为web工程,并配置H2管理控制台参数
    server: 
    	port: 80
    spring:
    	h2:
    		console: 
    			path: /h2
    			enabled: true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 访问用户名sa,默认密码123456
      在这里插入图片描述
    • 设置访问的数据源
    server:
      port: 80
    spring:
      h2:
        console:
          path: /h2
          enabled: true
      datasource:
        driver-class-name: org.h2.Driver
        url: jdbc:h2:~/test
        username: sa
        password: 123456
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • H2数据库控制台仅用于开发阶段,线上项目请务必关闭控制台功能
    server:
      port: 80
    spring:
      h2:
        console:
          path: /h2
          enabled: false
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    4.2、NoSQL

    4.2.1、redis下载安装与基本使用

    • Redis是一款key-value存储结构的内存级NoSQL数据库

      • 支持多种数据存储格式
      • 支持持久化
      • 支持集群
    • redis下载
      redis下载(Windows)

    • 安装启动

      • Windows解压安装或一键式安装
      • 服务端启动命令
      redis-server.exe redis.windows.conf
      
      • 1
      • 客户端启动命令
      redis-cli.exe
      
      • 1

    4.2.2、springboot整合redis

    • 导入SpringBoot整合Redis坐标
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-data-redisartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 配置Redis(采用默认配置)
    spring:
      data:
        redis:
          host: localhost
          port: 6379
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 主机:localhost(默认)
    • 端口:6379(默认)
    • RedisTemplate提供操作各种数据存储类型的接口API
      在这里插入图片描述
    • 客户端:RedisTemplate
    @SpringBootTest
    class Springboot10RedisApplicationTests {
    
        @Autowired
        private RedisTemplate redisTemplate;
    
        @Test
        void set() {
            ValueOperations valueOperations = redisTemplate.opsForValue();
            valueOperations.set("age",19);
        }
    
        @Test
        void get(){
            ValueOperations valueOperations = redisTemplate.opsForValue();
            Object o = valueOperations.get("age");
            System.out.println(o);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    4.2.3、Springboot读写Redis的客户端

    • StringRedisTemplate以字符串作为key和value,与Redis客户端操作等效
    @SpringBootTest
    public class RedisTest {
        @Autowired
        private StringRedisTemplate stringRedisTemplate;
        @Test
        void Demo1(){
            ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
            System.out.println(ops.get("name"));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    4.2.4、springboot操作Redis客户端实现技术切换(jedis)

    • 配置客户端
    spring:
      data:
        redis:
          host: localhost
          port: 6379
          client-type: jedis
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 配置客户端专用属性
    spring:
      data:
        redis:
          host: localhost
          port: 6379
          client-type: jedis
          lettuce:
            pool:
              max-active: 16
          jedis:
            pool:
              max-active: 16
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • lettcus与jedis区别
      • jedis连接Redis服务器是直连模式,当多线程模式下使用jedis会存在线程安全问题,解决方案可以通过配置连接池使每个连接专用,这样整体性能就大受影响。
      • lettcus基于Netty框架进行与Redis服务器连接,底层设计中采用StatefulRedisConnection。StatefulRedisConnection自身是线程安全的,可以保障并发访问安全问题,所以一个连接可以被多线程复用。当然lettcus也支持多连接实例一起工作。

    4.2.5、Mongodb

    • MongoDB是一个开源、高性能、无模式的文档型数据库。NoSQL数据库产品中的一种,是最像关系型数据库的非关系型数据库
    • 淘宝用户数据
      • 存储位置:数据库
      • 特征:永久性存储,修改频度极低
    • 游戏装备数据、游戏道具数据
      • 存储位置:数据库、Mongodb
      • 特征:永久性存储与临时存储相结合、修改频度较高
    • 直播数据、打赏数据、粉丝数据
      • 存储位置:数据库、Mongodb
      • 特征:永久性存储与临时存储相结合,修改频度极高
    • 物联网数据
      • 存储位置:Mongodb
      • 特征:临时存储,修改频度飞速

    4.2.6、Mongodb下载与安装

    • Windows版Mongo下载
    • Windows版Mongo安装
      • 解压后设置数据目录
    • Windows版Mongo启动
      • 服务端启动
      mongod --dbpath=..\data\db
      
      • 1
      • 客户端启动
      mongo --host=127.0.8.1 --port=27017
      
      • 1
  • 相关阅读:
    LeetCode 3 无重复字符的最长子串
    华为机试 - 滑动窗口最大和
    【数字逻辑】——逻辑函数及其简化(学习笔记)
    Spring使用注解进行注入
    Java反射用例:
    QT5.14.2+cmake3.8.2+opencv3.4.0环境配置遇到的问题
    BENTLY 350015 127610-01数字量输入模块
    VS2019 编译Postgrsql 的windows平台代码和调试
    SpringCloud 框架以及各组件总结
    子线程渲染技术和AC自动机
  • 原文地址:https://blog.csdn.net/weixin_74155781/article/details/133660749