推荐一个程序员的论坛网站:http://ourcoders.com/home/

以下内容使用到的技术有:Redis缓存、SpringMVC、Maven。项目中使用了redis缓存,目的是在业务场景中,提高SQL的查询效率,做出性能优化。先看pom.xml的配置文件中,Jedis是Redis的Java客户端,Jedis基本实现了Redis的所有功能。在使用的时候,我们创建一个Jedis对象,通过操作Jedis来操作Redis,实现我们的业务场景需求。项目中使用了Maven来托管,先看Jedis在pom文件中的配置如下:

         <!-- Redis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.7.0</version>
</dependency> <dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.5.0.RELEASE</version>
</dependency>

pom.xml中redis的配置文件

我们的pom.xml配置文件中共有两部分,上述配置会导入jedis-2.7.0.jar包和spring-data-redis.jar包。我们再看配置文件app-context-cache.xml,其中配置了ip地址,端口号,以及数据库的访问密码。这部分配置利用了maven编译时,会扫描相应的配置文件动态加载,如maven会根据:dev.properties、pre.properties、production.properties;开发、测试、生产生成相应的配置文件:详情如下:

 <?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:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- redis -->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="100" />
<property name="maxIdle" value="20" />
<property name="timeBetweenEvictionRunsMillis" value="30000" />
<property name="minEvictableIdleTimeMillis" value="30000" />
<property name="testOnBorrow" value="true" />
</bean>
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy">
<property name="poolConfig" ref="jedisPoolConfig" />
<property name="hostName">
<value>${redis.address}</value>
</property>
<property name="port">
<value>${redis.port}</value>
</property>
<property name="password">
<value>${redis.password}</value>
</property>
<property name="timeout" value="15000"></property>
<property name="usePool" value="true"></property>
</bean>
<bean id="jedisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory"></property>
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property>
<property name="valueSerializer">
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
</property>
</bean> <bean id="cacheService" class="xx.xx.xx.xx.CacheService" /> </beans>

app-context-cache.xml配置文件

其中<bean id="cacheService" class="xx.xx.xx.xx.CacheService" />指定了缓存类所在的package包中。再来看具体的CacheService的使用。

 /**
* 缓存操作
*/
public class CacheService { protected Logger logger = LoggerFactory.getLogger(getClass()); @Autowired
private RedisTemplate<String, Object> redisTemplate; /*
* 缓存最大过期时间-一个月
*/
public static final int EXPIRE_TIME_MAX = 30 * 24 * 3600; /*
* 缓存过期时间-半天
*/
public static final int EXPIRE_TIME_HALFDAY = 12 * 3600; /*
* 缓存过期时间-整天
*/
public static final int EXPIRE_TIME_ONEDAY = 24 * 3600; /******************************
********* 缓存操作 ***********
******************************/ /**
* 设置缓存
*
* @param key
* @param value
*/
public void putCache(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
} catch (Exception e) {
logger.error("PUT cache exception [key=" + key + ", value=" + value + "].", e);
}
} /**
* 设置缓存,并设定缓存时长(秒)
*
* @param key
* @param value
* @param expire
*/
public void putCache(String key, Object value, int expire) {
try { redisTemplate.opsForValue().set(key, value, expire, TimeUnit.SECONDS);
} catch (Exception e) {
logger.error("PUT cache exception [key=" + key + ", value=" + value + ", expire=" + expire + "].", e);
}
} /**
* 获取缓存数据
*
* @param key
* @return
*/
public Object getCache(String key) {
try { return redisTemplate.opsForValue().get(key);
} catch (Exception e) {
logger.error("GET cache exception [key=" + key + "].", e);
}
return null;
} /**
* 删除缓存
*
* @param key
*/
public void removeCache(String key) {
try { redisTemplate.delete(key); } catch (Exception e) {
logger.error("Remove cache exception [key=" + key + "].", e);
}
} /******************************
********* 队列操作 ***********
******************************/ /**
* 队列缓存设置
*
* @param key
* @param value
*/
public void putQueue(String key, Object value) {
try { redisTemplate.opsForList().leftPush(key, value); } catch (Exception e) {
logger.error("PUT Queue cache exception [key=" + key + ", value=" + value + "].", e);
}
} /**
* 获取队列缓存
*
* @param key
* @return
*/
public Object getQueue(String key) {
try { return redisTemplate.opsForList().rightPop(key); } catch (Exception e) {
logger.error("GET Queue cache exception [key=" + key + "].", e);
return null;
}
} /******************************
********* 栈操作 ***********
******************************/
public void putStack(String key, Object value) {
try {
redisTemplate.opsForList().leftPush(key, value);
} catch (Exception e) {
logger.error("PUT Stack cache exception [key=" + key + ", value=" + value + "].", e);
}
} public Object getStack(String key) {
try {
return redisTemplate.opsForList().leftPop(key); } catch (Exception e) {
logger.error("GET Stack cache exception [key=" + key + "].", e);
return null;
}
} public int length(String key) { try {
return redisTemplate.opsForList().size(key).intValue();
} catch (Exception e) {
logger.error("GET cache length exception [key=" + key + "].", e);
return 0;
}
} public void expire(String key, long timeout, TimeUnit unit) {
try {
redisTemplate.expire(key, timeout, unit);
} catch (Exception e) {
logger.error("SET expire time exception [key=" + key + "].", e);
}
} /******************************
********* hash操作 ***********
******************************/
/**
* hash put all
*
* @param key
* @param map
* @date 2015年10月12日
*/
public void hputs(String key, HashMap<? extends Object, ? extends Object> map) {
try {
redisTemplate.opsForHash().putAll(key, map);
} catch (Exception e) {
logger.error("PUT All Hash exception [key=" + key + "].", e);
}
} /**
* hash put
*
* @param key
* @param hashKey
* @param value
* @date 2015年10月12日
*/
public void hput(String key, Object hashKey, Object value) {
try {
redisTemplate.opsForHash().put(key, hashKey, value);
} catch (Exception e) {
logger.error("PUT Hash length exception [key=" + key + "].", e);
}
} /**
* hash get
*
* @param key
* @param hashKey
* @return
* @date 2015年10月12日
*/
public Object hget(String key, Object hashKey) {
try {
return redisTemplate.opsForHash().get(key, hashKey);
} catch (Exception e) {
logger.error("GET Hash exception [key=" + key + "].", e);
return null;
}
} /**
* hash remove
*
* @param key
* @param hashKey
* @date 2015年10月12日
*/
public void hrem(String key, Object hashKey) {
try {
redisTemplate.opsForHash().delete(key, hashKey);
} catch (Exception e) {
logger.error("DELETE Hash exception [key=" + key + "].", e);
}
} /**
* hash size
*
* @param key
* @return
* @date 2015年10月12日
*/
public long hsize(String key) {
try {
return redisTemplate.opsForHash().size(key);
} catch (Exception e) {
logger.error("GET Hash size exception [key=" + key + "].", e);
return 0;
}
} /**
* hash keys
*
* @param key
* @return
* @date 2015年10月12日
*/
public Set<?> hkeys(String key) {
try {
return redisTemplate.opsForHash().keys(key);
} catch (Exception e) {
logger.error("GET Hash size exception [key=" + key + "].", e);
return null;
}
} /**
* 取出Map
*/
public Map<Object,Object> hMap(String key){
try {
return redisTemplate.opsForHash().entries(key);
} catch (Exception e) {
logger.error("GET Map size exception [key=" + key + "].", e);
return null;
}
} /************************************************************
**********************zset 操作*****************************
************************************************************/
/**
*往Zset插入数据
*/
public void zsetPut(String key,Object hashKey,Double score){
try{
redisTemplate.opsForZSet().add(key, hashKey, score);
}catch(Exception e){
logger.error("PUT Zset exception [key=" + key + "].", e);
}
} /**
* 查询Zset,按照开始结束score
*/
public Set<?> zsetGet(String key,Double arg0,Double arg1){
try{
return redisTemplate.opsForZSet().rangeByScore(key, arg0, arg1);
}catch(Exception e){
logger.error("GET Zset exception [key=" + key + "].", e);
return null;
}
} /**
* 模糊查询
*/
public Set<String> fuzzyQuery(String pattern){
try{
return redisTemplate.keys(pattern);
}catch(Exception e){
logger.error("GET fuzzyQuery exception [key=" + pattern + "].", e);
return null;
}
} public RedisTemplate<String, Object> getRedisTemplate() {
return redisTemplate;
} public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
}

CacheService.java类文件

我们使用快捷键:ctrl+o迅速浏览一下CacheService.java类文件中的方法:

其中有如下的方法:用于设置缓存。

     /**
* 设置缓存
*
* @param key
* @param value
*/
public void putCache(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
} catch (Exception e) {
logger.error("PUT cache exception [key=" + key + ", value=" + value + "].", e);
}
}

设置缓存

做好了上述配置,再来看看我们项目中是如何使用他们的。

     public TradingArea findById(Integer id) {
if (id == null)
return null;
TradingArea ta = tradingAreaMapper.selectByPrimaryKey(id);
if (ta == null || ta.getIsActive() == (byte) 0) {
return null;
}
return ta;
} /**
* @Description: 缓存数据查询
*/
@Cache(expire = CacheService.EXPIRE_TIME_HALFDAY)
public TradingArea getTradingArea(Integer id){
return findById(id);
}

两个方法

根据主键ID查找对应的对象,我们写了两个方法,其中第一个方法,是针对该对象的增删改查,所以必须要用到实时数据,不能使用缓存。第二个方法,很显然,上方添加了缓存注解,通过设置缓存的有效时间,我们凡是做为关联表来查询的时候,都可以使用缓存来提示效率。那么问题的核心来了,我们上方添加了一个有效时间的注解,项目中是怎么实现来帮助我们取缓存的呢?先看缓存的定义文件

 @Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Cache {
boolean notCacheNull() default false;
int expire() default CacheService.EXPIRE_TIME_ONEDAY ;
boolean requireNew() default false;
}

当上述注解加在方法上的时候,会被一个拦截器拦截,拦截器拦截到之后,就会执行我们想要让缓存来做的:有就取出,没有就查SQL,同时拷贝一份在缓存中。下述是拦截器的配置文件,如下:

     <bean id="businessMethodInterceptor" class="com.XX.XX.interceptor.BusinessMethodInterceptor">
<property name="needRoutingDatasource" value="false" />
</bean>

我们来看一下拦截器,拦截了缓存注解之后,有哪些操作,代码如下:

        /**
* 缓存处理
*/
if (thisMethod.isAnnotationPresent(Cache.class)) {
Cache annotation = thisMethod.getAnnotation(Cache.class);
Class<?> returnType = thisMethod.getReturnType();
if (returnType != null && !"void".equals(returnType.getName())) {
Object cache = null;
try {
CacheKey key = new CacheKey(thisMethod.getDeclaringClass(), thisMethod, invocation.getArguments());
if(!annotation.requireNew()){
cache = cacheService.getCache(key.toString());
}
if (cache == null) {
cache = invocation.proceed();
try {
cacheService.putCache(key.toString(), cache, annotation.expire());
} catch (Exception e) {
logger.error("Cache Annotation process PUT CACHE exception.", e);
}
}
return cache;
} catch (Exception e) {
logger.error("Cache Annotation process exception.", e);
}
}
}
return invocation.proceed();

spring3.0结合Redis在项目中的运用的更多相关文章

  1. redis在项目中的应用

    redis在项目中的应用  ps:PHP 会自动 关redis连接 不需要手动关 对于临时的数据 可以不经过数据库直接redis上操作<pre>/*消息队列实例 消息队列详细步骤在http ...

  2. 无法安装程序包“MIcrosoft.Owin.Security 2.0.2”。您正在尝试将此程序包安装到某个将“.NETFramework,Version=v4.0”作为目标的项目中。

    在VS2010 MVC4项目中,安装NuGet程序包Microsoft.AspNet.SignalR时出现以下错误: 原因是安装的版本是Microsoft.AspNet.SignalR 2.0.2,要 ...

  3. redis在项目中的使用(单机版、集群版)

    1.下载jar包:jedis-2.6.2.jar 2.代码: JedisDao.java: package com.test.www.dao; public interface JedisDao { ...

  4. Redis 在项目中合理使用经验总结

    转自:https://my.oschina.net/u/920698/blog/3031587 背景 Redis 是一个开源的内存数据结构存储系统. 可以作为数据库.缓存和消息中间件使用. 支持多种类 ...

  5. 主攻ASP.NET.4.5.1 MVC5.0之重生:在项目中使用zTree jQuery 树插件

    效果图和json格式 Controllers代码 using HR.Models; using HR.Models.Repository; /***************************** ...

  6. Spring + SpringMVC + Mybatis项目中redis的配置及使用

    maven文件 <!-- redis --> <dependency> <groupId>redis.clients</groupId> <art ...

  7. spring3.0使用annotation完全代替XML

    @Service与@Component有什么不同?那天被问到这个问题,一时之间却想不起来,就利用这篇文章来纪录spring3.0中常用的annotation. 从spring2.5开始,annotat ...

  8. go语言实战教程:Redis实战项目应用

    项目Redis配置 在实战项目中使用Redis功能,首先需要进行Redis配置.本实战项目中,关与Redis的配置项包含:连接类型.地址.端口.公共前缀.以上配置项被定义包含在Iris框架的redis ...

  9. Redis 在NETCore中的应用

    Redis 在NETCore中的应用 Redis 在netFramework中的应用  也一样 新建.NETCORE(webapi)项目 安装NuGet //查询NuGet语句 Find-Packag ...

随机推荐

  1. Android开发学习之路-Palette颜色提取工具类使用

    视频(要FQ):https://www.youtube.com/watch?v=5u0dtzXL3PQ Palette是一个在support-v7包中的一个颜色提取工具类,用法比较简单,而且是谷歌官方 ...

  2. 每天一个linux命令(15):tail 命令

    tail 命令从指定点开始将文件写到标准输出.使用tail命令的-f选项可以方便的查阅正在改变的日志文件,tail -f filename会把filename里最尾部的内容显示在屏幕上,并且不但刷新, ...

  3. DOM_02之查找及元素操作

    1.查找之按节点间关系查找周围元素: 2.查找之HTML属性:①按id查找:var elem=document.getElementById("id"):找到一个元素,必须docu ...

  4. 快速入门系列--MVC--03控制器和IOC应用

    Asp.net MVC也接触好久了,但由于自己一直主要负责后台,尤其是数据库方面的工作对于该框架并没有一个很好的了解,尤其是蒋金楠大师的ASP.NET MVC4框架剖析一书都买了2年多了,真正认真看过 ...

  5. 深入理解CSS中的长度单位

    前面的话 本文分为绝对长度单位和相对长度单位来介绍CSS中的长度单位的主要知识 绝对长度单位 绝对长度单位代表一个物理测量 像素px(pixels) 在web上,像素px是典型的度量单位,很多其他长度 ...

  6. 【原创】C#搭建足球赛事资料库与预测平台(6) 赔率数据表设计2

            本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 开源C#彩票数据资料库系列文章总目录:[目录]C#搭建足球赛事资料库与预测平台与彩票数据分析目录 本篇文章开始将逐步介 ...

  7. iis https 客户端证书

    1.自建根证书 makecert -r -pe -n "CN=WebSSLTestRoot" -b 12/22/2013 -e 12/23/2024 -ss root -sr lo ...

  8. RMAN备份注意事项

    1.建议最好打开控制文件的自动备份. 2.如果没有打开控制文件的自动备份,一定注意备份的顺序,无论之前有无备份控制文件,备份全库以及归档之后,在最后一定要再次备份控制文件. 3.使用%U,或者%d%T ...

  9. Android之Activity的生命周期

    PS:写一发关于Activity的生命周期,也算是面试的重点内容. 学习内容: 1.Activity的生命周期 2.面对多种情况的时候Activity的生命周期 3.onSaveInstanceSta ...

  10. java反射实现动态代理

    参考:http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html http://my.oschina.net/lyp3314/b ...