Outline
Using MyBatis
its own secondary cache set to open, will not work in a distributed system, therefore, we useMiddlewareOpen second-level cache, this article describes the use of Redis
open two solutions strategy.本文介绍了2种使用redis的开启二级缓存的机制,使用Jedis 和 lettuce。
第一种策略 使用:Jedis
Jedis on implementation is directly connected redis server, if not thread-safe, only this time using a connection pool in a multithreaded environment, increase physical connection for each instance of Jedis
① the introduction of dependence
<!--redis的启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.1.5.RELEASE</version>
</dependency>
② configuration parameters redis
In the application.yml
file, add:
#设置redis的参数
spring:
# redis: #单机模式
# host: 192.168.*.*
# port: 6379
redis: #集群模式
cluster:
nodes: 192.168.8.18:7004,192.168.8:7001,192.168.8:7002
③ get the plant back door SprnigBoot
定义一个web触发器,作用是获得整个工厂内容,方便非工厂管理的普通类,可以拿到工厂管理的对象(全局容器)
We do so in order to obtain a managed factory redisTemplate
object.
package com.baizhi.cache;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
//web触发器,作用是获得整个工厂内容,方便非工厂管理的普通类。可以拿到工厂管理的对象(全局容器)
@Component
public class WebWare implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
//通过属性名获取对象的方法
public static Object getbyName(String name){
Object bean = applicationContext.getBean(name);
return bean;
}
//通过属性类获取对象的方法
public static Object getByClass(Class clazz){
Object bean = applicationContext.getBean(clazz);
return bean;
}
}
④ custom cache mechanism
Mybatis
ofcache, To the need to integrate custom or other Cache Cache provides the interface.
package com.baizhi.cache;
import org.apache.ibatis.cache.Cache;
import org.springframework.data.redis.core.RedisTemplate;
import java.util.concurrent.locks.ReadWriteLock;
//定义自己的一个缓存策略
public class MyCache implements Cache {
//获取工厂管理的redisTemplate对象
private RedisTemplate redisTemplate = (RedisTemplate) WebWare.getbyName("redisTemplate");
private String id;
public MyCache(String id) {
this.id = id;
}
@Override
public String getId() {
return id;
}
@Override
public void putObject(Object o, Object o1) {
redisTemplate.opsForHash().put(id,o,o1);
}
@Override
public Object getObject(Object o) {
Object o1 = redisTemplate.opsForHash().get(id, o);
return o1;
}
@Override
public Object removeObject(Object o) {
return null;
}
//清空缓存
@Override
public void clear() {
redisTemplate.delete(id);
}
@Override
public int getSize() {
return 0;
}
@Override
public ReadWriteLock getReadWriteLock() {
return null;
}
}
⑤ enable the secondary cache
In the *mapper.xml
Add the following files:
<cache type="com.baizhi.cache.MyCache"></cache>
第二种策略 使用 Lettuce
Lettuce connection is based on the connection instance can be accessed concurrently by multiple threads Netty in between, and is thread-safe, so a connection instance to meet concurrent access in a multithreaded environment
① the introduction of dependence
<!--集成Redis二级缓存-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--使用连接池技术-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
② configuration parameters redis
#连接redis
redis:
host: hbase
port: 6379
timeout: 5s #超时时间
lettuce:
pool:
max-active: 10 #最大活动数
max-idle: 8 #最大闲置数
max-wait: 5ms #最大等待数
min-idle: 1 #最小闲置数
shutdown-timeout: 100ms #超时停机时间
③ inlet registration component class
package com.baizhi;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.web.client.RestTemplate;
import java.net.UnknownHostException;
@SpringBootApplication
@MapperScan("com.baizhi.dao")
public class UsermodelApplication {
public static void main(String[] args) {
SpringApplication.run(UsermodelApplication.class, args);
}
//注册一个Rest组件 SpringMVC中自带的一个Rest客户端工具,可以无缝和SpringBoot集成
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
//注册一个Redis池技术的组件 Lettuce
@Bean
public RedisTemplate<Object, Object> redisTemplate(LettuceConnectionFactory connectionFactory) throws UnknownHostException {
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(connectionFactory);
//设置Key、value的序列化
redisTemplate.setKeySerializer(new JdkSerializationRedisSerializer());
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
return redisTemplate;
}
}
④ get the factory back door
package com.baizhi.cache;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class WebWare implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
//通过属性名获取对象的方法
public static Object getbyName(String name){
Object bean = applicationContext.getBean(name);
return bean;
}
//通过属性类获取对象的方法
public static Object getByClass(Class clazz){
Object bean = applicationContext.getBean(clazz);
return bean;
}
}
⑤ custom cache mechanism
package com.baizhi.cache;
import org.apache.ibatis.cache.Cache;
import org.aspectj.weaver.ast.Var;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class MyCache implements Cache {
private Logger logger= LoggerFactory.getLogger(MyCache.class);
//获取RedisTemple 对象
//获取工厂管理的redisTemplate对象
private RedisTemplate redisTemplate = (RedisTemplate) WebWare.getbyName("redisTemplate");
//创建一个读写锁
private ReadWriteLock lock = new ReentrantReadWriteLock();
//设置一个超时配置
private long timeout=300;
//id 用于存放namespace
private String id;
//提供一个构造
public MyCache(String id) {
this.id = id;
}
public void setTimeout(long timeout) {
this.timeout = timeout;
}
@Override
public String getId() {
return id;
}
@Override // o 某一方法的唯一标识 o1 方法的返回值
public void putObject(Object o, Object o1) {
/* redisTemplate.opsForHash().put(id,o,o1);*/
logger.debug("将查询结果存储到cache.key:"+o+",value:"+o1);
ValueOperations opsForValue = redisTemplate.opsForValue();
opsForValue.set(o,o1,timeout, TimeUnit.SECONDS);
}
@Override
public Object getObject(Object o) {
/*return redisTemplate.opsForHash().get(id,o);*/
logger.debug("从缓存中读取结果.key:"+o);
ValueOperations opsForValue = redisTemplate.opsForValue();
return opsForValue.get(o);
}
@Override
public Object removeObject(Object o) {
logger.debug("从缓存中清除.key:"+o);
ValueOperations opsForValue = redisTemplate.opsForValue();
Object value = opsForValue.get(o);
redisTemplate.delete(o);
return value;
}
@Override
public void clear() {
//清除
/* redisTemplate.delete(id);*/
logger.debug("从缓存中清除缓存区所有数据");
redisTemplate.execute((RedisConnection connection) ->{
connection.flushAll();
return null;
});
}
@Override
public int getSize() {
return 0;
}
@Override
public ReadWriteLock getReadWriteLock() {
return lock;
}
}
⑥ secondary cache enabled
<!--开启二级缓存-->
<cache type="com.baizhi.cache.MyCache">
<!--设置超时时间-->
<property name="timeout" value="60"/>
</cache>