(非原创)Mybatis和Spring data redis

 本文基于网上资料的总结和自己的实践经验,非原创。照理,关于mybaits缓存机制、redis以及spring data redis的资料请参照google,不再复述。

本文主要提供MybatisRedisCache实现类,并就mybatis与redis的集成做简要说明。很多copy的博客将来将去都只是抄袭一些文字,并未集成到项目中。


Mybatis在使用redis作为缓存时,虽然提升了查询效率,但是也带来了序列化问题。由于redis的存在,这里的存储对象必须实现序列化接口,着就要求mybatis pojo必须满足一下两个情况。

  1. ignore不必要属性的序列化
  2. 手动处理lazy proxy对象或者ignore
这两点要求定义缓存对象时,需要谨慎,应该尽量规避掉业务逻辑的注入。就好比关系型数据库的存储不需要考虑业务,都是业务根据存储来拼装。
lazy proxy可以实际加载出来,然后再放入到redis中。如果ignore掉,lazy部分还是需要mybatis来注入。

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.apache.commons.lang3.StringUtils;
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 org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;

import com.icb.creditcard.common.utils.SpringContextHolder;

/**
 * Description: Auth:Paris Date:Oct 26, 2016
 **/
public class MybatisRedisCache implements Cache {

	private static Logger logger = LoggerFactory.getLogger(MybatisRedisCache.class);
	private RedisTemplate<String, Object> redisTemplate = BeanUtils.getBean("redisTemplate");//redisTemplate定义在spring 配置中
	private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

	private final long CACHE_LIVE_TIME = 60 * 2;

	private String id;

	public MybatisRedisCache(final String id) {
		if (StringUtils.isEmpty(id)) {
			throw new IllegalArgumentException("MybatisRedisCache instances require an ID.");
		}
		this.id = id;
	}

	public void setId(String id) {
		this.id = id;
	}

	@Override
	public String getId() {
		return this.id;
	}

	@Override
	public void putObject(Object key, Object value) {
		final String keyf = key.toString();
		final Object valuef = value; 
		try {
			redisTemplate.execute(new RedisCallback<Long>() {

				@Override
				public Long doInRedis(RedisConnection connection)
						throws DataAccessException {
					RedisSerializer<Object> serializer = new GenericJackson2JsonRedisSerializer();
					byte[] keyb = serializer.serialize(keyf);
					connection.set(keyb, serializer.serialize(valuef));
					connection.expire(keyb, CACHE_LIVE_TIME);
					return 1L;
				}
				
			});
		} catch (Exception e) {
			logger.error("",e);
		}
	}

	@Override
	public Object getObject(Object key) {
		Object result = null;
		try {
			final String keyf = key.toString();
			result = redisTemplate.execute(new RedisCallback<Object>() {

				@Override
				public Object doInRedis(RedisConnection connection)
						throws DataAccessException {
					RedisSerializer<Object> serializer = new GenericJackson2JsonRedisSerializer();
					Object value = serializer.deserialize(connection.get(serializer.serialize(keyf)));
					return value;
				}
				
			});
		} catch (Exception e) {
			logger.error("",e);
		}
        return result;
	}

	@Override
	public Object removeObject(Object key) {
		Object result = null;
		try {
			final Object keyf = key;

			result = redisTemplate.execute(new RedisCallback<Object>() {

				@Override
				public Object doInRedis(RedisConnection connection) throws DataAccessException {
					RedisSerializer<Object> serializer = new GenericJackson2JsonRedisSerializer();
					byte[] keyb = serializer.serialize(keyf);
					Long l = connection.del(keyb.toString().getBytes());
					return l;
				}

			});
		} catch (Exception e) {
			logger.error("", e);
		}
		return result;
	}

	@Override
	public void clear() {
		redisTemplate.execute(new RedisCallback<Boolean>() {

			@Override
			public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
				connection.flushDb();
				connection.flushAll();
				return Boolean.TRUE;
			}
		});
	}

	@Override
	public int getSize() {
		return redisTemplate.execute(new RedisCallback<Integer>() {
			@Override
			public Integer doInRedis(RedisConnection connection) throws DataAccessException {
				return connection.dbSize().intValue();
			}

		});
	}

	@Override
	public ReadWriteLock getReadWriteLock() {
		return this.readWriteLock;
	}

}

猜你喜欢

转载自blog.csdn.net/u013275741/article/details/52943200