使用redis的缓存功能
2016-08-02 00:00
183 查看
摘要: 应用redis
在项目中,实现redis的缓存功能,采用了redisTemplate 和jedis两种方式。
一、redisTemplate的实现
1、配置Spring 文件
2、redis属性配置
3、创建一个接口,实现redis的添加数据,删除数据,查看数据等
4、实现redis 的接口
redisTemplate 是通过内部类实现内部类的方法实现。
测试:启动测试需要,把redis的服务开启。
二、jedis实现。这里用jedis继承mybatis的cache 缓存,来做redis的二级缓存。这里不需要再spring文件中配置。
2、开启mybatis的缓存
3、在mybatis的mapper文件中使用。
我使用了缓存的近期最少使用算法。在查询的时候,第二次会从缓存中获取
在项目中,实现redis的缓存功能,采用了redisTemplate 和jedis两种方式。
一、redisTemplate的实现
1、配置Spring 文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:redis="http://www.springframework.org/schema/redis" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/redis http://www.springframework.org/schema/redis/spring-redis.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxIdle" value="${redis.maxIdle}" /> <property name="testOnBorrow" value="${redis.testOnBorrow}" /> </bean> <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:hostName="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}" p:poolConfig-ref="poolConfig"/> <bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate" p:connectionFactory-ref="jedisConnectionFactory"/> <!----> </beans>
2、redis属性配置
# Redis settings redis.host=localhost redis.port=6379 redis.pass= redis.maxIdle=300 redis.maxActive=600 redis.maxWait=1000 redis.testOnBorrow=true
3、创建一个接口,实现redis的添加数据,删除数据,查看数据等
import java.util.Set; /** * Created by gangchaopan on 16/7/26. */ public interface RedisService { /** * 通过key删除 * * @param keys */ public abstract long del(String... keys); /** * 添加key value 并且设置存活时间(byte) * * @param key * @param value * @param liveTime */ public abstract void set(byte[] key, byte[] value, long liveTime); /** * 添加key value 并且设置存活时间 * * @param key * @param value * @param liveTime * 单位秒 */ public abstract void set(String key, String value, long liveTime); /** * 添加key value * * @param key * @param value */ public abstract void set(String key, String value); /** * 添加key value (字节)(序列化) * * @param key * @param value */ public abstract void set(byte[] key, byte[] value); /** * 获取redis value (String) * * @param key * @return */ public abstract String get(String key); /** * 通过正则匹配keys * * @param pattern * @return */ public abstract Set keys(String pattern); /** * 检查key是否已经存在 * * @param key * @return */ public abstract boolean exists(String key); /** * 清空redis 所有数据 * * @return */ public abstract String flushDB(); /** * 查看redis里有多少数据 */ public abstract long dbSize(); /** * 检查是否连接成功 * * @return */ public abstract String ping(); }
4、实现redis 的接口
import java.io.UnsupportedEncodingException; import java.util.Set; import com.yuepai.service.RedisService; 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.stereotype.Service; import javax.annotation.Resource; /** * 封装redis 缓存服务器服务接口 * * @author hk * <p> * 2012-12-16 上午3:09:18 */ @Service(value = "redisService") public class RedisServiceImpl implements RedisService { private static String redisCode = "utf-8"; private RedisTemplate<String, String> redisTemplate; @Resource public void setRedisTemplate(RedisTemplate<String, String> redisTemplate) { this.redisTemplate = redisTemplate; } private RedisServiceImpl() { } @Override public long del(final String... keys) { return redisTemplate.execute(new RedisCallback<Long>() { @Override public Long doInRedis(RedisConnection redisConnection) throws DataAccessException { long result = 0; for (String key : keys) { result = redisConnection.del(key.getBytes()); } return result; } }); } /** * @param key * @param value * @param liveTime */ @Override public void set(final byte[] key, final byte[] value, final long liveTime) { redisTemplate.execute(new RedisCallback() { public Long doInRedis(RedisConnection connection) throws DataAccessException { connection.set(key, value); if (liveTime > 0) { connection.expire(key, liveTime); } return 1L; } }); } /** * @param key * @param value * @param liveTime */ @Override public void set(String key, String value, long liveTime) { this.set(key.getBytes(), value.getBytes(), liveTime); } /** * @param key * @param value */ @Override public void set(String key, String value) { this.set(key, value, 0L); } /** * @param key * @param value */ @Override public void set(byte[] key, byte[] value) { this.set(key, value, 0L); } @Override public String get(final String key) { return redisTemplate.execute(new RedisCallback<String>() { @Override public String doInRedis(RedisConnection redisConnection) throws DataAccessException { try { return new String(redisConnection.get(key.getBytes()), redisCode); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return ""; } }); } @Override public Set keys(String pattern) { return redisTemplate.keys(pattern); } /** * @param key * @return */ @Override public boolean exists(final String key) { return redisTemplate.execute(new RedisCallback<Boolean>() { @Override public Boolean doInRedis(RedisConnection redisConnection) throws DataAccessException { return redisConnection.exists(key.getBytes()); } }); } /** * @return */ @Override public String flushDB() { return redisTemplate.execute(new RedisCallback<String>() { @Override public String doInRedis(RedisConnection redisConnection) throws DataAccessException { redisConnection.flushDb(); return "ok"; } }); } @Override public long dbSize() { return redisTemplate.execute(new RedisCallback<Long>() { @Override public Long doInRedis(RedisConnection redisConnection) throws DataAccessException { return redisConnection.dbSize(); } }); } @Override public String ping() { return redisTemplate.execute(new RedisCallback<String>() { @Override public String doInRedis(RedisConnection redisConnection) throws DataAccessException { return redisConnection.ping(); } }); } }
redisTemplate 是通过内部类实现内部类的方法实现。
测试:启动测试需要,把redis的服务开启。
import com.yuepai.service.RedisService; import org.junit.Test; import org.junit.runner.RunWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** * Created by gangchaopan on 16/7/26. */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:spring/spring-mvc.xml", "classpath:mybatis/spring-mybatis.xml","classpath:rabbitmq/spring-rabbitmq.xml","classpath:redis/spring-redis.xml"}) public class RedisTemplateTest { Logger log = LoggerFactory.getLogger(RedisTemplateTest.class); private RedisService redisService; @Autowired public void setRedisServicel(RedisService redisServicel) { this.redisService = redisServicel; } @Test public void testSet(){ String key ="test1"; String value= "hello mac"; redisService.set(key,value); log.debug("存储信息,key:{},value:{}",key,value); } @Test public void testGet(){ if(redisService.exists("key")){ String getValue = redisService.get("key"); log.debug("获取缓存信息:{}",getValue); }else{ log.debug("获取缓存信息key:{}","不存在"); } } @Test public void testDel(){ redisService.del("test1"); log.debug("已经删除缓存:key{}","test1"); } @Test public void testFlushDb(){ redisService.flushDB(); log.debug("缓存:{}","刷新缓存"); } @Test public void testPing(){ String ping = redisService.ping(); log.debug("ping,{}",ping); } }
二、jedis实现。这里用jedis继承mybatis的cache 缓存,来做redis的二级缓存。这里不需要再spring文件中配置。
package com.yuepai.redis.mybatisCache; import com.yuepai.utils.SerializeUtil; import org.apache.ibatis.cache.Cache; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; /** * Created by gangchaopan on 16/7/25. * 自定义redis缓存集成mybatis缓存 */ public class RedisCache implements Cache { private Logger log = LoggerFactory.getLogger(RedisCache.class); private Jedis redisClient = createClient(); private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); private String id; public RedisCache(final String id) { if (id == null) { throw new IllegalArgumentException("Cache instances require an ID"); } log.debug("-----------创建redis:id=" + id); this.id = id; } @Override public ReadWriteLock getReadWriteLock() { return this.readWriteLock; } @Override public String getId() { return this.id; } @Override public int getSize() { return Integer.valueOf(redisClient.dbSize().toString()); } @Override public void putObject(Object key, Object value) { log.debug("缓存数据:" + key + "=" + value); redisClient.set(SerializeUtil.serialize(key.toString()), SerializeUtil.serialize(value)); } @Override public Object getObject(Object key) { log.debug("参数{}",key); Object value = SerializeUtil.unserialize(redisClient.get(SerializeUtil.serialize(key.toString()))); log.debug("获取缓存数据:" + key + "=" + value); return value; } @Override public Object removeObject(Object key) { return redisClient.expire(SerializeUtil.serialize(key.toString()), 0); } @Override public void clear() { redisClient.flushDB(); } protected static Jedis createClient() { try { JedisPool pool = new JedisPool(new JedisPoolConfig(), "localhost"); return pool.getResource(); } catch (Exception e) { e.printStackTrace(); } throw new RuntimeException("初始化连接池错误"); } }
2、开启mybatis的缓存
<property name="configurationProperties"> <props> <prop key="cacheEnabled">true</prop> <!-- 查询时,关闭关联对象即时加载以提高性能 --> <prop key="lazyLoadingEnabled">false</prop> <!-- 设置关联对象加载的形态,此处为按需加载字段(加载字段由SQL指定),不会加载关联表的所有字段,以提高性能 --> <prop key="aggressiveLazyLoading">true</prop> <!-- 对于未知的SQL查询,允许返回不同的结果集以达到通用的效果 --> <prop key="multipleResultSetsEnabled">true</prop> <!-- 允许使用列标签代替列名 --> <prop key="useColumnLabel">true</prop> <!-- 允许使用自定义的主键值(比如由程序生成的UUID 32位编码作为键值),数据表的PK生成策略将被覆盖 --> <prop key="useGeneratedKeys">true</prop> <!-- 给予被嵌套的resultMap以字段-属性的映射支持 --> <prop key="autoMappingBehavior">FULL</prop> <!-- 对于批量更新操作缓存SQL以提高性能 --> <prop key="defaultExecutorType">BATCH</prop> <!-- 数据库超过25000秒仍未响应则超时 --> <prop key="defaultStatementTimeout">25000</prop> </props> </property>
3、在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="XXXXXXXX"> <cache type="XXXXXXX.mybatisCache" eviction="LRU"></cache> <select id="findById" parameterType="int" resultType="NNnnNNNNNN" > select * from user where id = #{id} </select> <!---通过账号密码,查找用户信息--> <select id="findByUsernameAndPassword" parameterType="map" resultType="YYYYYYYYY"> SELECT * FROM user WHERE username = #{username} and password = #{password} </select> </mapper>
我使用了缓存的近期最少使用算法。在查询的时候,第二次会从缓存中获取
相关文章推荐
- 使用Redis做预定库存缓存功能
- 使用高速缓存功能服务器增强Web站点的性能和可扩展性
- 技巧和诀窍:使用ASP.NET 2.0 输出缓存替换的功能实现“甜圈缓存(Donut Caching)”
- 关于使用ASP.NET4.0 OutputCacheProvider做缓存注意的地方(缓存放入redis)
- 使用Nginx的proxy_cache缓存功能取代Squid
- 使用Nginx的proxy_cache缓存功能取代Squid
- 技巧和诀窍:使用ASP.NET 2.0 输出缓存替换的功能实现“甜圈缓存(Donut Caching)”
- 分布式缓存系统Redis安装和使用
- 使用Nginx的proxy_cache缓存功能取代Squid
- 使用Nginx的proxy_cache缓存功能取代Squid
- android中图片加载使用LruCache缓存到内存或外部文件的功能
- 使用SQL数据缓存依赖功能的步骤
- 使用Nginx的proxy_cache缓存功能取代Squid
- 使用 ajax 解决浏览器缓存功能
- 缓存功能(简单的synchronized和使用读写锁)
- 使用ASP.NET 2.0 输出缓存替换的功能实现Donut Caching
- 使用Nginx的proxy_cache缓存功能取代Squid
- 使用Nginx的proxy_cache缓存功能取代Squid
- 在 Django 中使用 Redis 做缓存
- 不使用数据库缓存依赖项实现同样的功能[转]