二級緩存是多個SqlSession共享的,其作用域是mapper的同一個namespace,不同的sqlSession兩次執行相同namespace下的sql語句且向sql中傳遞參數也相同即最終執行相同的sql語句,第一次執行完畢會將數據庫中查詢的數據寫到緩存(內存),第二次會從緩存中獲取數據將不再從數據庫查詢,從而提高查詢效率。
1.添加pom依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
</dependency>
2.添加redis配置類
@Configuration
public class RedisConfig {
@Value("${spring.redis.host}")
private String host;
@Bean
public JedisPoolConfig getRedisConfig(){
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxIdle(maxIdle);
config.setMaxTotal(maxTotal);
config.setMaxWaitMillis(maxWaitMillis);
config.setMinIdle(minIdle);
return config;
}
@Bean(name = "jedisConnectionFactory")
public JedisConnectionFactory getConnectionFactory(){
JedisConnectionFactory factory = new JedisConnectionFactory();
JedisPoolConfig config = getRedisConfig();
factory.setPoolConfig(config);
factory.setHostName(host);
factory.setPort(port);
factory.setDatabase(database);
factory.setPassword(password);
factory.setTimeout(timeout);
return factory;
}
@Bean(name = "redisTemplate")
public RedisTemplate<?, ?> getRedisTemplate(){
RedisTemplate<?,?> template = new StringRedisTemplate(getConnectionFactory());
return template;
}
}
3.在application.properties中配置redis
## Redis 配置
## Redis數據庫索引(默認爲0)
spring.redis.database=0
## Redis服務器地址
spring.redis.host=127.0.0.1
## Redis服務器連接端口
spring.redis.port=6379
## Redis服務器連接密碼(默認爲空)
spring.redis.password=
## 連接池最大連接數(使用負值表示沒有限制)
spring.redis.pool.max-active=8
## 連接池最大阻塞等待時間(使用負值表示沒有限制)
spring.redis.pool.max-wait=-1
## 連接池中的最大空閒連接
spring.redis.pool.max-idle=8
## 連接池中的最小空閒連接
spring.redis.pool.min-idle=0
## 連接超時時間(毫秒)
spring.redis.timeout=0
4.配置Redis作爲Mybatis的緩存
public class MybatisRedisCache implements Cache {
private static JedisConnectionFactory jedisConnectionFactory;
private static JedisPool pool;
private final String id;
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
public MybatisRedisCache(final String id) {
if (id == null) {
throw new IllegalArgumentException("Cache instances require an ID");
}
this.id = id;
pool = new JedisPool(jedisConnectionFactory.getPoolConfig(), jedisConnectionFactory.getHostName(), jedisConnectionFactory.getPort());
}
private Object execute(RedisCallback callback) {
Jedis jedis = pool.getResource();
Object var3;
try {
var3 = callback.doWithRedis(jedis);
} finally {
jedis.close();
}
return var3;
}
@Override
public String getId() {
return this.id;
}
@Override
public int getSize() {
return (Integer) this.execute(new RedisCallback() {
@Override
public Object doWithRedis(Jedis jedis) {
Map<byte[], byte[]> result = jedis.hgetAll(MybatisRedisCache.this.id.toString().getBytes());
return result.size();
}
});
}
@Override
public void putObject(final Object key, final Object value) {
this.execute(new RedisCallback() {
@Override
public Object doWithRedis(Jedis jedis) {
jedis.hset(MybatisRedisCache.this.id.toString().getBytes(), key.toString().getBytes(), SerializeUtil.serialize(value));
return null;
}
});
}
@Override
public Object getObject(final Object key) {
return this.execute(new RedisCallback() {
@Override
public Object doWithRedis(Jedis jedis) {
return SerializeUtil.unserialize(jedis.hget(MybatisRedisCache.this.id.toString().getBytes(), key.toString().getBytes()));
}
});
}
@Override
public Object removeObject(final Object key) {
return this.execute(new RedisCallback() {
@Override
public Object doWithRedis(Jedis jedis) {
return jedis.hdel(MybatisRedisCache.this.id.toString(), new String[]{key.toString()});
}
});
}
@Override
public void clear() {
this.execute(new RedisCallback() {
@Override
public Object doWithRedis(Jedis jedis) {
jedis.del(MybatisRedisCache.this.id.toString());
return null;
}
});
}
@Override
public ReadWriteLock getReadWriteLock() {
return this.readWriteLock;
}
@Override
public String toString() {
return "Redis {" + this.id + "}";
}
public static void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) {
MybatisRedisCache.jedisConnectionFactory = jedisConnectionFactory;
}
}
5.通過RedisCacheTransfer靜態注入
@Component
public class RedisCacheTransfer {
@Autowired
public void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) {
MybatisRedisCache.setJedisConnectionFactory(jedisConnectionFactory);
}
}
6.配置mapper作用域namespace
二級緩存的作用域是mapper的namespace,所以要在mapper中添加這句話
<cache type="com.kangaroo.studio.moonlight.dao.cache.MybatisRedisCache"/>
7.實現model序列化
讀寫緩存Model需要序列化,只需要在類聲明的時候 implements Serializable 就好了。
8.配置logback.xml,控制檯查看sql語句
總結:
在第一次查詢的時候,可以在控制檯看到查詢的sql語句,當再次進行查詢的時候,控制檯不再輸出sql語句,此時數據是從redis緩存中獲取的。