zoukankan      html  css  js  c++  java
  • Mybatis使用Redis二级缓存

    在Mybatis中允许开发者自定义自己的缓存,本文将使用Redis作为Mybatis的二级缓存。在Mybatis中定义二级缓存,需要如下配置:

    1、 MyBatis支持二级缓存的总开关:全局配置变量参数“cacheEnabled=true”

    2、select语句所在的Mapper需配置了<cache> 或<cached-ref>节点

    3、select语句的参数 useCache=true

    Mybatis配置文件如下:

    <settings>
    	<!-- 这个配置使全局的映射器启用或禁用缓存 -->
       	<setting name="cacheEnabled" value="true" />
       	<!-- 对于未知的SQL查询,允许返回不同的结果集以达到通用的效果 -->    
      	<setting name="multipleResultSetsEnabled" value="true"/>
        	<!-- 配置默认的执行器。SIMPLE 执行器没有什么特别之处。REUSE 执行器重用预处理语句。BATCH 执行器重用语句和批量更新 -->
        	<setting name="defaultExecutorType" value="REUSE" />
        	<!-- 全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载。 -->
        	<setting name="lazyLoadingEnabled" value="false" />
        	<setting name="aggressiveLazyLoading" value="true" />
       	<!-- <setting name="enhancementEnabled" value="true"/> -->
        	<!-- 设置超时时间,它决定驱动等待一个数据库响应的时间。 -->
        	<setting name="defaultStatementTimeout" value="25000" />
    </settings>
    

     Mybatis的Mapper的配置文件如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
    	"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    	
    <mapper namespace="user">
    
    	<!-- 二级缓存 -->
    	<cache type="com.qunar.mobile.mybatis.cache.QRedisCache"/>
    
    	<select id="getUsers" resultType="User" useCache="true">
    		select  
    			user_id as userId, user_name as username, user_desc as userDesc, create_time as createTime
    		from bisystem_user
    	</select>
    	
    	
    </mapper>
    

      自定义二级缓存需要实现Mybatis的Cache接口,Redis缓存实现如下:

    public class QRedisCache implements Cache {
    
    	private String cacheId;
    	
    	private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true); 
    	
    	public QRedisCache(String cacheId) {
    		if (cacheId == null) {
    			throw new IllegalArgumentException("Cache instances require an ID");
    		}
    		this.cacheId = cacheId;
    	}
    	
    	@Override
    	public String getId() {
    		return cacheId;
    	}
    
    	@Override
    	public void putObject(Object key, Object value) {
    		JedisUtils.put(key, value);
    	}
    
    	@Override
    	public Object getObject(Object key) {
    		return JedisUtils.get(key);
    	}
    
    	@Override
    	public Object removeObject(Object key) {
    		return JedisUtils.remove(key);
    	}
    
    	@Override
    	public void clear() {
    		JedisUtils.removeAll();
    	}
    
    	@Override
    	public int getSize() {
    		return 0;
    	}
    
    	@Override
    	public ReadWriteLock getReadWriteLock() {
    		return readWriteLock;
    	}
    
    }
    

      在QRedisCache使用的辅助类JedisUtils及SerializeUtils实现如下:

    public class JedisUtils {
    
    	private static final Logger logger = Logger.getLogger(JedisUtils.class);
    	
    	private static JedisPool JEDISPOOL;
    	
    	static {
    		Properties props = new Properties();
    		try {
    			props.load(JedisUtils.class.getResourceAsStream("/redis.properties"));
    			JedisPoolConfig conf = new JedisPoolConfig();
    			conf.setMaxIdle(Integer.valueOf(props.getProperty("jedis.pool.maxIdle")));    
    			conf.setTestOnBorrow(Boolean.valueOf(props.getProperty("jedis.pool.testOnBorrow")));    
    			conf.setTestOnReturn(Boolean.valueOf(props.getProperty("jedis.pool.testOnReturn")));    
    			JEDISPOOL = new JedisPool(conf, props.getProperty("redis.ip"), Integer.valueOf(props.getProperty("redis.port"))); 
    		} catch (IOException e) {
    			logger.error("加载[jedis.properties]异常[" + e.getMessage() + "]", e);
    		}
    	}
    	
    	public static Jedis getJedis() {
    		return JEDISPOOL.getResource();
    	}
    	
    	public static void recycleJedis(Jedis jedis) {
    		jedis.close();
    	}
    	
    	/**
    	 * Redis存储Object序列化流
    	 * */
    	public static void put(Object key, Object value) {
    		Jedis jedis = getJedis();
    		jedis.set(SerializeUtils.serialize(key), SerializeUtils.serialize(value));
    		recycleJedis(jedis);
    	}
    	
    	public static <T> T get(Object key) {
    		Jedis jedis = getJedis();
    		T value = SerializeUtils.unserialize(jedis.get(SerializeUtils.serialize(key)));
    		recycleJedis(jedis);
    		return value;
    	}
    	
    	public static Long remove(Object key) {
    		Jedis jedis = getJedis();
    		Long num = jedis.del(SerializeUtils.serialize(key));
    		recycleJedis(jedis);
    		return num;
    	}
    	
    	public static void removeAll() {
    		Jedis jedis = getJedis();
    		jedis.flushDB();
    		recycleJedis(jedis);
    	}
    }
    
    
    public class SerializeUtils {
    
    	private static final Logger logger = Logger.getLogger(SerializeUtils.class);
    	
    	private static void close(ObjectOutputStream objectOutputStream, ByteArrayOutputStream byteArrayOutputStream) {
    		try {
    			if (byteArrayOutputStream != null) {
    				byteArrayOutputStream.close();
    			}
    			if (objectOutputStream != null) {
    				objectOutputStream.close();
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    			logger.error("关闭IO资源异常[" + e.getMessage() + "]", e);
    		}
    	}
    	
    	private static void close(ObjectInputStream objectInputStream, ByteArrayInputStream byteArrayInputStream) {
    		try {
    			if (objectInputStream != null) {
    				objectInputStream.close();
    			}
    			if (byteArrayInputStream != null) {
    				byteArrayInputStream.close();
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    			logger.error("关闭IO资源异常[" + e.getMessage() + "]", e);
    		}
    	}
    	
    	public static byte[] serialize(Object object) {
    		ObjectOutputStream objectOutputStream = null;
    		ByteArrayOutputStream byteArrayOutputStream = null;
    		try {
    			byteArrayOutputStream = new ByteArrayOutputStream();
    			objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
    			objectOutputStream.writeObject(object);
    			byte[] bytes = byteArrayOutputStream.toByteArray();
    			return bytes;
    		} catch (Exception e) {
    			e.printStackTrace();
    			logger.error("序列化对象异常[" + e.getMessage() + "]", e);
    		} finally {
    			close(objectOutputStream, byteArrayOutputStream);
    		}
    		return null;
    	}
    
    	@SuppressWarnings("unchecked")
    	public static <T> T unserialize(byte[] bytes) {
    		if (bytes == null)
    			return null;
    		ByteArrayInputStream byteArrayInputStream = null;
    		ObjectInputStream objectInputStream = null;
    		try {
    			byteArrayInputStream = new ByteArrayInputStream(bytes);
    			objectInputStream = new ObjectInputStream(byteArrayInputStream);
    			return (T) objectInputStream.readObject();
    		} catch (Exception e) {
    			e.printStackTrace();
    		} finally {
    			close(objectInputStream, byteArrayInputStream);
    		}
    		return null;
    	}
    
    }
    

      Redis的配置文件redis.properties如下:

    #redis服务器ip#   
    
    redis.ip=192.168.2.107
    
    #redis服务器端口号#  
    
    redis.port=6379
    
    #********jedis池参数设置********#  
    
    #jedis的最大分配对象#  
    
    jedis.pool.maxActive=3000
    
    #jedis最大保存idel状态对象数 #  
    
    jedis.pool.maxIdle=1000
    
    #jedis池没有对象返回时,最大等待时间 #  
    
    jedis.pool.maxWait=1500
    
    #jedis调用borrowObject方法时,是否进行有效检查#  
    
    jedis.pool.testOnBorrow=true
    
    #jedis调用returnObject方法时,是否进行有效检查 #  
    
    jedis.pool.testOnReturn=true
    

      

     

  • 相关阅读:
    转:Java 6 JVM参数选项大全(中文版)
    转:Http Get Post put delete
    转:Google MapReduce中文版
    转:java.net.SocketException: Too many open files解决方法
    转:UML类图基础
    转:Maven常用命令
    转:ibatis配置简介
    转:导出 Oracle 数据库中所所有用户表的表结构
    C# 中使用iTextSharp组件修改PDF元数据(title,Keywords等)
    SQL Server跨服务器查询
  • 原文地址:https://www.cnblogs.com/hanfight/p/4823204.html
Copyright © 2011-2022 走看看