Mybatis集成Redis

来源:互联网 发布:python init 编辑:程序博客网 时间:2024/05/16 14:40

emp_mapper.xml

<mapper namespace="cn.et.EmpMapper"><!--<cache></cache> 启用二级缓存  属性默认 type 指定使用哪个一个缓存类  --><cache type="cn.et.JedisCache"></cache><select id="selectEmp" resultType="cn.et.Emp">select * from emp where empno = #{0}</select></mapper>

JedisCache

package cn.et;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.util.Set;import java.util.concurrent.locks.ReadWriteLock;import java.util.concurrent.locks.ReentrantReadWriteLock;import org.apache.commons.pool2.impl.GenericObjectPoolConfig;import org.apache.ibatis.cache.Cache;import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisPool;/** * 当在查询时会自动实例化JedisCache类并且传入mapper查询的id; * @author Ma-PC * */public class JedisCache implements Cache {/** * 用于序列化和反序列化的操作类 * @author Ma-PC */static class SeqUtils{/** * 字节数组反序列化为对象的方法 * @param by * @return Object * @throws IOException * @throws ClassNotFoundException  */public static Object deSer(byte[] by) throws IOException, ClassNotFoundException{ByteArrayInputStream bais = new ByteArrayInputStream(by);ObjectInputStream ois = new ObjectInputStream(bais);return ois.readObject();}/** * 对象序列化成字节数组的方法 * @param obj * @returnbyte[] * @throws IOException */public static byte[] ser(Object obj) throws IOException{ByteArrayOutputStream baos = new ByteArrayOutputStream();ObjectOutputStream obos = new ObjectOutputStream(baos);obos.writeObject(obj);return baos.toByteArray();}}private static JedisPool jp = null;private String id ;public JedisCache(String id) {if(jp == null){//当redis出现异常时,将连接池设为null;//目的是将redis与数据库完全分离达到高可用性;try {//设置连接池属性的类GenericObjectPoolConfig gopc = new GenericObjectPoolConfig();jp = new JedisPool(gopc, "localhost");jp.getResource();} catch (Exception e) {//e.printStackTrace();jp=null;}}this.id = id;}public String getId() {return id;}/** * 第一次查询数据后 会调用putObject将数据写入到缓存中; */public void putObject(Object key, Object value) {//到连接池为null时,不写入数据if(jp==null){return ;}Jedis jedis = jp.getResource();try {jedis.set(SeqUtils.ser(key), SeqUtils.ser(value));//将缓存中的数据保存到本地文件;//jedis.save();//将redis对象回收到连接池中;jp.returnResourceObject(jedis);} catch (IOException e) {e.printStackTrace();}}/** * 自动调用该方法 当返回为null时自动查询数据库 * 否则直接使用返回的对象 * key 其实就是 oId; */public Object getObject(Object key) {//当连接池为null时,直接查询数据库if(jp==null){return null;}Jedis jedis = jp.getResource();try {byte[] be =jedis.get(SeqUtils.ser(key));if(be != null){Object obj = SeqUtils.deSer(be);//将redis对象回收到连接池中;jp.returnResourceObject(jedis);return obj;}} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}return null;}/** * 调用了例如 mybatis 的 flush方法  清空缓存 * 就会自动调用removeObject清空该元素 */public Object removeObject(Object key) {Jedis jedis = jp.getResource();try {jedis.del(SeqUtils.ser(key));//将redis对象回收到连接池中;jp.returnResourceObject(jedis);} catch (IOException e) {e.printStackTrace();}return null;}/** *清空所有缓存  */public void clear() {Jedis jedis = jp.getResource();jedis.flushAll();//将redis对象回收到连接池中;jp.returnResourceObject(jedis);}/** * 用于获取redis中缓存了多少元素 */public int getSize() {Jedis jedis = jp.getResource();//*表示所有Set<String> allElemebts = jedis.keys("*");return allElemebts.size();}/** * 非阻塞式io  non-blocking io 简单可以理解成 异步调用的io流 * 处理读写相同数据时的线程安全问题 */public ReadWriteLock getReadWriteLock() {return new ReentrantReadWriteLock();}}


Test

/** * 二级缓存 * @param args */public static void main(String[] args) {SqlSessionFactory factory = getSqlSessionFactory();SqlSession session = factory.openSession();EmpMapper dm = session.getMapper(EmpMapper.class);Emp emp = dm.selectEmp("7369");//开启二级缓存后  关闭session时   //session中一级缓存的数据会自动发往二级缓存session.close();//打开第二个SqlSessionSqlSession session2 = factory.openSession();//通过sqlSession2获取EmpMapper实例EmpMapper em = session2.getMapper(EmpMapper.class);Emp selectEmp = em.selectEmp("7369");System.out.println(emp==selectEmp);}


Run

第一次运行:第一次到数据库查询后,写入缓存中,往后相同的查询直接使用缓存中的数据
2017-07-13 10:35:34 DEBUG [cn.et..EmpMapper.selectEmp] ==>  Preparing: select * from emp where empno = ? 2017-07-13 10:35:34 DEBUG [cn.et.EmpMapper.selectEmp] ==> Parameters: 7369(String)2017-07-13 10:35:34 DEBUG [cn.et.EmpMapper.selectEmp] <==      Total: 12017-07-13 10:35:34 DEBUG [org.apache.ibatis.transaction.jdbc.JdbcTransaction] Resetting autocommit to true on JDBC Connection [oracle.jdbc.driver.T4CConnection@dc85d20]2017-07-13 10:35:34 DEBUG [org.apache.ibatis.transaction.jdbc.JdbcTransaction] Closing JDBC Connection [oracle.jdbc.driver.T4CConnection@dc85d20]2017-07-13 10:35:34 DEBUG [org.apache.ibatis.datasource.pooled.PooledDataSource] Returned connection 231234848 to pool.2017-07-13 10:35:34 DEBUG [cn.et.EmpMapper] Cache Hit Ratio [cn.et.lesson05.EmpMapper]: 0.5


第二次运行:

2017-07-13 10:37:35 DEBUG [cn.et.EmpMapper] Cache Hit Ratio [cn.et.EmpMapper]: 1.02017-07-13 10:37:35 DEBUG [cn.et.EmpMapper] Cache Hit Ratio [cn.et.EmpMapper]: 1.0


第三次关闭Redis服务器后运行 :

2017-07-13 10:40:09 DEBUG [cn.et.EmpMapper.selectEmp] ==>  Preparing: select * from emp where empno = ? 2017-07-13 10:40:09 DEBUG [cn.et.EmpMapper.selectEmp] ==> Parameters: 7369(String)2017-07-13 10:40:09 DEBUG [cn.et.EmpMapper.selectEmp] <==      Total: 12017-07-13 10:40:09 DEBUG [org.apache.ibatis.transaction.jdbc.JdbcTransaction] Resetting autocommit to true on JDBC Connection [oracle.jdbc.driver.T4CConnection@fd1c5f4]2017-07-13 10:40:09 DEBUG [org.apache.ibatis.transaction.jdbc.JdbcTransaction] Closing JDBC Connection [oracle.jdbc.driver.T4CConnection@fd1c5f4]2017-07-13 10:40:09 DEBUG [org.apache.ibatis.datasource.pooled.PooledDataSource] Returned connection 265405940 to pool.2017-07-13 10:40:09 DEBUG [cn.et.EmpMapper] Cache Hit Ratio [cn.et.EmpMapper]: 0.02017-07-13 10:40:09 DEBUG [org.apache.ibatis.transaction.jdbc.JdbcTransaction] Opening JDBC Connection2017-07-13 10:40:09 DEBUG [org.apache.ibatis.datasource.pooled.PooledDataSource] Checked out connection 265405940 from pool.2017-07-13 10:40:09 DEBUG [org.apache.ibatis.transaction.jdbc.JdbcTransaction] Setting autocommit to false on JDBC Connection [oracle.jdbc.driver.T4CConnection@fd1c5f4]2017-07-13 10:40:09 DEBUG [cn.et.EmpMapper.selectEmp] ==>  Preparing: select * from emp where empno = ? 2017-07-13 10:40:09 DEBUG [cn.et.EmpMapper.selectEmp] ==> Parameters: 7369(String)2017-07-13 10:40:09 DEBUG [cn.et.EmpMapper.selectEmp] <==      Total: 1


原创粉丝点击