
?
package com.sohu.tv.cache;
import org.apache.ibatis.session.SqlSession;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.sohu.tv.bean.Player;
import com.sohu.tv.mapper.ClubDao;
import com.sohu.tv.mapper.PlayerDao;
import com.sohu.tv.test.mapper.BaseTest;
/**
* 一级缓存测试
*
* @author leifu
* @Date 2015-8-3
* @Time 下午9:51:00
*/
public class FirstCacheTest extends BaseTest {
private SqlSession sqlSession;
@Before
public void before() {
sqlSession = sessionFactory.openSession();
}
@After
public void after() {
sqlSession.close();
}
@Test
public void testCache1() throws Exception {
PlayerDao playerDao = sqlSession.getMapper(PlayerDao.class);
// 下边查询使用一个SqlSession
// 第一次发起请求,查询id为1的球员
Player player1 = playerDao.getPlayerById(1);
System.out.println(player1);
// 如果sqlSession去执行commit操作(执行插入、更新、删除),清空SqlSession中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读。
// 更新player1的信息
player1.setAge(88);
playerDao.updatePlayer(player1);
// 执行commit操作去清空缓存
sqlSession.commit();
// 第二次发起请求,查询id为1的球员
Player player2 = playerDao.getPlayerById(1);
System.out.println(player2);
}
}

?
总配置文件中,二级缓存也是开启的,不需要设置
<setting name="cacheEnabled" value="true"/>
mapper级别的cache需要开启,在对应的mapper.xml写入
<!--开启本mapper的二级缓存--> <cache/>
package com.sohu.tv.cache;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import com.sohu.tv.bean.Player;
import com.sohu.tv.mapper.PlayerDao;
import com.sohu.tv.test.mapper.BaseTest;
/**
* 二级缓存测试
*
* @author leifu
* @Date 2015-8-3
* @Time 下午10:10:34
*/
public class SecondCacheTest extends BaseTest {
/**
*
* @throws Exception
*/
@Test
public void testCache2() throws Exception {
SqlSession sqlSession1 = sessionFactory.openSession();
SqlSession sqlSession2 = sessionFactory.openSession();
SqlSession sqlSession3 = sessionFactory.openSession();
int targetId = 1;
PlayerDao playerDao1 = sqlSession1.getMapper(PlayerDao.class);
// 第一次发起请求,查询id为1的球员
Player player1 = playerDao1.getPlayerById(targetId);
System.out.println("player1: " + player1);
// 这里执行关闭操作,将sqlsession中的数据写到二级缓存区域
sqlSession1.close();
// 使用sqlSession3执行commit()操作
// 第一次发起请求,查询id为1的球员
PlayerDao playerDao3 = sqlSession3.getMapper(PlayerDao.class);
Player player3 = playerDao3.getPlayerById(targetId);
System.out.println("player3: " + player3);
player3.setAge(60);
playerDao3.updatePlayer(player3);
// 执行提交,清空UserMapper下边的二级缓存
sqlSession3.commit();
sqlSession3.close();
PlayerDao playerDao2 = sqlSession2.getMapper(PlayerDao.class);
// 第二次发起请求,查询id为1的用户
Player player2 = playerDao2.getPlayerById(targetId);
System.out.println("player2: " + player2);
sqlSession2.close();
}
}
?
引入jedis pom依赖:
<jedis.version>2.6.3-sohutv-SNAPSHOT</jedis.version>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>${jedis.version}</version>
</dependency>
?
jedis获取工具(使用jedispool)
package com.sohu.tv.redis;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.JedisPool;
/**
* jedisPool获取工具
*
* @author leifu
* @Date 2015年8月4日
* @Time 上午9:01:45
*/
public class RedisStandAloneUtil {
private final static Logger logger = LoggerFactory.getLogger(RedisStandAloneUtil.class);
/**
* jedis连接池
*/
private static JedisPool jedisPool;
/**
* redis-host
*/
private final static String REDIS_HOST = "10.10.52.130";
/**
* redis-port
*/
private final static int REDIS_PORT = 6384;
static {
try {
jedisPool = new JedisPool(new GenericObjectPoolConfig(), REDIS_HOST, REDIS_PORT);
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
public static JedisPool getJedisPool() {
return jedisPool;
}
public static void main(String[] args) {
System.out.println(RedisStandAloneUtil.getJedisPool().getResource().info());
}
}
?

?
Redis需要自己来实现,代码如下:
package com.sohu.tv.redis;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.ibatis.cache.Cache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.serializable.ProtostuffSerializer;
/**
* mybatis redis实现
*
* @author leifu
* @Date 2015年8月4日
* @Time 上午9:12:37
*/
public class MybatisRedisCache implements Cache {
private static Logger logger = LoggerFactory.getLogger(MybatisRedisCache.class);
private String id;
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
private final ProtostuffSerializer protostuffSerializer = new ProtostuffSerializer();
public MybatisRedisCache(final String id) {
if (logger.isInfoEnabled()) {
logger.info("============ MybatisRedisCache id {} ============", id);
}
if (id == null) {
throw new IllegalArgumentException("Cache instances require an ID");
}
this.id = id;
}
@Override
public String getId() {
return this.id;
}
@Override
public int getSize() {
Jedis jedis = null;
int size = -1;
try {
jedis = RedisStandAloneUtil.getJedisPool().getResource();
size = Integer.valueOf(jedis.dbSize().toString());
} catch (Exception e) {
logger.error(e.getMessage(), e);
} finally {
if (jedis != null) {
jedis.close();
}
}
return size;
}
@Override
public void putObject(Object key, Object value) {
if (logger.isInfoEnabled()) {
logger.info("============ putObject key: {}, value: {} ============", key, value);
}
Jedis jedis = null;
try {
jedis = RedisStandAloneUtil.getJedisPool().getResource();
byte[] byteKey = protostuffSerializer.serialize(key);
byte[] byteValue = protostuffSerializer.serialize(value);
jedis.set(byteKey, byteValue);
} catch (Exception e) {
logger.error(e.getMessage(), e);
} finally {
if (jedis != null) {
jedis.close();
}
}
}
@Override
public Object getObject(Object key) {
if (logger.isInfoEnabled()) {
logger.info("============ getObject key: {}============", key);
}
Object object = null;
Jedis jedis = null;
try {
jedis = RedisStandAloneUtil.getJedisPool().getResource();
byte[] bytes = jedis.get(protostuffSerializer.serialize(key));
if (bytes != null) {
object = protostuffSerializer.deserialize(bytes);
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
} finally {
if (jedis != null) {
jedis.close();
}
}
return object;
}
@Override
public Object removeObject(Object key) {
if (logger.isInfoEnabled()) {
logger.info("============ removeObject key: {}============", key);
}
String result = "success";
Jedis jedis = null;
try {
jedis = RedisStandAloneUtil.getJedisPool().getResource();
jedis.del(String.valueOf(key));
} catch (Exception e) {
logger.error(e.getMessage(), e);
} finally {
if (jedis != null) {
jedis.close();
}
}
return result;
}
@Override
public void clear() {
if (logger.isInfoEnabled()) {
logger.info("============ start clear cache ============");
}
String result = "fail";
Jedis jedis = null;
try {
jedis = RedisStandAloneUtil.getJedisPool().getResource();
result = jedis.flushAll();
} catch (Exception e) {
logger.error(e.getMessage(), e);
} finally {
if (jedis != null) {
jedis.close();
}
}
if (logger.isInfoEnabled()) {
logger.info("============ end clear cache result is {}============", result);
}
}
@Override
public ReadWriteLock getReadWriteLock() {
return readWriteLock;
}
}
?
?
<cache type="com.sohu.tv.redis.MybatisRedisCache"/>
MyBatis系列目录--5. MyBatis一级缓存和二级缓存(redis实现)
原文:http://carlosfu.iteye.com/blog/2240161