?
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