SpringBoot学习笔记(三)

测试

加载测试专用属性

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

@SpringBootTest(poperties = {
    
    "test.prop=testValue1"})
public class PropertiesAndArgsTest {
    
    
	@Value("${test.prop}")
	private String msg;

	@Test
	void testProperties(){
    
    
		System.out.println(msg);
	}
}
  • 优势:比多环境开发中的测试坏境影响范围更小,仅对当前测试类有效

在启动测试环境时可以通过args参数设置测试环境专用的传入参数

@SpringBootTest(args = {
    
    "--test.prop=testValue2"})
public class PropertiesAndArgsTest {
    
    
	@Value("${test.arg}")
	private String msg;

	@Test
	void testProperties(){
    
    
		System.out.println(msg);
	}
}

加载测试专用配置

使用@Import注解加载当前测试类专用的配置

@Configuration
public class MsgConig {
    
    
	
	@Bean
	public String msg() {
    
    
		return "bean msg";
	}
}
@SpringBootTest
@Import(MsgConfig.class)
public class ConfigurationTest {
    
    
	@Autowired
	private String msg;
	@Test
	void testConfiguration(){
    
    
		System.out.println(msg);
	}
}

总结:

加载测试范围配置应用于小范围测试环境

Web环境模拟测试

模拟端口

@SpringBootTest(webEnviroment = SpringBootTest.WebEnviroment.RANDOM_PORT)
public class WebTest {
    
    
	@Test
	void testRandomPort () {
    
    
	}
}

虚拟请求测试

@RestController
@RequestMapping("/books")
public class BookController {
    
    
	
	@GetMapping
	public String getById(){
    
    
		System.out.println("getById is running......");
		return "springboot";
	}
}
@SpringBootTest(webEnviroment = SpringBootTest.WebEnviroment.RANDOM_PORT)
//开启虚拟MVC调用
@AutoConfigureMockMvc
public class WebTest {
    
    
	@Test
	//注入虚拟MVC调用对象
	void testRandomPort (@Autowired MockMvc mvc) throws Exception {
    
    
			//创建虚拟请求,当前访问/books
			MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
			//执行请求
			mvc.perform(builder);
	}
}

虚拟请求状态匹配

@SpringBootTest(webEnviroment = SpringBootTest.WebEnviroment.RANDOM_PORT)
//开启虚拟MVC调用
@AutoConfigureMockMvc
public class WebTest {
    
    
	@Test
	//注入虚拟MVC调用对象
	void testRandomPort (@Autowired MockMvc mvc) throws Exception {
    
    
			//创建虚拟请求,当前访问/books
			MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
			//执行请求
			ResultActions action = mvc.perform(builder);
			//匹配执行状态(是否预期值)
			//定义执行状态匹配器
			StatusResultMatchers status = MockMvcResultMatchers.status();
			//定义预期执行状态
			ResultMatcher ok = status.isOk();
			//使用本次真实执行结果与预期结果进行对比
			action.andExpect(ok);
	}
}

匹配响应体

@SpringBootTest(webEnviroment = SpringBootTest.WebEnviroment.RANDOM_PORT)
//开启虚拟MVC调用
@AutoConfigureMockMvc
public class WebTest {
    
    
	@Test
	//注入虚拟MVC调用对象
	void testRandomPort (@Autowired MockMvc mvc) throws Exception {
    
    
			//创建虚拟请求,当前访问/books
			MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
			//执行请求
			ResultActions action = mvc.perform(builder);
			//匹配执行结果(是否预期值)
			//定义执行结果匹配器
			ContentResultMatchers content = MockMvcResultMatchers.content();
			//定义预期执行结果
			ResultMatcher result = content.string("springboot");
			//使用本次真实执行结果与预期结果进行对比
			action.andExpect(ok);
	}
}

匹配响应体(json)

虚拟请求体(json)匹配

@Data
public class Book {
    
    
	private int id;
	private String name;
	private String type;
	private String description;
}
@RestController
@RequestMapping("/books")
public class BookController {
    
    
	
	@GetMapping
	public String 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;
	}
}
@SpringBootTest(webEnviroment = SpringBootTest.WebEnviroment.RANDOM_PORT)
//开启虚拟MVC调用
@AutoConfigureMockMvc
public class WebTest {
    
    
	@Test
	//注入虚拟MVC调用对象
	void testRandomPort (@Autowired MockMvc mvc) throws Exception {
    
    
			//创建虚拟请求,当前访问/books
			MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
			//执行请求
			ResultActions action = mvc.perform(builder);
			//匹配执行结果(是否预期值)
			//定义执行结果匹配器
			ContentResultMatchers content = MockMvcResultMatchers.content();
			//定义预期执行结果
			ResultMatcher result = content.json("{\"id\":1,\"name\":\"SpringBoot2\"}");
			//使用本次真实执行结果与预期结果进行对比
			action.andExpect(ok);
	}
}

匹配响应头

虚拟请求头匹配

@SpringBootTest(webEnviroment = SpringBootTest.WebEnviroment.RANDOM_PORT)
//开启虚拟MVC调用
@AutoConfigureMockMvc
public class WebTest {
    
    
	@Test
	//注入虚拟MVC调用对象
	void testRandomPort (@Autowired MockMvc mvc) throws Exception {
    
    
			//创建虚拟请求,当前访问/books
			MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get("/books");
			//执行请求
			ResultActions action = mvc.perform(builder);
			//匹配执行结果(是否预期值)
			//定义执行结果匹配器
			HeaderResultMatchers content = MockMvcResultMatchers.header();
			//定义预期执行结果
			ResultMatcher result = content.string("Content-Type","application/json");
			//使用本次真实执行结果与预期结果进行对比
			action.andExpect(ok);
	}
}

总结:

web环境模拟测试

  • 设置测试端口
  • 模拟测试启动
  • 模拟测试匹配(各组成部分信息均可匹配)

数据层测试回滚

数据层测试事务回滚

为测试用例添加事务,SpringBoot会对测试用例对应的事务操作进行回滚

@SpringBootTest
@Transactional
public class DaoTest {
    
    
	@Autowired
	private BookService bookService;
}

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

@SpringBootTest
@Transactional
@Rollback(false)
public class DaoTest {
    
    
}

总结:

测试用例回滚事务

测试用例数据设定

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

testcase:
  book:
    id: ${
    
    random.int}        #随机数
    id2: ${
    
    random.int(10)}   #10以内随机数
    type: ${
    
    random.int(10,20)}   #10到20随机数
    uuid: ${
    
    random.uuid}      #随机uuid
    name: ${
    
    random.value}     #随机字符串,MD5字符串,32位
    publishTime: ${
    
    random.long} #随机整数(Long范围)
  • 其中() 可以是任意字符,例如[] , !!均可

内置数据源

数据层解决方案

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

Druid + MyBatis-Plus + MySQL
  • 数据源:DruidDataSource
  • 持久化技术:MyBatis-Plus / MyBatis
  • 数据库:MySQL

数据源配置格式

格式一:

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTC
    username: root
    password: root
    type: com.alibaba.druid.pool.DruidDataSource

格式二:

spring:
  datasource:
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTC
      username: root
      password: root

数据源配置

SpringBoot提供了3种内嵌的数据源对象供开发者选择

  • HikariCP:默认内置数据源对象
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTC
    hikari:
      driver-class-name: com.mysql.cj.jdbc.Driver
      username: root
      password: root

注意:这个url跟hikari是同一级别

  • Tomcat提供DataSource:HikariCP不可用的情况下,且在web环境中,将使用tomcat服务器配置的数据源对象
  • Commons DBCP:HikariCP不可用,tomcat数据源也不可用,将使用dbcp数据源

JdbcTemplate

数据层解决方案

内置持久化解决方案-JdbcTemplate

@SpringBootTest
class SpringbootSSqlApplicationTest {
    
    
	@Autowired
	private JdbcTemplate jdbcTemplate;
	@Test
	void testJdbc(){
    
    
		String sql = "select * from tbl_book where id = 1";
		List<Book> query = jdbcTemplate.query(sql, 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;
		}
	});
	System.out.println(query);
  }
}

使用JdbcTemplate得引入依赖:

<dependency>
	<groupId>org.springframework.book</groupId>
	<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

JdbcTemplate配置:

spring:
  jdbc:
    template:
      query-timeout: -1   # 查询超时时间
      max-rows: 500       # 最大行数
      fetch-size: -1      # 批处理数量
      

总结:

1.SpringBoot内置JdbcTemplate持久化解决方案
2.使用JdbcTemplate需要导入spring-boot-starter-jdbc


H2数据库

内嵌数据库

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

  • H2
  • HSQL
  • Derby

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

server:
  port: 80
spring: 
  datasource:
    url: jdbc:h2:~/test
    hikari:
      driver-class-name: org.h2.Driver
      username: sa
      password: 123456
  h2:
    console:
      path: /2
      enabled: true

访问用户名sa,默认密码123456

浏览器,打开地址 localhost/h2 即可在浏览器中看h2数据库

操作数据库(创建表)

create table tbl_book(id int,name varchar,type varchar,description varchar)

H2数据库控制台仅用于开发阶段,线上项目请务必关闭控制台功能

server:
  port: 80
spring:
  h2:
    console:
      path: /h2
      enabled: false

总结:

  1. H2内嵌式数据库启动方式
  2. H2数据库线上运行时请务必关闭

数据层解决方案

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

Druid + MyBatis-Plus + MySQL
数据源 持久化 数据库
Druid MyBatis-Plus MySQL
HiKari MyBatis H2
JdbcTemplate

数据库层解决方案

SQL
NoSQL

NoSQL解决方案

市面上常见的NoSQL解决方案

  • Redis
  • Mongo
  • ES

redis下载安装与基本使用

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

  • 支持多种数据存储格式
  • 支持持久化
  • 支持集群

Redis下载(Windows版)

  • http://github.com/tporadowski/redis/releases

Redis安装与启动(Windows版)

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

总结:

1.Redis安装(Windows版)
2.Redis基本操作


SpringBoot整合Redis

1.导入SpringBoot整合Redis坐标

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
</denpendency>

2.配置Redis坐标(采用默认配置)

spring:
  redis:
    host: localhost # 127.0.0.1
    port: 6379
  • 主机: localhost(默认)
  • 端口: 6379(默认)

3.RedisTemplate提供操纵各种数据存储类型的接口API

4.客户端: RedisTemplate

@SpringBootTest
class SpringbootNosqlApplicationTests {
    
    
	@Test
	void set(@Autowired RedisTemplate redisTemplate) {
    
    
		ValueOperations ops = redisTemplate.opsForValue();
		ops.set("testKey","testValue");
	}
	@Test
	void set(@Autowired RedisTemplate redisTemplate) {
    
    
		ValueOperations ops = redisTemplate.opsForValue();
		Object val = ops.get("testKey");
		System.out.println(val);
	}
}
@SpringBootTest
class SpringbootNosqlApplicationTests {
    
    
	@Test
	void set(@Autowired RedisTemplate redisTemplate) {
    
    
		HashOperations ops = redisTemplate.opsForHash();
		opsH.set("testKeyH","testFieldH","testValueH");
	}
	@Test
	void set(@Autowired RedisTemplate redisTemplate) {
    
    
		HashOperations opsH = redisTemplate.opsForHash();
		Object valH = opsH.get("testKeyH","testFieldH");
		System.out.println(valH);
	}
}

总结:

SpringBoot整合Redis

  • 导入redis对应的starter
  • 配置
  • 提供操作Redis接口对象RedisTemplate
    - - ops: 获取各种数据类型操作接口

SpringBoot读写Redis的客户端

客户端: RedisTemplate以对象作为key和value,内部对数据进行序列化

@SpringBootTest
class SpringbootNosqlApplicationTests {
    
    
	@Test
	void set(@Autowired RedisTemplate redisTemplate) {
    
    
		ValueOperations ops = redisTemplate.opsForValue();
		ops.set("testKey","testValue");
	}
	@Test
	void set(@Autowired RedisTemplate redisTemplate) {
    
    
		ValueOperations ops = redisTemplate.opsForValue();
		Object val = ops.get("testKey");
		System.out.println(val);
	}
}

客户端:StringRediTemplate以字符串作为key和value,与Redis客户端操作等效

@SpringBootTest
class SpringbootNosqlApplicationTests {
    
    
	@Test
	void set(@Autowired StringRedisTemplate redisTemplate) {
    
    
		ValueOperations ops = redisTemplate.opsForValue();
		ops.set("testKey","testValue");
	}
	@Test
	void set(@Autowired StringRedisTemplate redisTemplate) {
    
    
		ValueOperations ops = redisTemplate.opsForValue();
		Object val = ops.get("testKey");
		System.out.println(val);
	}
}

总结:
1.RedisTemplate
2.StringRedisTemplate(常用)


SpringBoot操作Redis客户端实现技术切换(jedis)

客户端选择:jedis

<dependency>
 	<groupId>redis.clients</groupId>
 	<artifactId>jedis</artifactId>
</dependency>

配置客户端

spring:
	redis:
	  host: localhost # 127.0.0.1
	  port: 6379
	  clent-type: lettuce

用jedis, clent-type就指定jedis,用lettuce,客户端类型就指定lettuce(也可不指定,默认就是lettuce)

配置客户端专用属性

spring:
	redis:
	  host: localhost # 127.0.0.1
	  port: 6379
	  clent-type: lettuce
	  lettuce:
	    pool:
	      max-active: 16
	  jedis:
	    pool:
	      max-active: 16

lettcus与jedis区别

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

总结:

SpringBoot整合Redis客户端选择

  • lettuce(默认)
  • jedis

Mongodb简介

MongoDB是一个开源、高性能、无模式的文档型数据库。NoSQL数据库产品中的一种,是最像关系型数据库的非关系型数据库

应用场景:

淘宝用户数据

  • 存储位置: 数据库
  • 特征: 永久性存储,修改额度极低

游戏装备数据、游戏道具数据

  • 存储位置: 数据库、Mongodb
  • 特征: 永久性存储与临时存储相结合、修改额度加粗样式较高

直播数据、打赏数据、粉丝数据

  • 存储位置: 数据库、Mongodb
  • 特征: 永久性存储与临时存储相结合、修改额度极高

物联网数据

  • 存储位置: Mongodb
  • 特征: 临时存储,修改额度飞速

总结:

Mongodb应用场景


Mongodb下载与安装

Windows版Mongo下载

  • https://www.mongodb.com/try/download

Window版Mongo安装

  • 解压缩后设置数据目录

Windows版Mongo启动

- 服务端启动

mongod --dbpath=//\data\db

- 客户端启动

mongo -- host=12.0.0.1 --port=2701

Windows版Mongo安装问题及解决方案

由于找不到VCRUNTIMEE140_1.dll,无法继续执行代码。重新安装程序可能会解决此问题。

步骤一: 下载对应的dll文件(通过互联网搜索即可)

步骤二: 拷贝到windows安装路径下的system32目录中
步骤三: 执行命令注册对应dll文件

regsve32 vcruntime140_1.dll

总结:

  1. Mongodb安装、启动
  2. 可视化客户端Robo 3T安装与连接

Mongodb基础操作

新增

db.集合名称.insert/sava/insertOne(文档)

修改

db.集合名称.remove(条件)

删除

db.集合名称.update(条件,{
    
    操作种类:{
    
    文件}})

1.基础查询

  • 查询全部: db.集合.find();
  • 查第一条: db.集合.findOne()
  • 查询指定数量文档: db.集合.find().limit(10) //查10条文档
  • 跳过指定数量文档: db.集合.find().skip(20) //跳过20条文档
  • 统计: db.集合.count()
  • 排序: db.集合.sort({age:1}) //按age升序排序
  • 投影: db.集合名称.find(条件,{name:1,age
  • :1}) //仅保留name和age域

2.条件查询

  • 基本格式: db.集合.fing({条件})
  • 模糊查询: db.集合.find({域名:/正则表达式/}) //等同SQL中的like,比like强大,可以执行正则所有规则
  • 条件比较运算: db.集合.find({域名:{$gt:值}}) //等同SQL中的数据比较运算,例如: name>18
  • 包含查询: db.集合.find({域名:{$in:[值1,值2]}}) //等同于SQL中的in
  • 条件连接查询: db.集合.find({$and:[{条件1},{t条件2}]}) //等同于SQL中的and、or

总结:

Mongodb基础CRUD


SpringBoot整合Mongodb

导入Mongodb驱动

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

配置客户端

spring:
  data:
    mondodb:
      url: mongodb://localhost/luxifa

客户端读写Mongodb

@Test
void testSave(@Autowired MongoTemplate mongoTemplate) {
    
    
	Book boo = new Book();
	book.setId(1);
	book.setType("springboot");
	book.setName("springboot");
	book.setDescription("springboot");
	mongoTemplate.save(book);
}

@Test
void testFind(@Autowired MongoTemplate mongoTemplate) {
    
    
	List<Book> all = mongoTemplate.findAll(Book.class);
	System.out.println(all);
}

总结:

SpringBoot整合Mongodb

  • 导入Mongodb’对应的starer
  • 配置mongodb访问url
  • 提供操作Mongodb接口对象MongoTemplate

## 缓存 - SpringBoot提供了缓存的统一整合接口,方便缓存技术的开发与管理
  • Generic
  • JCache
  • Ehcache
  • Hazelcat
  • Infinispan
  • Couchbase
  • Redis
  • Caffenine
  • Simple(默认)
  • memcached

Spring缓存使用方式

- 导入缓存技术对应的starter

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-cache</artifactId>
</dependency>

- 启用缓存

@SpringBootApplication
@EnableCaching
public class SpringbootCacheApplication {
    
    
	public static void main(String[] args) {
    
    
		SpringApplication.run(SpringbootCacheApplication.class,args);
	}
}

- 设置当前操作的结果数据进入缓存

@Cacheable(value="cacheSpace",key="#id")
public Book getById(Integer id) {
    
    
	return bookDao.selectById(id);
}

总结:
SpringBoot启动缓存的方式

- @EnableCaching
- Cacheable


变更缓存供应商Ehcache

  • ** 加入Ehcache坐标(缓存供应商实现)**
<dependency>
	<groupId>net.sf.ehcache</groupId>
	<artifactId>ehcache</artifactId>
</dependency>
  • 缓存设定为使用Ehcache
spring:
  cache:
    type: ehcahe
    ehcache:
      config: ehcache.xml
  • 提供echcache配置文件ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://echcache.org/ehcache.xsd"
         updateCheck="false">
	<!--默认缓存策略-->
	<!-- external: 是否永久存在,设置为true则不会被消除,此时与timeout冲突,通常设置为false-->
	<!-- diskPersistent: 是否启用磁盘持久化-->
	<!-- maxElementdInMemory: 最大缓存数量-->
	<!-- overflowToDisk: 超过最大缓存数据是否持久化到磁盘-->
	<!-- timeToldleSeconds: 最大不活动间隔,设置过长缓存容易溢出,设置过短无效果-->
	<!-- timeToLiveSeconds: 最大活时间-->
	<!-- memeryStoreEvictionPolicy: 缓存清除策略-->
	<defaultCache
			eternal="false"
			diskPersistent="false"
			maxElementsInMemory="1000"
			overflowToDisk="60"
			timeToldleSeconds="60"
			timeToLiveSeconds="60"
			memoryStoreEvictionPolict="LRU" />
</ehcache>
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://echcache.org/ehcache.xsd"
         updateCheck="false">
	<cache
	        name="smsCode"
			eternal="false"
			diskPersistent="false"
			maxElementsInMemory="1000"
			overflowToDisk="60"
			timeToldleSeconds="60"
			timeToLiveSeconds="60"
			memoryStoreEvictionPolict="LRU" />
</ehcache>

总结:
变更缓存供应商为Ehcache


数据淘汰策略

影响数据淘汰的相关配置

检测易失数据(可能会过期的数据集server.db[i].expires)

  • volatile-lru: 挑选最近最少使用的数据淘汰
  • volatile-lfu: 挑选最近使用次数最少的数据淘汰
  • volatile-ttl: 挑选将要过期的数据淘汰
  • volatile-random: 任意选择数据淘汰

变更缓存供应商Redis

  • 加入Redis坐标(缓存供应商实现)
<dependency>
	<groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>  
  • 配置Redis服务器,缓存设定为使用Redis
spring:
  redis:
    host: localhost
	port: 6379
  cache:
	type: redis
  • 设置Redis相关配置
spring:
  redis:
    host: localhost
    port: 6379
  cache:
    type: redis
    redis:
      use-key-prefix: true  #是否使用前缀名(系统定义前缀名)
      key-prefix: sms_      #追加自定义前缀名
      time-to-live: 10s     #有效时长
      cache-null-value: false  #是否允许存储空值

总结:

变更供应商为Redis


memcached下载与安装

安装memcached

  • 使用管理员身份运行cmd指令

安装

memcached.exe -d install

运行memcached

  • 启动服务
mamcached.exe -d start
  • 停止服务
memcached.exe -d stop

变更缓存供应商memcached

  • 加入Xmemcache坐标(缓存供应商实现)
<dependency>
	<groupId>com.googlecode.xmemcached</groupId>
	<artifactId>xmemcached</artifactId>
	<version>2.4.7</version>
</dependency>
  • 配置memcached服务器必要属性
memcached:
	# memcached服务器地址
	servers: localhost:11211
	# 连接池的数量
	poolSize: 10
	# 设置默认操作超时
	opTimeout: 3000
  • 创建读取属性配置信息类,加载配置
@Component
@ConfigurationProperties(prefix = "memcached")
@Data
public class XMemcachedProperties {
    
    
	private String servers;
	private Integer poolSize;
	private Long opTimeout;
}
  • 创建客户端配置类
@Configuration
public class XMemcachedConfig {
    
    
	@Autowired
	private XMemcachedProperties xMemcachedProperties;
	@Bean
	public MemcachedClient getMemcachedClient() throws IOException{
    
    
		MemcachedClientBuilder builder = new XMemcachedClientBuilder(xMemcachedProperties.getServers());
		MemcachedClient memcachedClient = builder.build();
		return memcachedClient;
	}
}
  • 配置memcached属性
@Service
public class SMSCodeServiceMemcacheImpl implements SMSCodeService {
    
    
	@Autowired
	private CodeUtils codeUtils;
	@Autowired
	private MemcachedClient memcachedClient;
	@Ovrride
	public String sendCodeToSMS(String tele) {
    
    
		String code = this.codeUtils.generator(tele);
		//将数据加入memcache
		try {
    
    
			memcachedClient.set(tele,0,code); //key,timeout,value
		} catch (Exception e) {
    
    
			e.printStackTrace();
		}
		return code;
	}




	public String checkCode(CodeMsg codeMsg) {
    
    
		String value = null;
		try {
    
    
			value = memcachedClient.get((code.getTele()).toString(); //key,timeout,value
		} catch (Exception e) {
    
    
			e.printStackTrace();
		}
		return codeMsg.getCode().equals(value);
	}
}

总结:
1.xmemcache客户端加载方式(bean初始化)
2.xmemcache客户端使用方式(set & get)


变更缓存供应商jetcache

  • jetCache对SpringCache进行了封装,在原有功能基础上实现了多级缓存、缓存统计、自动刷新、异步调用、数据报表等功能

  • jetCache设定了本地缓存与远程缓存的多级缓存解决方案
    本地缓存(local):linkedHashMapCaffeine

    远程缓存(remote): RedisTair

  • 加入jetcache坐标

<dependency>
	<groupId>com.alicp.jetcache</groupId>
	<artifactId>jetcache-starter-redis</artifactId>
	<version>2.6.2</version>
</dependency>
  • 配置远程缓存必要属性
jetcache:
  remote:
    default:
      type: redis
      host: localhost
      port: 6379
      poolConfig:
        maxTotal: 50
    sms:
      type: redis
      host: localhost
      port: 6379
      poolConfig:
        maxTotal: 50
  • 配置本地缓存必要属性
jetcache:
  local:
    default:
      type: linkedhashmap
      keyConvertor: fastjson
  • 配置示范
jetcache:
  statIntervalMinutes: 15
  areaInCacheName: false
  local:
    default:
      type: linkedhashmap
      keyConvertor: fastjson
      limit: 100
  remote:
    default:
      host: localhost
      port: 6379
      type: redis
      keyConvertor: fastjson
      valueEncoder: java
      valueDecoder: java
      poolConfig:
        minIdle: 5
        maxIdle: 20
        maxTotal: 50
  • 配置属性说明
属性 默认值 说明
jetcache.statIntervalMinutes 0 统计间隔,0表示不统计
jetcache.hiddenPackages 自动生成name时,隐藏指定的包名前缀
jetcache.(local或remote).${area}.type 缓存类型,本地支持linkedhashmap、caffeine,远程支持redis、tair
jetcache.(local或remote).${area}.keyConvertor key转换器,当前仅支持fastjson
jetcache.(local或remote).${area}.valueEncoder java 仅remote类型的缓存需要指定,可选java和kryo
jetcache.(local或remote).${area}.valueDecoder java 仅remote类型的缓存需要指定,可选java和kryo
jetcache.(local或remote).${area}.limit 100 仅local类型的缓存需要指定,缓存实例最大元素数
jetcache.(local或remote).${area}.expireAfterWriteInMillis 无穷大 默认过期时间,毫秒单位
jetcache.${area}.expireAfterAccessInmillis 0 仅local类型的缓存有效,毫秒单位,最大不活动间隔
  • 开启jetcacahe注解支持
@SpringBootApplication
@EnableCreateCacheAnnotation
public class SpringbootCacheApplication {
    
    
	public static void main(String[] args) {
    
    
		SpringApplication.run(SpringbootCacheApplication.class,args);
	}
}
  • 声明缓存对象
@Service
public class SMSCodeServiceImpl implements SMSCodeService {
    
    
	@Autowired
	private CodeUtils codeUtils;
	@CreateCache(name = "smsCache" , expire = 3600)
	private Cache<String,String> jetSMSCache;
}
  • 缓存操作
@Service
public class SMSCodeServiceImpl implements SMSCodeService {
    
    
	@Override
	public String sendCodeToSMS(String tele) {
    
    
		String code = this.codeUtils.generator(tele);
		jetSMSCache.put(telw,code);
		return code;
	}

	@Override
	public boolean checkCode(CodeMsg codeMsg) {
    
    
		String value = jetSMSCache.get(codeMsg.getTele());
		return codeMsg.getCode().equals(value);
	}
}

总结:

1、jetcache简介
2、jetcache远程缓存使用方式
3、jetcache本地缓存使用方式


jetcache方法缓存

  • 启用方法注解
@SpringBootApplication
@EnableCreateCacheAnnotation
@EnableMethodCache(basePackages = "com.ithema")
public class SpringBootJetCacheApplication {
    
    
	public static void main(String[] args) {
    
    
		SpringApplication.run(SpringBootJetCacheApplication.class,args);
	}
}
  • 使用方法注解操作缓存
@Service
public class BookServiceImpl implements BookService {
    
    
	@Autowired
	private BookDao bookDao;

	@Cache(name = "smsCache_",key = "#id", expire = 3600)
	@CacheRefresh(refresh = 10,timeUnit = TimeUnit.SECONDS)
	public Book getById(Integer id) {
    
    
		return bookDao.selectById(id);
	}
}
@Service
public class BookServiceImpl implement BookService {
    
    

	@CacheUpdate(name = "smsCache_", key = "#book.id", value = "#book")
	public boolean update(Book book) {
    
    
		return bookDao.updateById(book) > 0;
	}	

	@CacheInvalidate(name = "smsCache_", key = "#id")
	public boolean delete(Integer id) {
    
    
		return bookDao.deleteById(id) > 0;
	}
}
  • 缓存对象必须保障可序列化
@Data
public class Book implements Serializable {
    
    
}
jetcache:
  remote:
    default:
      type: redis
      keyConvertor: fastjson
      valueEncoder: java
      valueDecoder: java 

总结:

jetcache方法注解使用方式


j2cache基本操作

  • j2cache是一个缓存整合框架,可以提供缓存的整合方式,使各种缓存搭配使用,自身不提供缓存功能
  • 基于ehcache + redis 进行整合

j2cache相关配置

  • 加入j2cache坐标,加入整合缓存的坐标
<dependency>
	<groupId>net.oschina.j2cache</groupId>
	<artifactId>j2cache-spring-boot2-starter</artifactId>
	<version>2.8.0-release</version>
</dependency>
<dependency>
	<groupId>net.oschina.j2cache</groupId>
	<artifactId>j2cache-core</artifactId>
	<version>2.8.4-release</version>
</dependency>
<dependency>
	<groupId>net.sf.ehcache</groupId>
	<artifactId>jehcache</artifactId>
</dependency>
  • 配置使用j2cache(application.yml)
j2cache:
	config-location: j2cache.properties
  • 配置一级缓存与二级缓存以及一级缓存数据到二级缓存的发送方式(j2cache.properties)
# 配置1级缓存
j2cache.L1.provider_class = ehcache
ehcache.configXml = ehcache.xml

# 配置1级缓存数据到2级缓存的广播方式:可以使用redis提供的消息订阅模式,也可以使用groupd多播实现
j2cache.broadcast = net.oschina.j2cache.cache.support.redis.SpringRedisPubSubPolicy

# 配置2级缓存
j2cache.L2.provider_class = net.oschina.j2cache.cache.support.redis.SpringRedisProvider
j2cache.L2.config_section = redis
redis.hosts = localhost:6379

  • 设置使用缓存
@Service
public class SMSCodeServiceImpl implements SMSCodeService {
    
    
	@Autowired
	private CodeUtils codeUtils;
	@Autowired
	private CacheChannel cacheChannel;
}
  • 设置使用缓存
@Service
public class SMSCodeServiceImpl implements SMSCodeService {
    
    
	@Override
	public String sendCodeToSMS(String tele) {
    
    
		String code = codeUtils.generator(tele);
		cacheChannel.set("sms",tele,code);
		return code;
	}

	@Override
	public boolean checkCode(SMSCode smsCode) {
    
    
		String code = cacheChannel.get("sms",smsCode.getTele()).asString();
		return smsCode.getCode().equals(code);
	}
}

总结:

j2cache缓存的基础使用

小结:

1.spring-cache
simple
ehcache
redis
memcached
2.jetcache
3.j2cache

猜你喜欢

转载自blog.csdn.net/weixin_42594143/article/details/129164048