在这里就不作spring框架详细描述,只对用的做解释,有什么问题欢迎来信。
这里增长spring-data-redis
和jedis
必需要jar包。java
<dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.3.4.RELEASE</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.5.2</version> </dependency>
在spring的配置文件applicationContext.xml里加入下面的redis的配置信息。程序员
<!-- redis配置 --> <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxIdle" value="300" /> <property name="maxTotal" value="600" /> <property name="maxWaitMillis" value="1000" /> <property name="testOnBorrow" value="true" /> </bean> <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:host-name="192.168.31.4" p:port="6379" p:password="" p:pool-config-ref="poolConfig"/> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"> <property name="connectionFactory" ref="connectionFactory" /> </bean>
这里配置redis的一些信息,固然也能够用配置文件来配置redis
redis.host=192.168.31.4 redis.port=6379 redis.pass= redis.maxIdle=50 redis.maxActive=50 redis.maxWait=50 redis.testOnBorrow=true redis.timeout=1000
接下来在配置文件中配置要缓存的对象值,以下:spring
<cache:annotation-driven/> <!-- 缓存管理器 --> <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager"> <property name="caches"> <set> <bean class="com.hejia.alauda.redis.SystemRedisCache"> <property name="redisTemplate" ref="redisTemplate" /> <property name="name" value="default" /> <property name="timeout" value="600" /><!-- 10分钟后过时 --> </bean> <bean class="com.hejia.alauda.redis.SystemRedisCache"> <property name="redisTemplate" ref="redisTemplate" /> <property name="name" value="orderServiceImpl.selectInterests" /> <property name="timeout" value="600" /> </bean> <bean class="com.hejia.alauda.redis.SystemRedisCache"> <property name="redisTemplate" ref="redisTemplate" /> <property name="name" value="orderServiceImpl.selectInterestsList" /> <property name="timeout" value="600" /> </bean> </set> </property> </bean>
这里面配置的orderServiceImpl.selectInterests 和 orderServiceImpl.selectInterestsList 分别是redis缓存的名称,下面代码会说到数据库
这里增长配置文件中实现的SystemRedisCache ,这里主要对redis的业务的操做方法。数组
import com.hejia.alauda.utils.SerializableUtil; import org.springframework.cache.Cache; import org.springframework.cache.support.SimpleValueWrapper; import org.springframework.dao.DataAccessException; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.core.RedisCallback; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.util.StringUtils; /** * info:redis缓存配置类 * Created by shang on 2016/11/9. */ public class SystemRedisCache implements Cache { /** * Redis */ private RedisTemplate<String, Object> redisTemplate; /** * 缓存名称 */ private String name; /** * 超时时间 */ private long timeout; /* * (non-Javadoc) * @see org.springframework.cache.Cache#getName() */ @Override public String getName() { return this.name; } /* * (non-Javadoc) * @see org.springframework.cache.Cache#getNativeCache() */ @Override public Object getNativeCache() { // TODO Auto-generated method stub return this.redisTemplate; } /* * (non-Javadoc) * @see org.springframework.cache.Cache#get(java.lang.Object) */ @Override public ValueWrapper get(Object key) { if (StringUtils.isEmpty(key)) { return null; } else { final String finalKey; if (key instanceof String) { finalKey = (String) key; } else { finalKey = key.toString(); } Object object = null; object = redisTemplate.execute(new RedisCallback<Object>() { public Object doInRedis(RedisConnection connection) throws DataAccessException { byte[] key = finalKey.getBytes(); byte[] value = connection.get(key); if (value == null) { return null; } return SerializableUtil.unserialize(value); } }); return (object != null ? new SimpleValueWrapper(object) : null); } } /* * (non-Javadoc) * @see org.springframework.cache.Cache#get(java.lang.Object, java.lang.Class) */ @SuppressWarnings("unchecked") @Override public <T> T get(Object key, Class<T> type) { if (StringUtils.isEmpty(key) || null == type) { return null; } else { final String finalKey; final Class<T> finalType = type; if (key instanceof String) { finalKey = (String) key; } else { finalKey = key.toString(); } final Object object = redisTemplate.execute(new RedisCallback<Object>() { public Object doInRedis(RedisConnection connection) throws DataAccessException { byte[] key = finalKey.getBytes(); byte[] value = connection.get(key); if (value == null) { return null; } return SerializableUtil.unserialize(value); } }); if (finalType != null && finalType.isInstance(object) && null != object) { return (T) object; } else { return null; } } } /* * (non-Javadoc) * @see org.springframework.cache.Cache#put(java.lang.Object, java.lang.Object) */ @Override public void put(final Object key, final Object value) { if (StringUtils.isEmpty(key) || StringUtils.isEmpty(value)) { return; } else { final String finalKey; if (key instanceof String) { finalKey = (String) key; } else { finalKey = key.toString(); } if (!StringUtils.isEmpty(finalKey)) { final Object finalValue = value; redisTemplate.execute(new RedisCallback<Boolean>() { @Override public Boolean doInRedis(RedisConnection connection) { connection.set(finalKey.getBytes(), SerializableUtil.serialize(finalValue)); // 设置超时间 connection.expire(finalKey.getBytes(), timeout); return true; } }); } } } /* * 根据Key 删除缓存 */ @Override public void evict(Object key) { if (null != key) { final String finalKey; if (key instanceof String) { finalKey = (String) key; } else { finalKey = key.toString(); } if (!StringUtils.isEmpty(finalKey)) { redisTemplate.execute(new RedisCallback<Long>() { public Long doInRedis(RedisConnection connection) throws DataAccessException { return connection.del(finalKey.getBytes()); } }); } } } /* * 清楚系统缓存 */ @Override public void clear() { // TODO Auto-generated method stub // redisTemplate.execute(new RedisCallback<String>() { // public String doInRedis(RedisConnection connection) throws DataAccessException { // connection.flushDb(); // return "ok"; // } // }); } public RedisTemplate<String, Object> getRedisTemplate() { return redisTemplate; } public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) { this.redisTemplate = redisTemplate; } public void setName(String name) { this.name = name; } public long getTimeout() { return timeout; } public void setTimeout(long timeout) { this.timeout = timeout; } }
这里附带一个工具类的代码,主要对开发中object和list对象的序列化和反序列化。 由于redis不知object和泛型,全部在将对象存入redis时,须要将缓存的数据序列化。缓存
import java.io.*; import java.util.ArrayList; import java.util.List; /** * info:序列化工具类 * Created by shang on 2016/11/9. */ public class SerializableUtil { /** * 序列化 * * @param object * @return */ public static byte[] serialize(Object object) { if (object == null) { return null; } ObjectOutputStream oos = null; ByteArrayOutputStream baos = null; byte[] bytes = null; try { // 序列化 baos = new ByteArrayOutputStream(); oos = new ObjectOutputStream(baos); oos.writeObject(object); bytes = baos.toByteArray(); } catch (Exception e) { e.printStackTrace(); } finally { close(oos); close(baos); } return bytes; } /** * 反序列化 * * @param bytes * @return */ public static Object unserialize(byte[] bytes) { if (bytes == null) { return null; } ByteArrayInputStream bais = null; ObjectInputStream ois = null; try { // 反序列化 bais = new ByteArrayInputStream(bytes); ois = new ObjectInputStream(bais); return ois.readObject(); } catch (Exception e) { e.printStackTrace(); } finally { close(bais); close(ois); } return null; } /** * 序列化 list 集合 * * @param list * @return */ public static byte[] serializeList(List<?> list) { if (list==null||list.size()==0) { return null; } ObjectOutputStream oos = null; ByteArrayOutputStream baos = null; byte[] bytes = null; try { baos = new ByteArrayOutputStream(); oos = new ObjectOutputStream(baos); for (Object obj : list) { oos.writeObject(obj); } bytes = baos.toByteArray(); } catch (Exception e) { e.printStackTrace(); } finally { close(oos); close(baos); } return bytes; } /** * 反序列化 list 集合 */ public static List<?> unserializeList(byte[] bytes) { if (bytes == null) { return null; } List<Object> list = new ArrayList<Object>(); ByteArrayInputStream bais = null; ObjectInputStream ois = null; try { // 反序列化 bais = new ByteArrayInputStream(bytes); ois = new ObjectInputStream(bais); while (bais.available() > 0) { Object obj = (Object) ois.readObject(); if (obj == null) { break; } list.add(obj); } } catch (Exception e) { e.printStackTrace(); } finally { close(bais); close(ois); } return list; } /** * 关闭io流对象 * * @param closeable */ public static void close(Closeable closeable) { if (closeable != null) { try { closeable.close(); } catch (Exception e) { e.printStackTrace(); } } } }
对指定的service方法作缓存,使用方法以下:app
@Cacheable(value = "orderServiceImpl.selectInterests",key = "'selectInterests_'+#params.get('user_id')+'_'+#params.get('type')+'_'+#pager.pageNumber")//增长redis缓存 @Override public Pager<Interest> selectInterests(Map<String, Object> params, Pager<Interest> pager) { System.out.println("select selectInterests class ...."); pager.setList(interestMapper.findInterestListV3(params, pager)); pager.setTotalCount(interestMapper.findCountInterestListV3(params)); return pager; } @Cacheable(value = "orderServiceImpl.selectInterestsList",key = "'selectInterestsList_'+#params.get('user_id')+'_'+#params.get('type')+'_'+#params.get('valueDate')")//增长redis缓存 @Override public List<Map<String, Object>> selectInterestsList(Map<String, Object> params) { System.out.println("select ---selectInterestsList class"); return interestMapper.selectInterestsListV3(params); }
这上面的两个方法就是spring配置文件里配置的两个缓存,我这里主要是对查询的分页作缓存。 上面的方法只是添加缓存,并10分钟后过时。这里的key是在redis所对应的标识,若是要查询出来可使用key值来查询。框架
若是你须要对缓存进行修改和删除,这须要使用@CachePut
和 @CacheEvict
。使用方法以下less
- @CacheConfig:主要用于配置该类中会用到的一些共用的缓存配置。在这里@CacheConfig(cacheNames = "users"):配置了该数据访问对象中返回的内容将存储于名为users的缓存对象中,咱们也能够不使用该注解,直接经过@Cacheable本身配置缓存集的名字来定义。 - @Cacheable:配置了findByName函数的返回值将被加入缓存。同时在查询时,会先从缓存中获取,若不存在才再发起对数据库的访问。该注解主要有下面几个参数: - value、cacheNames:两个等同的参数(cacheNames为Spring 4新增,做为value的别名),用于指定缓存存储的集合名。因为Spring 4中新增了@CacheConfig,所以在Spring 3中本来必须有的value属性,也成为非必需项了 - key:缓存对象存储在Map集合中的key值,非必需,缺省按照函数的全部参数组合做为key值,若本身配置需使用SpEL表达式,好比:@Cacheable(key = "#p0"):使用函数第一个参数做为缓存的key值,更多关于SpEL表达式的详细内容可参考官方文档 - condition:缓存对象的条件,非必需,也需使用SpEL表达式,只有知足表达式条件的内容才会被缓存,好比:@Cacheable(key = "#p0", condition = "#p0.length() < 3"),表示只有当第一个参数的长度小于3的时候才会被缓存,若作此配置上面的AAA用户就不会被缓存,读者可自行实验尝试。 - unless:另一个缓存条件参数,非必需,需使用SpEL表达式。它不一样于condition参数的地方在于它的判断时机,该条件是在函数被调用以后才作判断的,因此它能够经过对result进行判断。 - keyGenerator:用于指定key生成器,非必需。若须要指定一个自定义的key生成器,咱们须要去实现org.springframework.cache.interceptor.KeyGenerator接口,并使用该参数来指定。须要注意的是:该参数与key是互斥的 - cacheManager:用于指定使用哪一个缓存管理器,非必需。只有当有多个时才须要使用 - cacheResolver:用于指定使用那个缓存解析器,非必需。需经过org.springframework.cache.interceptor.CacheResolver接口来实现本身的缓存解析器,并用该参数指定。 除了这里用到的两个注解以外,还有下面几个核心注解: - @CachePut:配置于函数上,可以根据参数定义条件来进行缓存,它与@Cacheable不一样的是,它每次都会真是调用函数,因此主要用于数据新增和修改操做上。它的参数与@Cacheable相似,具体功能可参考上面对@Cacheable参数的解析 - @CacheEvict:配置于函数上,一般用在删除方法上,用来从缓存中移除相应数据。除了同@Cacheable同样的参数以外,它还有下面两个参数: - allEntries:非必需,默认为false。当为true时,会移除全部数据 - beforeInvocation:非必需,默认为false,会在调用方法以后移除数据。当为true时,会在调用方法以前移除数据。
上面这些就是使用spring cache对redis作缓存的用法。若是在你的项目里须要能够试试一番,这里没有使用Ecache缓存是由于项目使用分布式部署,若是是本地缓存就不行了,因此使用redis作缓存,统一存取。
有什么问题欢迎给我来信或留言!