Mybatis有一级缓存、二级缓存,不过存在一些问题,最好使用第三方缓存,这里来记录下配置redis作为缓存。
Cache实现类代码:
public class RedisCache implements Cache {
//实现类
private static final Logger logger = LoggerFactory.getLogger(RedisCache.class);
//这里需要静态注入
private static JedisConnectionFactory jedisConnectionFactory;
private final String id;
/**
* The {@code ReadWriteLock}.
*/
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
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 void clear()
{
RedisConnection connection = null;
try
{
connection = jedisConnectionFactory.getConnection(); //连接清除数据
connection.flushDb();
connection.flushAll();
}
catch (JedisConnectionException e)
{
e.printStackTrace();
}
finally
{
if (connection != null) {
connection.close();
}
}
}
@Override
public String getId()
{
return this.id;
}
@Override
public Object getObject(Object key)
{
Object result = null;
RedisConnection connection = null;
try
{
connection = jedisConnectionFactory.getConnection();
RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer(); //借用spring_data_redis.jar中的JdkSerializationRedisSerializer.class
result = serializer.deserialize(connection.get(serializer.serialize(key))); //利用其反序列化方法获取值
}
catch (JedisConnectionException e)
{
e.printStackTrace();
}
finally
{
if (connection != null) {
connection.close();
}
}
return result;
}
@Override
public ReadWriteLock getReadWriteLock()
{
return this.readWriteLock;
}
@Override
public int getSize()
{
int result = 0;
RedisConnection connection = null;
try
{
connection = jedisConnectionFactory.getConnection();
result = Integer.valueOf(connection.dbSize().toString());
}
catch (JedisConnectionException e)
{
e.printStackTrace();
}
finally
{
if (connection != null) {
connection.close();
}
}
return result;
}
@Override
public void putObject(Object key, Object value)
{
RedisConnection connection = null;
try
{
// logger.info("id是:" + this.id);
// logger.info(">>>>>>>>>>>>>>>>>>>>>>>>putObject:"+key+"="+value);
connection = jedisConnectionFactory.getConnection();
RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer(); //借用spring_data_redis.jar中的JdkSerializationRedisSerializer.class
connection.set(serializer.serialize(key), serializer.serialize(value)); //利用其序列化方法将数据写入redis服务的缓存中
}
catch (JedisConnectionException e)
{
e.printStackTrace();
}
finally
{
if (connection != null) {
connection.close();
}
}
}
@Override
public Object removeObject(Object key)
{
RedisConnection connection = null;
Object result = null;
try
{
connection = jedisConnectionFactory.getConnection();
RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
result =connection.expire(serializer.serialize(key), 0);
}
catch (JedisConnectionException e)
{
e.printStackTrace();
}
finally
{
if (connection != null) {
connection.close();
}
}
return result;
}
public static void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) {
RedisCache.jedisConnectionFactory = jedisConnectionFactory;
int a = 1;
}
}
问题:@Autowired
没办法注入静态属性,所以此处的jedisConnectionFactory
要通过其他方法注入
解决:这里我使用中间类来实现,在xml文件中配置好熟悉,再有中间类使用@Autowired注解方法来间接的注入到缓存类中。
中间类代码:
public class RedisCacheTransfer {
@Autowired
public void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) {
jedisConnectionFactory.afterPropertiesSet();
RedisCache.setJedisConnectionFactory(jedisConnectionFactory);
}
}
xml配置:(这里properties文件在application.xml中导入配置,此处就不展示了)
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="${master.redis.max_idle}" />
<property name="maxTotal" value="${master.redis.max_active}" />
<property name="maxWaitMillis" value="${master.redis.timeout}" />
<property name="testOnBorrow" value="true"/>
bean>
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:host-name="${master.redis.ip}"
p:port="${master.redis.port}"
p:password="${master.redis.password}"
p:pool-config-ref="poolConfig"/>
<bean id="redisCacheTransfer" class="tech.lingshou.common.util.db.RedisCacheTransfer">
<property name="jedisConnectionFactory" ref="jedisConnectionFactory"/>
bean>
beans>
运用代码(注解配置或映射xml文件中配置)
//使用注解配置
@CacheNamespace(implementation= RedisCache.class)
public interface LsAdminRoleMapper extends BaseMapper<LsAdminRole> {
}
至此,基本的配置就完成了…
在使用了缓存后,我在使用mybatis的分页进行查询的时候,发现了问题,就是返回的pageNum和
pageSize有时候会出现为0的情况,但是查询的是有记录的…后来在mybatis配置文件中查看,发现是分页插件问题,应该将PaginationInterceptor改为CachePaginationInterceptor才能实现二级缓存。
<configuration>
<settings>
<setting name="localCacheScope" value="SESSION"/>
<setting name="cacheEnabled" value="true"/>
settings>
<plugins>
<plugin interceptor="com.baomidou.mybatisplus.plugins.CachePaginationInterceptor">
<property name="dialectType" value="mysql" />
plugin>
plugins>
configuration>