推荐一个程序员的论坛网站: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. 将不确定变为确定~transactionscope何时提升为分布式事务~SQL2005与SQL2008不同

    回到目录 Transactionscope何时被提升为分布式事务,即时要触发msdtc服务,这个问题与数据库版本有关,在前面的文章中,我的MSTDC系列出现了多个版本,有一点没有说清楚,测试的环境不同 ...

  2. jQuery插件之ajaxFileUpload

    原文:http://www.cnblogs.com/kissdodog/archive/2012/12/15/2819025.html ajaxFileUpload是一个异步上传文件的jQuery插件 ...

  3. js中关于value的一个小知识点(value既是属性也是变量)

    今天在学习input的value值时,发现这么一个小知识点,以前理解不太透彻. [1]以下这种情况是常见情况,会弹出“测试内容” <input type="button" v ...

  4. java坦克大战源码下载

    HJZGG:https://github.com/hjzgg/hjzgg_tank_java 解压之后运行可执行jar包即可!效果图如下: v 1.游戏开始 v 2.选择地图 v 3.开始游戏 v 4 ...

  5. Kruskal算法(三)之 Java详解

    前面分别通过C和C++实现了克鲁斯卡尔,本文介绍克鲁斯卡尔的Java实现. 目录 1. 最小生成树 2. 克鲁斯卡尔算法介绍 3. 克鲁斯卡尔算法图解 4. 克鲁斯卡尔算法分析 5. 克鲁斯卡尔算法的 ...

  6. 如何用UE(UltraEdit)删除重复行?--转

    原文地址:https://www.zhengjie.com/question/bb148773 使用UE(UltraEdit)的高级排序功能就可以删除掉所有的重复行. 操作步骤 1.文件—排序(R)— ...

  7. Greenplum 数据库安装部署(生产环境)

    Greenplum 数据库安装部署(生产环境) 硬件配置: 16 台 IBM X3650, 节点配置:CPU 2 * 8core,内存 128GB,硬盘 16 * 900GB,万兆网卡. 万兆交换机. ...

  8. [New Portal]Windows Azure Virtual Machine (23) 使用Storage Space,提高Virtual Machine磁盘的IOPS

    <Windows Azure Platform 系列文章目录> 注意:如果使用Azure Virtual Machine,虚拟机所在的存储账号建议使用Local Redundant.不建议 ...

  9. JS根据身份证号码算年龄

    如果把身份证号码传到页面上,在前端页面获取年龄就需要用到JS脚本了: function GetAge(identityCard) { var len = (identityCard + "& ...

  10. 大话胖model和瘦model

    今天业务完成到一定程度,查看下代码,猛然发现目前的这个代码有点奇怪.奇怪就奇怪在我的model中有很多文件,每个文件都对应数据库中的一张表,然后每个model中有很多是几乎没有什么逻辑代码的.比如: ...