目录:
- 手工启动热部署
- 自动启动热部署
- 热部署范围配置
- 关闭热部署功能
- 第三方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: 0127
ApplicationTests
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.StdOutImpl
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.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也支持多连接实例一起工作.