从事Java开发工作阶段的知识分享
mybatis二级缓存+Redis实现代码
demo代码:
一、添加maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
二、Redis相关配置类
(一)、
import org.apache.ibatis.cache.Cache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class RedisCache implements Cache {
private static final Logger logger = LoggerFactory.getLogger(RedisCache.class);
private static RedisTemplate<String, Object> redisTemplate;
private static final Integer SQLCACHETIME=2*60;//秒
private final String id;
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
@Override
public ReadWriteLock getReadWriteLock() {
return this.readWriteLock;
}
public static void setRedisTemplate(RedisTemplate redisTemplate) {
RedisCache.redisTemplate = redisTemplate;
}
public RedisCache(final String id) {
if (id == null) {
throw new IllegalArgumentException("Cache instances require an ID");
}
logger.debug("MybatisRedisCache:id=" + id);
this.id = id;
}
@Override
public String getId() {
return this.id;
}
@Override
public void putObject(Object key, Object value) {
try {
logger.info(">>>>>>>>>>>>>>>>>>>>>>>>putObject: key=" + key + ",value=" + value);
if (null != value)
redisTemplate.opsForValue().set(key.toString(), value, SQLCACHETIME, TimeUnit.SECONDS);
} catch (Exception e) {
e.printStackTrace();
logger.error("redis保存数据异常!");
}
}
@Override
public Object getObject(Object key) {
try {
logger.info(">>>>>>>>>>>>>>>>>>>>>>>>getObject: key=" + key);
if (null != key)
return redisTemplate.opsForValue().get(key.toString());
} catch (Exception e) {
e.printStackTrace();
logger.error("redis获取数据异常!");
}
return null;
}
@Override
public Object removeObject(Object key) {
try {
if (null != key)
return redisTemplate.expire(key.toString(), 1, TimeUnit.DAYS);
} catch (Exception e) {
e.printStackTrace();
logger.error("redis获取数据异常!");
}
return null;
}
@Override
public void clear() {
Long size = redisTemplate.execute(new RedisCallback<Long>() {
@Override
public Long doInRedis(RedisConnection redisConnection) throws DataAccessException {
Long size = redisConnection.dbSize();
//连接清除数据
redisConnection.flushDb();
redisConnection.flushAll();
return size;
}
});
logger.info(">>>>>>>>>>>>>>>>>>>>>>>>clear: 清除了" + size + "个对象");
}
@Override
public int getSize() {
Long size = redisTemplate.execute(new RedisCallback<Long>() {
@Override
public Long doInRedis(RedisConnection connection)
throws DataAccessException {
return connection.dbSize();
}
});
return size.intValue();
}
}
(二)、
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
@EnableCaching
public class RedisCacheConfig {
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory){
CacheManager cacheManager = RedisCacheManager.create(factory);
return cacheManager;
}
@Bean
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory){
RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory);
// key序列化方式;(不然会出现乱码;),但是如果方法上有Long等非String类型的话,会报类型转换错误;
// 所以在没有自己定义key生成策略的时候,以下这个代码建议不要这么写,可以不配置或者自己实现ObjectRedisSerializer
// 或者JdkSerializationRedisSerializer序列化方式;
RedisSerializer<String> redisSerializer = new StringRedisSerializer();// Long类型不可以会出现异常信息;
redisTemplate.setKeySerializer(redisSerializer);
redisTemplate.setHashKeySerializer(redisSerializer);
redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
(三)、
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
@Component
public class RedisCacheTransfer {
@Autowired
public void setRedisTemplate(RedisTemplate redisTemplate) {
RedisCache.setRedisTemplate(redisTemplate);
}
}
三、xml二级缓存的配置写法
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="lq.com.dao.UserMapper">
<cache size="1024" type="lq.com.config.RedisCache"></cache>
<select id="listUser" resultType="lq.com.entity.User">
select
user_id as userId,user_name as userName,user_age as userAge
from `user`
</select>
</mapper>
四、实体类
import java.io.Serializable;
public class User implements Serializable {
private Integer userId;
private String userName;
private Integer userAge;
private Integer userIsDelete;
public User() {
}
public User(Integer userId, String userName, Integer userAge, Integer userIsDelete) {
this.userId = userId;
this.userName = userName;
this.userAge = userAge;
this.userIsDelete = userIsDelete;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Integer getUserAge() {
return userAge;
}
public void setUserAge(Integer userAge) {
this.userAge = userAge;
}
public Integer getUserIsDelete() {
return userIsDelete;
}
public void setUserIsDelete(Integer userIsDelete) {
this.userIsDelete = userIsDelete;
}
}