---维基百科: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);
}
}
}
经过测试就发现写的时候清空缓存,读的时候先读区缓存,缓存没有读区数据库,然后在放入到缓存。