目录:
- 手工启动热部署
- 自动启动热部署
- 热部署范围配置
- 关闭热部署功能
- 第三方bean属性绑定
- 松散绑定
- 常用计量单位应用
- bean属性校验
- 进制数据转换规则
- 加载测试专用属性
- 加载测试专用配置
- 测试类中启动web环境
- 发送虚拟请求
- 匹配响应执行状态
- 匹配响应体
- 匹配响应体(json)
- 匹配响应头
- 业务层测试事务回滚
- 测试用例设置随机数据
- 内置数据源
- JdbcTemplate
- H2数据库
- redis下载安装与基本使用
- SpringBoot整合Redis
- Springboot读写Redis的客户端
- Sprintboot操作Redis客户端实现技术切换(jedis)
1.手工启动热部署
开启开发者工具

激活热部署:Ctrl + F9
- 重启(Restart):自定义开发代码,包含类、页面、配置文件等,加载位置restart类加载器
- 重载(ReLoad):jar包,加载位置base类加载器
小结:
- 开启开发者工具后启用热部署
- 使用构建项目操作启动热部署(Ctrl+F9)
- 热部署仅仅加载当前开发者自定义开发的资源,不加载jar资源
2.自动启动热部署
 
 
ctrl+alt+shift+/

激活方式:Idea失去焦点5秒后启动热部署
热部署Idea专业版spring boot(spring mvc)项目_idea springmvc 热部署-CSDN博客
3.热部署范围配置
默认不触发重启的目录列表
- /META-INF/maven
- /META-INF/resources
- /resources
- /static
- /public
- /templates
自定义不参与重启排除项

4.关闭热部署功能
属性加载优先顺序

设置高优先级属性禁用热部署

5.第三方bean属性绑定
 
 

@EnableConfigurationProperties注解可以将使用@ConfigurationProperties注解对应的类加入Spring容器
 
 
注意事项
- @EnableConfigurationProperties.与@Component不能同时使用
解除使用@ConfigurationProperties注释警告


6.松散绑定
 
 
注意事项
- 宽松绑定不支持注解@Value引用单个属性的方式
@ConfigurationProperties绑定属性支持属性名宽松绑定

注意事项
- 绑定前缀名命名规范:仅能使用纯小写字母、数字、下划线作为合法的字符
7.常用计量单位应用
 
 
JDK8支持的时间与空间计量单位

8.bean属性校验
数据校验
- 开启数据校验有助于系统安全性,J2EE规范中7SR303规范定义了一组有关数据校验相关的API
添加JSR3日3规范坐标与Hibernate校验框架对应坐标

对Bean开启校验功能

设置校验规则

9.进制数据转换规则
字面值表达方式

application.yml
servers:
  ipAddress: 192.168.0.1
  #  ipaddress: 192.168.0.1
  #  ip_address: 192.168.0.1
  #  ip-address: 192.168.0.1
  #  IPADDRESS: 192.168.0.1
  #  IP_ADD_R-E_SS: 192.168.0.1
  port: 4444
  timeout: -1
  serverTimeOut: 3
  dataSize: 10240
dataSource:
  driverClassName: com.mysql.jdbc.Driver456
  password: 0127ApplicationTests
package com.example;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class ApplicationTests {
    @Value("${dataSource.password}")
    private String password;
    @Value("${servers.ipAddress}")
    private String msg;
    @Test
    void contextLoads() {
        System.out.println(msg);
        System.out.println(password);
    }
}
运行结果:(0127)转换成了8进制

10.加载测试专用属性
在启动测试环境时可以通过properties参数设置测试环境专用的属性

优势:比多环境开发中的测试环境影响范围更小,仅对当前测试类有效
在启动测试环境时可以通过args参数设置测试环境专用的传入参数

Sprintboot14TestApplicationTests
package com.example;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
//@SpringBootTest(properties = {"test.prop=testValue1"})
//@SpringBootTest(args = {"--test.prop=testValue2"})
@SpringBootTest(properties = {"test.prop=testValue1"}, args = {"--test.prop=testValue2"})
class Sprintboot14TestApplicationTests {
    @Value("${test.prop}")
    private String msg;
    @Test
    void contextLoads() {
        System.out.println(msg);
    }
}
application.yml
test:
  prop: testValue
11.加载测试专用配置
使用@Import注解加载当前测试类专用的配置

MsgConfig.class
package com.example.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MsgConfig {
    @Bean
    public String msg() {
        return "bean msg";
    }
}
ConfigurationTest.class
package com.example;
import com.example.config.MsgConfig;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Import;
@SpringBootTest
@Import({MsgConfig.class})
public class ConfigurationTest {
    @Autowired
    private String msg;
    @Test
    void testConfiguration() {
        System.out.println(msg);
    }
}
运行结果:

12.测试类中启动web环境
模拟端口


WebTest.class
package com.example;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class WebTest {
    @Test
    void test() {
    }
}
13.发送虚拟请求
虚拟请求测试

BookController.class
package com.example.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/books")
public class BookController {
    @GetMapping
    public String getById() {
        System.out.println("getById is running...");
        return "sprintboot";
    }
}
WebTest.class
package com.example;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@AutoConfigureMockMvc
public class WebTest {
    @Test
    void test() {
    }
    @Test
    void testWeb(@Autowired MockMvc mvc) throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        mvc.perform(builder);
    }
}
运行结果:

14.匹配响应执行状态
虚拟请求状态匹配

WebTest.class
package com.example;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.result.StatusResultMatchers;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@AutoConfigureMockMvc
public class WebTest {
    @Test
    void testWeb(@Autowired MockMvc mvc) throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        mvc.perform(builder);
    }
    @Test
    void testStatus(@Autowired MockMvc mvc) throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        ResultActions action = mvc.perform(builder);
        StatusResultMatchers status = MockMvcResultMatchers.status();
        ResultMatcher ok = status.isOk();
        action.andExpect(ok);
    }
}
15.匹配响应体
虚拟请求响应体匹配

WebTest.class
package com.example;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.ContentResultMatchers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.result.StatusResultMatchers;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@AutoConfigureMockMvc
public class WebTest {
    @Test
    void testWeb(@Autowired MockMvc mvc) throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        mvc.perform(builder);
    }
    @Test
    void testStatus(@Autowired MockMvc mvc) throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        ResultActions action = mvc.perform(builder);
        StatusResultMatchers status = MockMvcResultMatchers.status();
        ResultMatcher ok = status.isOk();
        action.andExpect(ok);
    }
    @Test
    void testBody(@Autowired MockMvc mvc) throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        ResultActions action = mvc.perform(builder);
        ContentResultMatchers content = MockMvcResultMatchers.content();
        ResultMatcher result = content.string("springboot");
        action.andExpect(result);
    }
}
16.匹配响应体(json)
虚拟请求响应体(json)匹配

BookController.class
package com.example.controller;
import com.example.domain.Book;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/books")
public class BookController {
//    @GetMapping
//    public String getById() {
//        System.out.println("getById is running...");
//        return "springboot";
//    }
    @GetMapping
    public Book getById() {
        System.out.println("getById is running...");
        Book book = new Book();
        book.setId(1);
        book.setName("springboot");
        book.setType("springboot");
        book.setDescription("springboot");
        return book;
    }
}
WebTest.class
package com.example;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.ContentResultMatchers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.result.StatusResultMatchers;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@AutoConfigureMockMvc
public class WebTest {
    @Test
    void testWeb(@Autowired MockMvc mvc) throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        mvc.perform(builder);
    }
    @Test
    void testStatus(@Autowired MockMvc mvc) throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        ResultActions action = mvc.perform(builder);
        StatusResultMatchers status = MockMvcResultMatchers.status();
        ResultMatcher ok = status.isOk();
        action.andExpect(ok);
    }
    @Test
    void testBody(@Autowired MockMvc mvc) throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        ResultActions action = mvc.perform(builder);
        ContentResultMatchers content = MockMvcResultMatchers.content();
        ResultMatcher result = content.string("springboot");
        action.andExpect(result);
    }
    @Test
    void testJson(@Autowired MockMvc mvc) throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        ResultActions action = mvc.perform(builder);
        ContentResultMatchers content = MockMvcResultMatchers.content();
        ResultMatcher result = content.json("{\"id\":1,\"name\":\"springboot\",\"type\":\"springboot\",\"description\":\"springboot\"}");
        action.andExpect(result);
    }
}
17.匹配响应头
虚拟请求响应头匹配

WebTest.class+
package com.example;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.ContentResultMatchers;
import org.springframework.test.web.servlet.result.HeaderResultMatchers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.result.StatusResultMatchers;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@AutoConfigureMockMvc
public class WebTest {
    @Test
    void testWeb(@Autowired MockMvc mvc) throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        mvc.perform(builder);
    }
    @Test
    void testStatus(@Autowired MockMvc mvc) throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        ResultActions action = mvc.perform(builder);
        StatusResultMatchers status = MockMvcResultMatchers.status();
        ResultMatcher ok = status.isOk();
        action.andExpect(ok);
    }
    @Test
    void testBody(@Autowired MockMvc mvc) throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        ResultActions action = mvc.perform(builder);
        ContentResultMatchers content = MockMvcResultMatchers.content();
        ResultMatcher result = content.string("springboot");
        action.andExpect(result);
    }
    @Test
    void testJson(@Autowired MockMvc mvc) throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        ResultActions action = mvc.perform(builder);
        ContentResultMatchers content = MockMvcResultMatchers.content();
        ResultMatcher result = content.json("{\"id\":1,\"name\":\"springboot\",\"type\":\"springboot\",\"description\":\"springboot\"}");
        action.andExpect(result);
    }
    @Test
    void testContentType(@Autowired MockMvc mvc) throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        ResultActions action = mvc.perform(builder);
        HeaderResultMatchers header = MockMvcResultMatchers.header();
        ResultMatcher contentType = header.string("Content-Type", "application/json");
        action.andExpect(contentType);
    }
    @Test
    void testGetById(@Autowired MockMvc mvc) throws Exception {
        MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
        ResultActions action = mvc.perform(builder);
        StatusResultMatchers status = MockMvcResultMatchers.status();
        ResultMatcher ok = status.isOk();
        action.andExpect(ok);
        HeaderResultMatchers header = MockMvcResultMatchers.header();
        ResultMatcher contentType = header.string("Content-Type", "application/json");
        action.andExpect(contentType);
        ContentResultMatchers content = MockMvcResultMatchers.content();
        ResultMatcher result = content.json("{\"id\":1,\"name\":\"springboot\",\"type\":\"springboot\",\"description\":\"springboot\"}");
        action.andExpect(result);
    }
}
18.业务层测试事务回滚
为测试用例添加事务,SpringBoot会对测试用例对应的事务提交操作进行回滚

如果想在测试用例中提交事务,可以通过@Rollback注解设置

19.测试用例设置随机数据
测试用例数据通常采用随机值进行测试,使用SpringBoot提供的随机数为其赋值

- ${random.int}表示随机整数
- ${random.int(10)}表示10以内的随机数
- ${random.int(10,20)}表示10到20的随机数
- 其中()可以是任意字符,例如[],!!均可
20.内置数据源
现有数据层解决方案技术选型

- 数据源:DruidDataSource
- 持久化技术:MyBatis-Plus /MyBatis
- 数据库:MySQL
格式一

格式二

SpringBoot提供了3种内嵌的数据源对象供开发者选择
- HikariCP.
- Tomcat提供DataSource.
- Commons DBCP
 
 
通用配置无法设置具体的数据源配置信息,仅提供基本的连接相关配置,如需配置,在下一级配置中设置具体设定

21.JdbcTemplate
现有数据层解决方案技术选型

- 数据源:DruidDataSource
- 持久化技术: MyBatls-Plus / MyBatis
- 数据库:MySQL
内置持久化解决方案——JdbcIemplate


JdbcTemplate配置
 
 
22.H2数据库
SpringBoot提供了3种内嵌数据库供开发者选择,提高开发测试效率
- H2
- HSQL
- Derby
导入H2相关坐标

设置当前项目为web工程,并配置H2管理控制台参数

访问用户名sa,默认密码123456
操作数据库(创建表)
 
 
设置访问数据源

H2数据库控制台仅用于开发阶段,线上项目请务必关闭控制台功能
 
 
SpringBoot可以根据url地址自动识别数据库种类,在保障驱动类存在的情况下,可以省略配置
 
 
现有数据层解决方案技术选型

 
 
BookDao.interface
package com.example.springboot_15_sql.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.springboot_15_sql.domain.Book;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface BookDao extends BaseMapper<Book> {
}
Book.class
package com.example.springboot_15_sql.domain;
import lombok.Data;
@Data
public class Book {
    private int id;
    private String name;
    private String type;
    private String description;
}
Sprintboot15SqlApplication.class
package com.example.springboot_15_sql;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Springboot15SqlApplication {
    public static void main(String[] args) {
        SpringApplication.run(Springboot15SqlApplication.class, args);
    }
}
application.yml
#server:
#  port: 8080
#
#spring:
#  datasource:
#    url: jdbc:mysql://localhost:3308/test_db
#    hikari:
#      driver-class-name: com.mysql.cj.jdbc.Driver
#      username: root
#      password: 666666
#      maximum-pool-size: 50
#mybatis-plus:
#  global-config:
#    db-config:
#      table-prefix: tbl_
#      id-type: auto
#  configuration:
#    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
server:
  port: 8080
spring:
  h2:
    console:
      enabled: true
      path: /h2
  datasource:
    url: jdbc:h2:~/test
    hikari:
      driver-class-name: org.h2.Driver
      username: sa
      password: 123456
mybatis-plus:
  global-config:
    db-config:
      table-prefix: tbl_
      id-type: auto
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImplpom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.17</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>springboot_15_sql</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot_15_sql</name>
    <description>springboot_15_sql</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--        <dependency>-->
        <!--            <groupId>com.mysql</groupId>-->
        <!--            <artifactId>mysql-connector-j</artifactId>-->
        <!--            <scope>runtime</scope>-->
        <!--        </dependency>-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--        <dependency>-->
        <!--            <groupId>com.baomidou</groupId>-->
        <!--            <artifactId>mybatis-plus-boot-starter</artifactId>-->
        <!--            <version>3.4.1</version>-->
        <!--        </dependency>-->
        <!--        <dependency>-->
        <!--            <groupId>com.alibaba</groupId>-->
        <!--            <artifactId>druid-spring-boot-starter</artifactId>-->
        <!--            <version>1.2.6</version>-->
        <!--        </dependency>-->
        <!--        <dependency>-->
        <!--            <groupId>org.springframework.boot</groupId>-->
        <!--            <artifactId>spring-boot-starter-jdbc</artifactId>-->
        <!--        </dependency>-->
        <!--        <dependency>-->
        <!--            <groupId>org.springframework.boot</groupId>-->
        <!--            <artifactId>spring-boot-starter-jdbc</artifactId>-->
        <!--        </dependency>-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.1</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <image>
                        <builder>paketobuildpacks/builder-jammy-base:latest</builder>
                    </image>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
Sprintboot15SqlApplicationTests.class
package com.example.springboot_15_sql;
import com.example.springboot_15_sql.dao.BookDao;
import com.example.springboot_15_sql.domain.Book;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
@SpringBootTest
class Springboot15SqlApplicationTests {
    @Autowired
    private BookDao bookDao;
    @Test
    void test() {
        bookDao.selectById(1);
    }
    @Test
    void testJdbcTemplate(@Autowired JdbcTemplate jdbcTemplate) {
        String sql = "select * from tbl_book";
//        List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
//        System.out.println(maps);
        RowMapper<Book> rm = new RowMapper<Book>() {
            @Override
            public Book mapRow(ResultSet rs, int rowNum) throws SQLException {
                Book temp = new Book();
                temp.setId(rs.getInt("id"));
                temp.setName(rs.getString("name"));
                temp.setType(rs.getString("type"));
                temp.setDescription(rs.getString("description"));
                return temp;
            }
        };
        List<Book> list = jdbcTemplate.query(sql, rm);
        System.out.println(list);
    }
//    @Test
//    void testJdbcTemplateSave(@Autowired JdbcTemplate jdbcTemplate) {
//        String sql = "insert into tbl_book values(null,'springboot','springboot','springboot')";
//        jdbcTemplate.update(sql);
//    }
    @Test
    void testJdbcTemplateSave(@Autowired JdbcTemplate jdbcTemplate) {
        String sql = "insert into tbl_book values(3,'springboot3','springboot3','springboot3')";
        jdbcTemplate.update(sql);
    }
}
23.redis下载安装与基本使用
市面上常见的NoSQL解决方案
- Redis
- Mongo
- ES
Redis是一款key-value存储结构的内存级NoSQL数据库
- 支持多种数据存储格式
- 支持持久化
- 支持集群
Redis下载(Windows版)
- https://github.com/tporadowski/redis/releases
Redis安装与启动( Windows版)
- Windows解压安装或一键式安装
- 服务端启动命令

- 客户端启动命令
 
 
24.SpringBoot整合Redis
导入SpringBoot整合Redis坐标

配置Redis(采用默认配置)

- 主机: localhost(默认)
- 端口:6379(默认)
RedisTemplate提供操作各种数据存储类型的接口API
 
 
客户端:RedisTemplate

 
 
pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>sprintboot_16_redis</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>sprintboot_16_redis</name>
    <description>sprintboot_16_redis</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <image>
                        <builder>paketobuildpacks/builder-jammy-base:latest</builder>
                    </image>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
application.yml
spring:
  redis:
    host: localhost
    port: 6379
Springboot16RedisApplicationTests.class
package com.example.sprintboot_16_redis;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
@SpringBootTest
class Sprintboot16RedisApplicationTests {
    @Autowired
    private RedisTemplate redisTemplate;
    @Test
    void set() {
        ValueOperations ops = redisTemplate.opsForValue();
        ops.set("age", "41");
    }
    @Test
    void get() {
        ValueOperations ops = redisTemplate.opsForValue();
        Object age = ops.get("age");
        System.out.println(age);
    }
    @Test
    void hset() {
        HashOperations ops = redisTemplate.opsForHash();
        ops.put("info", "a", "aa");
    }
    @Test
    void hget() {
        HashOperations ops = redisTemplate.opsForHash();
        Object val = ops.get("info", "a");
        System.out.println(val);
    }
}
25.Springboot读写Redis的客户端
客户端:RedisTemplate以对象作为key和value,内部对数据进行序列化

客户端: StringRedisTemplate以字符串作为key和value,与Redis客户端操作等效
 
 
StringRedisTemplateTest.class
package com.example.sprintboot_16_redis;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
@SpringBootTest
public class StringRedisTemplateTest {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Test
    void get1() {
        ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
        String name = ops.get("name");
        System.out.println(name);
    }
    @Test
    void get2() {
        ValueOperations ops = redisTemplate.opsForValue();
        Object name = ops.get("name");
        System.out.println(name);
    }
}
26.Sprintboot操作Redis客户端实现技术切换(jedis)
客户端选择:jedis

配置客户端

配置客户端专用属性
 
 
lettcus与jedis区别
- jedis连接Redis服务器是直连模式,当多线程模式下使用jedis会存在线程安全问题,解决方案可以通过配置连接池使每个连接专用,这样整体性能就大受影响。
- lettcus基于Netty框架进行与Redis服务器连接,底层设计中采用StatefulRedisConnectian。StatefulRedisConnection自身是线程安全的,可以保障并发访问安全问题,所以一个连接可以被多线程复用。当然lettcus也支持多连接实例一起工作.



















