推荐一个程序员的论坛网站: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. JAVA数据类型,变量,转换,常量,运算符

    java数据类型: Java基本类型共有八种,基本类型可以分为三类: 1.字符类型char,用单引号赋值 2.布尔类型boolean 3.数值类型byte.short.int.long.float.d ...

  2. 如何实现 Android 应用的持续部署?

    构建一个高质量的 Android 应用 最大的挑战是什么? 在整个开发流程中,也许 Coding 时莫名的 bug,也许是 Android 开发兼容性问题,多版本多渠道自动打包问题,也有开发工具选择等 ...

  3. Java面试(1)-- Java赋值表达式

    1 class Demo01{ 2 public static void main(String[] args){ 3 //赋值运算符 = 4 5 //例1 6 int a = 1; 7 System ...

  4. SlickUpload Upload to disk

    The file upload stream provider is a built-in SlickUpload provider that uses the filesystem for uplo ...

  5. 美团(iPad)顶部界面的简单实现, 及开发时常见bug

    项目功能介绍:1.支持横竖屏旋转,界面正常显示2.通过点击界面顶部"美团",可展示出左右双tableView分别显示服务类列表和子类列表3.通过点击界面顶部"广州&quo ...

  6. 一套后台管理html模版

    最近自己需要一套后台管理的模版,然后去网上查找,模版的确很多,但是适合我的并不多.我需要的模版是不会很大,我能够控制代码,样式不要太古朴,最好有点CSS3的效果.最后终于找到一张主页,然后再根据这个主 ...

  7. javascript学习—理解addLoadEvent函数

    onload事件是HTML DOM Event 对象的一个属性,又叫事件句柄(Event Handlers),它会在页面或图像加载完成后(注意是加载完成后)立即发生. window.onload = ...

  8. Elasticsearch——禁止Body中的index覆盖Url中的index参数

    本篇继续一下Elasticsearch日常使用的技巧翻译. 在Elasticsearch有很多的api支持在body中指定_index等信息,比如mget或者msearch以及bulk. 默认的情况下 ...

  9. 基于 CSS3 Media Queries 的 HTML5 应用

    先来介绍下 media,确切的说应该是 CSS media queries(CSS 媒体查询),媒体查询包含了一个媒体类型和至少一个使用如宽度.高度和颜色等媒体属性来限制样式表范围的表达式.CSS3 ...

  10. 基于HTML5 WebGL实现3D飞机叶轮旋转

    在上一篇<基于HT for Web矢量实现2D叶轮旋转>中讲述了叶轮旋转在2D拓扑上的应用,今天我们就来讲讲叶轮旋转在3D上的应用. 在3D拓扑上可以创建各种各样的图元,在HT for W ...