最近想在框架里面加入redis,替换原因呢其实也没有,就是单纯的想替换掉
---维基百科:redis介绍
一般开发中用户状态使用session或者cookie,两种方式各种利弊。
Session:在InProc模式下容易丢失,并且引起并发问题。如果使用SQLServer或者SQLServer模式又消耗了性能
Cookie则容易将一些用户信息暴露,加解密同样也消耗了性能。
Redis采用这样的方案解决了几个问题,
1.Redis存取速度快。
2.用户数据不容易丢失。
3.用户多的情况下容易支持集群。
4.能够查看在线用户。
5.能够实现用户一处登录。(通过代码实现,后续介绍)
6.支持持久化。(当然可能没什么用)
然后研究了2天怎么去整合spring mybatis和redis...
新创建一个redis工具类
package cx.common.utils.redis; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.apache.log4j.Logger; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; /** * * @ClassName RedisUtils * @Description Redis缓存工具类 * @author K * @Date 2016年6月22日 下午6:08:52 * @version 1.0.0 */ public class RedisUtils { private static Logger logger = Logger.getLogger(RedisUtils.class); /** 默认缓存时间 */ private static final int DEFAULT_CACHE_SECONDS = 60 * 60 * 1;// 单位秒 设置成一个钟 /** 连接池 **/ private static JedisPool jedisPool; static { if (jedisPool == null) { JedisPoolConfig config = new JedisPoolConfig(); //控制一个pool可分配多少个jedis实例,通过pool.getResource()来获取; //如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。 config.setMaxIdle(8); //控制一个pool最多有多少个状态为idle(空闲的)的jedis实例。 config.setMaxTotal(8); //表示当borrow(引入)一个jedis实例时,最大的等待时间,如果超过等待时间,则直接抛出JedisConnectionException; config.setMaxWaitMillis(1000 * 100); //在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的; config.setTestOnBorrow(true); config.setMinEvictableIdleTimeMillis(60000); config.setTimeBetweenEvictionRunsMillis(30000); config.setNumTestsPerEvictionRun(-1); config.setMinIdle(0); jedisPool = new JedisPool(config, "192.168.11.247", 6379); } } /** * 释放redis资源 * * @param jedis */ private static void releaseResource(Jedis jedis) { if (jedis != null) { jedisPool.returnResource(jedis); } } /** * 删除Redis中的所有key * * @param jedis * @throws Exception */ public static void flushAll() { Jedis jedis = null; try { jedis = jedisPool.getResource(); jedis.flushAll(); } catch (Exception e) { logger.error("Cache清空失败:" + e); } finally { releaseResource(jedis); } } /** * 保存一个对象到Redis中(缓存过期时间:使用此工具类中的默认时间) . <br/> * * @param key * 键 . <br/> * @param object * 缓存对象 . <br/> * @return true or false . <br/> * @throws Exception */ public static Boolean save(Object key, Object object) { return save(key, object, DEFAULT_CACHE_SECONDS); } /** * 保存一个对象到redis中并指定过期时间 * * @param key * 键 . <br/> * @param object * 缓存对象 . <br/> * @param seconds * 过期时间(单位为秒).<br/> * @return true or false . */ public static Boolean save(Object key, Object object, int seconds) { Jedis jedis = null; try { jedis = jedisPool.getResource(); jedis.set(SerializeUtils.serialize(key), SerializeUtils.serialize(object)); jedis.expire(SerializeUtils.serialize(key), seconds); return true; } catch (Exception e) { logger.error("Cache保存失败:" + e); return false; } finally { releaseResource(jedis); } } /** * 根据缓存键获取Redis缓存中的值.<br/> * * @param key * 键.<br/> * @return Object .<br/> * @throws Exception */ public static Object get(Object key) { Jedis jedis = null; try { jedis = jedisPool.getResource(); byte[] obj = jedis.get(SerializeUtils.serialize(key)); return obj == null ? null : SerializeUtils.unSerialize(obj); } catch (Exception e) { logger.error("Cache获取失败:" + e); return null; } finally { releaseResource(jedis); } } /** * 根据缓存键清除Redis缓存中的值.<br/> * * @param key * @return * @throws Exception */ public static Boolean del(Object key) { Jedis jedis = null; try { jedis = jedisPool.getResource(); jedis.del(SerializeUtils.serialize(key)); return true; } catch (Exception e) { logger.error("Cache删除失败:" + e); return false; } finally { releaseResource(jedis); } } /** * 根据缓存键清除Redis缓存中的值.<br/> * * @param keys * @return * @throws Exception */ public static Boolean del(Object... keys) { Jedis jedis = null; try { jedis = jedisPool.getResource(); jedis.del(SerializeUtils.serialize(keys)); return true; } catch (Exception e) { logger.error("Cache删除失败:" + e); return false; } finally { releaseResource(jedis); } } /** * * @param key * @param seconds * 超时时间(单位为秒) * @return */ public static Boolean expire(Object key, int seconds) { Jedis jedis = null; try { jedis = jedisPool.getResource(); jedis.expire(SerializeUtils.serialize(key), seconds); return true; } catch (Exception e) { logger.error("Cache设置超时时间失败:" + e); return false; } finally { releaseResource(jedis); } } /** * 添加一个内容到指定key的hash中 * * @param key * @param field * @param value * @return */ public static Boolean addHash(String key, Object field, Object value) { Jedis jedis = null; try { jedis = jedisPool.getResource(); jedis.hset(SerializeUtils.serialize(key), SerializeUtils.serialize(field), SerializeUtils.serialize(value)); return true; } catch (Exception e) { logger.error("Cache保存失败:" + e); return false; } finally { releaseResource(jedis); } } /** * 从指定hash中拿一个对象 * * @param key * @param field * @return */ public static Object getHash(Object key, Object field) { Jedis jedis = null; try { jedis = jedisPool.getResource(); byte[] obj = jedis.hget(SerializeUtils.serialize(key), SerializeUtils.serialize(field)); return SerializeUtils.unSerialize(obj); } catch (Exception e) { logger.error("Cache读取失败:" + e); return null; } finally { releaseResource(jedis); } } /** * 从hash中删除指定filed的值 * * @param key * @param field * @return */ public static Boolean delHash(Object key, Object field) { Jedis jedis = null; try { jedis = jedisPool.getResource(); long result = jedis.hdel(SerializeUtils.serialize(key), SerializeUtils.serialize(field)); return result == 1 ? true : false; } catch (Exception e) { logger.error("Cache删除失败:" + e); return null; } finally { releaseResource(jedis); } } /** * 拿到缓存中所有符合pattern的key * * @param pattern * @return */ public static Set<byte[]> keys(String pattern) { Jedis jedis = null; try { jedis = jedisPool.getResource(); Set<byte[]> allKey = jedis.keys(("*" + pattern + "*").getBytes()); return allKey; } catch (Exception e) { logger.error("Cache获取失败:" + e); return new HashSet<byte[]>(); } finally { releaseResource(jedis); } } /** * 获得hash中的所有key value * * @param key * @return */ public static Map<byte[], byte[]> getAllHash(Object key) { Jedis jedis = null; try { jedis = jedisPool.getResource(); Map<byte[], byte[]> map = jedis.hgetAll(SerializeUtils.serialize(key)); return map; } catch (Exception e) { logger.error("Cache获取失败:" + e); return null; } finally { releaseResource(jedis); } } /** * 判断一个key是否存在 * * @param key * @return */ public static Boolean exists(Object key) { Jedis jedis = null; Boolean result = false; try { jedis = jedisPool.getResource(); result = jedis.exists(SerializeUtils.serialize(key)); return result; } catch (Exception e) { logger.error("Cache获取失败:" + e); return false; } finally { releaseResource(jedis); } } public void setjedisPool(JedisPool jedisPool) { RedisUtils.jedisPool = jedisPool; } public static JedisPool getjedisPool() { return jedisPool; } }
创建一个序列化工具类
package cx.common.utils.redis; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import org.apache.log4j.Logger; /** * * @ClassName SerializeUtils * @Description 序列化工具 * @author K * @Date 2016年6月24日 上午9:44:38 * @version 1.0.0 */ public class SerializeUtils { private static Logger logger = Logger.getLogger(SerializeUtils.class); /** * * @Description 序列化 * @param object * @return * @throws Exception */ public static byte[] serialize(Object object) throws Exception { if(object == null) return null; ObjectOutputStream oos = null; ByteArrayOutputStream baos = null; try { // 序列化 baos = new ByteArrayOutputStream(); oos = new ObjectOutputStream(baos); oos.writeObject(object); byte[] bytes = baos.toByteArray(); return bytes; } catch (Exception e) { logger.error(e); throw e; } } /** * * @Description 反序列化 * @param bytes * @return * @throws Exception */ public static Object unSerialize(byte[] bytes) throws Exception { if(bytes == null) return null; ByteArrayInputStream bais = null; try { // 反序列化 bais = new ByteArrayInputStream(bytes); ObjectInputStream ois = new ObjectInputStream(bais); return ois.readObject(); } catch (Exception e) { logger.error(e); throw e; } } }
redis 管理
package cx.common.utils.redis.springImpl; import java.util.Collection; import org.springframework.cache.Cache; import org.springframework.cache.support.AbstractCacheManager; /** * * @ClassName CacheManager * @Description 继承了 spring 的 AbstractCacheManager 管理 RedisCache 类缓存管理 * @author K * @Date 2016年6月27日 下午1:55:49 * @version 1.0.0 * @param <T> */ public class CacheManager<T extends Object> extends AbstractCacheManager { private Collection<? extends RedisCache> caches; public void setCaches(Collection<? extends RedisCache> caches) { this.caches = caches; } @Override protected Collection<? extends Cache> loadCaches() { return this.caches; } }
继承spring缓存来实现redis
package cx.service.shiro.mybatis.cache.redis; import org.apache.ibatis.cache.decorators.LoggingCache; /** * * @ClassName MybatiesRedisCache * @Description 根据SPring API 自定义一个缓存类 ,实现Redis 缓存 * @author K * @Date 2016年6月27日 下午3:30:52 * @version 1.0.0 */ public class MybatiesRedisCache extends LoggingCache { public MybatiesRedisCache(String id) { super(new RedisCache(id)); } }
redis初始化 和连接池
package cx.service.shiro.mybatis.cache.redis; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.exceptions.JedisConnectionException; import cx.common.utils.redis.RedisUtils; /** * * @ClassName CachePool * @Description redis 初始化 * 由于需结合Mybatis实现 不与Spring redis注解实现混用。 * 与Spring redis注解实现 各独立实现各自功能。 * @author K * @Date 2016年6月27日 下午3:29:03 * @version 1.0.0 */ public class CachePool { JedisPool pool; private static final CachePool cachePool = new CachePool(); private RedisUtils readisUtils = new RedisUtils(); /**单例模式*/ public static CachePool getInstance(){ return cachePool; } /**初始化*/ private CachePool() { pool = readisUtils.getjedisPool(); } public Jedis getJedis(){ Jedis jedis = null; boolean borrowOrOprSuccess = true; try { jedis = pool.getResource(); } catch (JedisConnectionException e) { borrowOrOprSuccess = false; if (jedis != null) pool.returnBrokenResource(jedis); } finally { if (borrowOrOprSuccess) pool.returnResource(jedis); } jedis = pool.getResource(); return jedis; } public JedisPool getJedisPool(){ return this.pool; } }
实现
package cx.service.shiro.mybatis.cache.redis; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.ibatis.cache.Cache; import cx.common.utils.redis.SerializeUtils; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.exceptions.JedisConnectionException; /** * * @ClassName RedisCache * @Description Mybatis 接口 实现 redis 功能 类 * @author K * @Date 2016年6月27日 下午3:29:45 * @version 1.0.0 */ public class RedisCache implements Cache { private static Log log = LogFactory.getLog(RedisCache.class); private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); private String id; public RedisCache(final String id) { if (id == null) { throw new IllegalArgumentException("必须传入ID"); } log.debug("MybatisRedisCache:id=" + id); this.id = id; } @Override public String getId() { return this.id; } @Override public int getSize() { Jedis jedis = null; JedisPool jedisPool = null; int result = 0; boolean borrowOrOprSuccess = true; try { jedis = CachePool.getInstance().getJedis(); jedisPool = CachePool.getInstance().getJedisPool(); result = Integer.valueOf(jedis.dbSize().toString()); } catch (JedisConnectionException e) { borrowOrOprSuccess = false; if (jedis != null) jedisPool.returnBrokenResource(jedis); } finally { if (borrowOrOprSuccess) jedisPool.returnResource(jedis); } return result; } @Override public void putObject(Object key, Object value) { if (log.isDebugEnabled()) log.debug("putObject:" + key.hashCode() + "=" + value); if (log.isInfoEnabled()) log.info("put to redis sql :" + key.toString()); Jedis jedis = null; JedisPool jedisPool = null; boolean borrowOrOprSuccess = true; try { jedis = CachePool.getInstance().getJedis(); jedisPool = CachePool.getInstance().getJedisPool(); jedis.set(SerializeUtils.serialize(key.hashCode()), SerializeUtils.serialize(value)); } catch (JedisConnectionException e) { borrowOrOprSuccess = false; if (jedis != null) jedisPool.returnBrokenResource(jedis); } catch (Exception e) { e.printStackTrace(); } finally { if (borrowOrOprSuccess) jedisPool.returnResource(jedis); } } @Override public Object getObject(Object key) { Jedis jedis = null; JedisPool jedisPool = null; Object value = null; boolean borrowOrOprSuccess = true; try { jedis = CachePool.getInstance().getJedis(); jedisPool = CachePool.getInstance().getJedisPool(); System.out.println(key.hashCode()); System.out.println(SerializeUtils.serialize(key.hashCode())); System.out.println(jedis.get(SerializeUtils.serialize(key.hashCode()))); value = SerializeUtils.unSerialize(jedis.get(SerializeUtils.serialize(key.hashCode()))); } catch (JedisConnectionException e) { borrowOrOprSuccess = false; if (jedis != null) jedisPool.returnBrokenResource(jedis); } catch (Exception e) { e.printStackTrace(); } finally { if (borrowOrOprSuccess) jedisPool.returnResource(jedis); } if (log.isDebugEnabled()) log.debug("getObject:" + key.hashCode() + "=" + value); return value; } @Override public Object removeObject(Object key) { Jedis jedis = null; JedisPool jedisPool = null; Object value = null; boolean borrowOrOprSuccess = true; try { jedis = CachePool.getInstance().getJedis(); jedisPool = CachePool.getInstance().getJedisPool(); value = jedis.expire(SerializeUtils.serialize(key.hashCode()), 0); } catch (JedisConnectionException e) { borrowOrOprSuccess = false; if (jedis != null) jedisPool.returnBrokenResource(jedis); } catch (Exception e) { e.printStackTrace(); } finally { if (borrowOrOprSuccess) jedisPool.returnResource(jedis); } if (log.isDebugEnabled()) log.debug("getObject:" + key.hashCode() + "=" + value); return value; } @Override public void clear() { Jedis jedis = null; JedisPool jedisPool = null; boolean borrowOrOprSuccess = true; try { jedis = CachePool.getInstance().getJedis(); jedisPool = CachePool.getInstance().getJedisPool(); jedis.flushDB(); jedis.flushAll(); } catch (JedisConnectionException e) { borrowOrOprSuccess = false; if (jedis != null) jedisPool.returnBrokenResource(jedis); } finally { if (borrowOrOprSuccess) jedisPool.returnResource(jedis); } } @Override public ReadWriteLock getReadWriteLock() { return readWriteLock; } }
redis配置文件spring-jedis.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:cache="http://www.springframework.org/schema/cache" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd" default-autowire="byName" default-lazy-init="false"> <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="testWhileIdle" value="true" /> <property name="minEvictableIdleTimeMillis" value="60000" /> <property name="timeBetweenEvictionRunsMillis" value="30000" /> <property name="numTestsPerEvictionRun" value="-1" /> <property name="maxTotal" value="8" /> <property name="maxIdle" value="8" /> <property name="minIdle" value="0" /> </bean> <bean id="shardedJedisPool" class="redis.clients.jedis.ShardedJedisPool"> <constructor-arg index="0" ref="jedisPoolConfig" /> <constructor-arg index="1"> <list> <bean class="redis.clients.jedis.JedisShardInfo"> <constructor-arg index="0" value="192.168.11.247" /> <constructor-arg index="1" value="6379" type="int" /> </bean> </list> </constructor-arg> </bean> <!-- generic cache manager --> <cache:annotation-driven /> <!-- generic cache manager --> <bean id="cacheManager" class="cx.common.utils.redis.springImpl.CacheManager"> <property name="caches"> <set> <bean class="cx.common.utils.redis.springImpl.RedisCache" p:name="redisCache" /> </set> </property> </bean> </beans>
mybatis配置文件mybatis-config.xml中开启缓存
<settings> <!-- 这个配置使全局的映射器启用或禁用 缓存 --> <span style="color:#FF0000;"> <setting name="cacheEnabled" value="true" /></span> <!-- 全局启用或禁用延迟加载。当禁用时, 所有关联对象都会即时加载 --> <setting name="lazyLoadingEnabled" value="false" /> <setting name="aggressiveLazyLoading" value="true" /> <!-- 允许或不允许多种结果集从一个单独 的语句中返回(需要适合的驱动) --> <setting name="multipleResultSetsEnabled" value="true" /> <!-- 使用列标签代替列名。 不同的驱动在这 方便表现不同。 参考驱动文档或充分测 试两种方法来决定所使用的驱动 --> <setting name="useColumnLabel" value="true" /> <!-- 允许 JDBC 支持生成的键。 需要适合的 驱动。 如果设置为 true 则这个设置强制 生成的键被使用, 尽管一些驱动拒绝兼 容但仍然有效(比如 Derby) --> <setting name="useGeneratedKeys" value="false" /> <!-- 配置默认的执行器。SIMPLE 执行器没 有什么特别之处。REUSE 执行器重用 预处理语句。BATCH 执行器重用语句 和批量更新 --> <setting name="defaultExecutorType" value="SIMPLE" /> <!-- 设置超时时间, 它决定驱动等待一个数 据库响应的时间 --> <setting name="defaultStatementTimeout" value="100" /> <setting name="safeRowBoundsEnabled" value="false" /> <setting name="mapUnderscoreToCamelCase" value="false" /> <setting name="localCacheScope" value="SESSION" /> <setting name="jdbcTypeForNull" value="OTHER" /> <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString" /> </settings>
添加缓存到mybatis.mapper sql文中
<?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"> <!--定义mybatis自身应用信息--> <mapper namespace="cx.service.shiro.dao.impl.SysConfigDaoImpl"> <!--redis缓存--> <cache eviction="LRU" type="cx.service.shiro.mybatis.cache.redis.MybatiesRedisCache" /> <!--数据库表名--> <sql id="table">SYS_CONFIG</sql> <!--配置映射文件--> <resultMap id="BaseResultMap" type="cx.facade.shiro.entity.SysConfig"> <id column="id" property="id" /> <result column="name" property="name" /> <result column="config_keys" property="configKeys" /> <result column="config_value" property="configValue" /> <result column="description" property="description" /> <result column="is_sys" property="isSys" /> <result column="create_by" property="createBy" /> <result column="create_date" property="createDate" /> <result column="update_by" property="updateBy" /> <result column="update_date" property="updateDate" /> <result column="status" property="status" /> </resultMap> <sql id="condition_sql"> <if test="id != null and id != ''"> and id = #{id}</if> <if test="name != null and name != ''"> and name = #{name}</if> <if test="configKeys != null and configKeys != ''"> and config_keys = #{configKeys}</if> <if test="configValue != null and configValue != ''"> and config_value = #{configValue}</if> <if test="description != null and description != ''"> and description = #{description}</if> <if test="isSys != null and isSys != ''"> and is_sys = #{isSys}</if> <if test="createBy != null and createBy != ''"> and create_by = #{createBy}</if> <if test="createDate != null and createDate != ''"> and create_date = #{createDate}</if> <if test="updateBy != null and updateBy != ''"> and update_by = #{updateBy}</if> <if test="updateDate != null and updateDate != ''"> and update_date = #{updateDate}</if> <if test="status != null and status != ''"> and status = #{status}</if> </sql> <insert id="insert" useGeneratedKeys="true" keyProperty="id" parameterType="cx.facade.shiro.entity.SysConfig" <span style="color:#FF0000;">flushCache="true"</span>> insert into <include refid="table" /> (id,name,config_keys,config_value,description,is_sys,create_by,create_date,update_by,update_date,status) values ( #{id},#{name},#{configKeys},#{configValue},#{description},#{isSys},#{createBy},#{createDate},#{updateBy},#{updateDate},#{status}) </insert> <update id="update" parameterType="cx.facade.shiro.entity.SysConfig" <span style="color:#FF0000;">flushCache="true"</span>> update <include refid="table" /> <set> id = #{id}, name = #{name}, config_keys = #{configKeys}, config_value = #{configValue}, description = #{description}, is_sys = #{isSys}, create_by = #{createBy}, create_date = #{createDate}, update_by = #{updateBy}, update_date = #{updateDate}, status = #{status} </set> <where> <include refid="condition_sql" /> </where> </update> <select id="listPage" parameterType="java.util.Map" resultMap="BaseResultMap" <span style="color:#FF0000;">flushCache="false" useCache="true"</span>> SELECT * FROM <include refid="table" /> <where> <include refid="condition_sql" /> </where> <![CDATA[ order by key desc]]> </select> <insert id="batchInsert" parameterType="cx.facade.shiro.entity.SysConfig" <span style="color:#FF0000;">flushCache="true"</span>> insert into <include refid="table" /> (id,name,config_keys,config_value,description,is_sys,create_by,create_date,update_by,update_date,status) values ( <foreach collection="list" item="item" index="index" separator=","> #{id},#{name},#{configKeys},#{configValue},#{description},#{isSys},#{createBy},#{createDate},#{updateBy},#{updateDate},#{status}) </foreach> </insert> <select id="listBy" parameterType="java.util.Map" resultMap="BaseResultMap" <span style="color:#FF0000;">flushCache="false" useCache="true"</span>> SELECT * FROM <include refid="table" /> <where> <include refid="condition_sql" /> </where> </select> </mapper>
<span style="color:#FF0000;"></span>
在MyBatis中有flushCache、useCache这两个配置属性,分为下面几种情况:
(1)当为select语句时:
flushCache默认为false,表示任何时候语句被调用,都不会去清空本地缓存和二级缓存。
useCache默认为true,表示会将本条语句的结果进行二级缓存。
(2)当为insert、update、delete语句时:
flushCache默认为true,表示任何时候语句被调用,都会导致本地缓存和二级缓存被清空。
useCache属性在该情况下没有。
上面的信息我是从MyBatis官方文档中找到的,会发现当为select语句的时候,如果没有去配置flushCache、useCache,那么默认是启用缓存的,所以,如果有必要,那么就需要人工修改配置,修改结果类似下面:
<select id="save" parameterType="XXXXXEO" statementType="CALLABLE" flushCache="true" useCache="false"> …… </select>
然后编写测试类
package cx.service.dubbotest; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.context.support.ClassPathXmlApplicationContext; import cx.facade.shiro.entity.SysCompany; import cx.facade.shiro.entity.SysConfig; import cx.service.shiro.biz.SysCompanyBiz; import cx.service.shiro.biz.SysConfigBiz; /** * * @ClassName SpringMybatisRedis * @Description redis测试用的MainClass. * @author K * @Date 2016年6月22日 上午11:14:30 * @version 1.0.0 */ public class SpringMybatisRedis { private static final Log log = LogFactory.getLog(SpringMybatisRedis.class); @SuppressWarnings("resource") public static void main(String[] args) { try { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring/spring-context.xml"); context.start(); SysConfigBiz sysConfigBiz = (SysConfigBiz) context.getBean("sysConfigBiz"); SysCompanyBiz sysCompanyBiz = (SysCompanyBiz) context.getBean("sysCompanyBiz"); SysCompany sysCompany =new SysCompany(); sysCompany.setCompanyCode("562w2s49qd653l7311"); sysCompany.setParentCode("jk1"); sysCompany.setUpdateBy("jkjk"); sysCompany.setUpdateDate(new Date()); sysCompany.setCreateBy("jkjk"); sysCompany.setCreateDate(new Date()); // sysCompanyBiz.insertCompany(sysCompany); SysConfig sysConfig = new SysConfig(); sysConfig.setId("562w2s49qd653l7311"); sysConfig.setConfigKeys("jkjk"); sysConfig.setConfigValue("jkjk"); sysConfig.setName("jkjk"); sysConfig.setCreateBy("jkjk"); sysConfig.setCreateDate(new Date()); sysConfig.setDescription("jkjk"); sysConfig.setIsSys("1"); sysConfig.setStatus("0"); sysConfig.setUpdateBy("jkjk"); sysConfig.setUpdateDate(new Date()); // sysConfigBiz.insertConfig(sysConfig); Map<String, Object> paramMap = new HashMap<String, Object>(); paramMap.put("id", "503882516984905728"); SysConfig dsds = sysConfigBiz.getConfig(paramMap); // List<SysConfig> dsds = sysConfigBiz.getConfigs(paramMap); paramMap = new HashMap<String, Object>(); paramMap.put("copanyCode", "562w2s495d653l7311"); List<SysCompany> qwdas = sysCompanyBiz.getCompanys(paramMap); // SysConfig dsds = sysConfigBiz.getConfig(paramMap); System.out.println("*****************************jk**********************:"); // System.out.println(dsds.getId()+"*****************************jk**********************:"); // for (int i = 0; i < dsds.size(); i++) { // System.out.println("配置:"+dsds.get(i).getId()); // } for (int i = 0; i < qwdas.size(); i++) { System.out.println("组织:"+qwdas.get(i).getCompanyCode()); } context.stop(); } catch (Exception e) { log.error("== DubboProvider context start error:", e); }finally { log.info("===>System.exit"); System.exit(0); } } }
经过测试就发现写的时候清空缓存,读的时候先读区缓存,缓存没有读区数据库,然后在放入到缓存。