对于某些需求,例如只需要做查询的项目,或者部分数据只做查询,不做增删改的项目(例如省市区表等),可以利用aop与redis,查询数据时先从redis中查询,如果查询不到,则到数据库中查询,然后将数据库中查询的数据放到redis中一份,下次查询时就能直接从redis中查到,不需要查询数据库了。
1、spring与redis整合
参考链接: SSM框架_5(spring与redis整合) - 开源小菜鸟2333
2、redis切面
Redis.java:定义Redis注解,Target为类和方法上
package com.ssm.annotation;
import java.lang.annotation.*;
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Redis {
}
3、redisAspect.java
切面:查询前先查询redis,如果查询不到穿透到数据库,从数据库查询到数据后,保存到redis,然后下次查询可直接命中缓存
@Aspect
@Component
public class RedisAspect extends BaseController{
private static final Logger logger = LoggerFactory.getLogger(RedisAspect.class);
@Autowired
private RedisUtil redisUtil;
// Controller层切点
@Pointcut("@annotation(com.ssm.annotation.Redis)") //@annotation用于匹配当前执行方法持有指定注解的方法;
public void redisAspect() {
}
@Around("redisAspect()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
//获取目标方法参数
Object[] args = joinPoint.getArgs();
String applId = null;
if (args != null && args.length > 0) {
applId = String.valueOf(args[0]);
}
// 请求类名称
String targetName = joinPoint.getTarget().getClass().getName();
// 请求方法
String methodName = joinPoint.getSignature().getName();
//redis中key格式:请求类名称 + 请求方法 + 目标方法参数
String redisKey = targetName + methodName + applId;
logger.debug("调用从redis中查询的方法,redisKey=" + redisKey);
//获取从redis中查询到的对象
Object objectFromRedis = redisUtil.getData4Object2Redis(redisKey);
//如果查询到了
if(null != objectFromRedis){
logger.debug("从redis中查询到了数据...不需要查询数据库");
return objectFromRedis;
}
logger.debug("没有从redis中查到数据...");
//没有查到,那么查询数据库
Object object = null;
object = joinPoint.proceed();
//后置:将数据库中查询的数据放到redis中
logger.debug("把数据库查询的数据存储到redis中的方法...");
redisUtil.setData4Object2Redis(redisKey, object);
//将查询到的数据返回
return object;
}
}
4、spring-mvc.xml:配置xml
此处class为该RedisAspect.java的路径
<!-- redis缓存注解 -->
<bean id="RedisAspect" class="com.ssm.annotation.RedisAspect"/>
5、controller层
在需要做redis缓存处理的方法上添加@Redis注解,如下:
@Redis
@RequestMapping(value = "/testAjax", method = RequestMethod.POST)
@ResponseBody
public Object test(Model model) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("id","数据拿到了");
return jsonObject.toJSONString();
}
项目启动:第一次运行到该方法,后台日志,如下:
2017-05-24 13:58:10 [com.ssm.annotation.RedisAspect.around(RedisAspect.java:46)] - [ DEBUG ] 调用从redis中查询的方法,redisKey=com.ssm.controller.UserControllertest{}
2017-05-24 13:58:10 [com.ssm.annotation.RedisAspect.around(RedisAspect.java:56)] - [ DEBUG ] 没有从redis中查到数据...
2017-05-24 13:58:10 [com.ssm.annotation.RedisAspect.around(RedisAspect.java:63)] - [ DEBUG ] 把数据库查询的数据存储到redis中的方法...
浏览器刷新页面,控制台输出,如下:
2017-05-24 13:58:19 [com.ssm.annotation.RedisAspect.around(RedisAspect.java:46)] - [ DEBUG ] 调用从redis中查询的方法,redisKey=com.ssm.controller.UserControllertest{}
2017-05-24 13:58:19 [com.ssm.annotation.RedisAspect.around(RedisAspect.java:52)] - [ DEBUG ] 从redis中查询到了数据...不需要查询数据库
进入redis交互页面:
127.0.0.1:7001> KEYS *
"com.ssm.controller.LoginControllerloginPostadmin"
"com.ssm.controller.UserControllertest{}"
"com.ssm.controller.LoginControllerlogin{}"
"com.ssm.controller.UserControlleruserManager{}"
"com.ssm.controller.IndexControllerindex{}"
6、相关参考链接
- SpringAOP与Redis搭建缓存 - MrLinFeng - 博客园
- Redis Keys 命令_查找所有符合给定模式( pattern)的 key 。
- linux redis-cli 根据端口号进入交互页面-CSDN问答
7、相关redis命令(Linux环境下)
根据IP和端口号进入交互页面:
./redis-cli -h 127.0.0.1 -p 7001
进入后:
> keys * //获取 redis 中所有的 key
> keys w3c* //查找以 w3c 为开头的 key
> flushdb //清除所有redis缓存