我觉得作为新时代的仙男~OVO,上班这方面,上班是不可能上班的,这辈子不可能上班的。做生意又不会
做,就是逛csdn,才能维持的了生活这样子,进csdn感觉像回家一样,在csdn里的感觉比家里感觉好多了!
里面个个都是人才,说话又好听,我超喜欢里面的。
好了,废话有点多( ^_^ )/拜拜,下面直接讲讲redis的操作~~~~啥?Σ( ° △ °|||)︴你问我怎么就开始操作了,下
载和安装呢?当然没有啦哼(ˉ(∞)ˉ)唧,百度打开搜出来一堆一堆的!那就这样吧~在爱都曲终人……(๑•̀ㅂ•́)و✧
redis提供了5个数据类型,这个要知道(≧▽≦)/~
第一个就是各位java中接触的第一个复杂数据类型(づ ̄3 ̄)づ╭❤~没错!就是String,它在redis中是用的
最多的~~
来了解一下基本操作,它们分别是set、get、del,没错,就是增删改查o(≧v≦)o。是不是感觉没有“改”这个操
作,修改一条数据的value,只需要用set就可以完成,就是找到要修改的数据的KEY,然后”set key 修改的值
“这样就可以完成“改”了( ⊙o⊙ )千真万确
咳咳,废话多了点,下面列一下用法:
set key value -----这个用来保存一条数据的,比如set name 张三,就可以向redis中添加一条key为name值为
张三的数据
get key -----这个就是查呗,没啥好说的
del key -----这个就是删呗,更没啥好说的
( ̄_, ̄ )没错,就是懒
Hash也差不多就是那么回事吧!其实就是个HashMap,可能有仙男仙女要问了:我看第一个String其实也是
一个Map啊!都是key/value的形式~
没错,为了加以区分redis特别把Hash这个数据类型做成了2个Map︿( ̄︶ ̄)︿,大概,应该,可能,没错的
话是这样的
上图可以说是很直观了啊(๑•̀ㅂ•́)و✧,啥?没懂啊,那就文字在说一遍吧╮(╯▽╰)╭,
也就是说,Redis中Hash是以key来存一个Key/Value的,也许它有点像JavaBean?可以吧第一个Key理解为类
名,第二个key就是他的成员属性,然后值就是new的时候传入的参数,或者get/set?应该吧
额!你说怎么操作?哦,忘了哼(ˉ(∞)ˉ)唧,下面是基本的操作
hset key field value -----这个呢就是向redis中存一个数据,比如 hset user name 小明
hget key field -----这个就是查呗,它还有个大哥叫hgetall key,它可以根据key来查,它大哥可以一下查所有
hdel key field -----这个就删呗,没啥好说的啊
其实List是一个LinkList,然后呢它是一个双向链表(悄悄的说:就是两边都可以插入数据,偷偷告诉你,它
可以作为栈,队列,有限集合,消息队列来使用哦),List呢他是有序的,可以重复的,可以通过下标获取
value的,这个应该没学过redis也知道的。然后就是操作了!!!
lpush/rpush values-----这两个兄弟呢一个可以从左边插入一个可以从右边插入,values这个s很关键,代表它
可以一次放多个,来个例子 lpush mylist 1 2 3 4 5 men a 这样的形式都可以的
lrange key start end -----这个就是查询了没简写应该是List Range(我这么认为的)就是列表范围嘛,一般呢
都是0开始-1结束就可以查出全部,当然你如果知道你要查的范围你当然可以不用0到-1
lpop/rpop -----它们也是左右兄弟,就是弹出(删除)嘛。
我们都知道set是无序不重复的集合(java里面),所以在redis里面也是一样的,废话不多说,直接上操作
sadd key val1 val2 -----顾名思义,就是添加一个或者多个元素
smembers key -----它可以查出key中set的所有的元素
srem key val1 val2 -----这个就移除一个或多个!
顾名思义,sorted set有序集合,它有个比较有意思的东西,”分数“(score),sortedset的排序是根据它的分
数来排的,分数越低越靠前,但是它也一样的不能有重复的元素。
zadd key score1 val1 score2 val2 ----- zadd这个命令就是添加了,他和set一样可以一次添加多个值!
zrange key start end -----和list一样是以范围来查询元素的
zrem key val1 val2 -----移除一个或多个元素!!!
场景:开发前没有想用缓存的,开发中的时候突然让加缓存,但是代码都快写完了,怎么办?
方法:redis+Spring aop解决!!!!
步骤:
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
//目标作用在方法上
@Target(ElementType.METHOD)
@Documented
public @interface RedisCache {
}
package com.electric.dlysc.annotation;
import java.lang.annotation.*;
/***
* ┌─┐ ┌─┐
* ┌──┘ ┴───────┘ ┴──┐
* │ │
* │ ─── │
* │ ─┬┘ └┬─ │
* │ │
* │ ─┴─ │
* │ │
* └───┐ ┌───┘
* │ │
* │ │
* │ │
* │ └──────────────┐
* │ │
* │ ├─┐
* │ ┌─┘
* │ │
* └─┐ ┐ ┌───────┬──┐ ┌──┘
* │ ─┤ ─┤ │ ─┤ ─┤
* └──┴──┘ └──┴──┘
* 神兽保佑
* 代码无BUG!
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface RedisCacheChage {
}
@Component
@Aspect
public class RedisAspect {
@Autowired
//导入Spring提供的redis操作模板
private StringRedisTemplate redis;
//创建一个Jackson的OMapper用来将bean转为json返回的
private ObjectMapper mapper=new ObjectMapper();
//缓存的名字哎
private String name;
//将元注解作为切点的标志
@Pointcut("@annotation(com.electric.dlysc.annotation.RedisCache)")
private void point(){}
@Pointcut("@annotation(com.electric.dlysc.annotation.RedisCacheChage)")
private void chagePoint(){}
//用环绕通知来决定是否查询数据库
@Around("point()")
public Object isCache(ProceedingJoinPoint joinPoint) throws Throwable {
//获取对象的signature,里面有目标方法的信息
Signature signature = joinPoint.getSignature();
//定义缓存的名字
name=signature.getDeclaringTypeName()+"."+signature.getName();
//用Spring的模板查出缓存
String cache = redis.opsForValue().get(name);
//做是否缓存的判断
if (cache==null){
//没缓存,继续执行目标方法
return joinPoint.proceed();
} else{
//有缓存,返回缓存Layui是自定义的返回前端的消息格式。也可以直接用string
Layui layui = mapper.readValue(cache, Layui.class);
return layui;
}
}
//用后置通知来缓存
@AfterReturning(value = "point()",returning = "result")
public void getAfterArg(JoinPoint joinPoint,Layui result) throws JsonProcessingException {
Signature signature = joinPoint.getSignature();
//将数据转换为string,存入redis
String res = mapper.writeValueAsString(result);
redis.opsForValue().set(name, res);
}
//这个用来监听,当数据库发送添加,修改,删除的时候清楚缓存的
@After("chagePoint()")
public void chageCache(JoinPoint joinPoint){
redis.delete(name);
}
}
@RedisCache
//标注了这个注解,就是判断是否有缓存
public Layui findAllList(String token, String route) throws TokenException, RouteException {
List<Permission> allNode=permissionUtils.allNode(token, route);
if (permissionUtils.isNode(PermissionCons.PERMISSION_READ,allNode)){
List<ShopList> list=Mapper.findAllList();
return Layui.dateOther(list,allNode);
}
return LayuiCons.NO_PERMISSION;
}
@RedisCacheChage
//标注了这个注解,就是调用这个方法就会清空缓存
public Layui addShopList(String token,String route,ShopList shopList) throws TokenException, RouteException {
List<Permission> allNode=permissionUtils.allNode(token, route);
if (permissionUtils.isNode(PermissionCons.PERMISSION_READ,allNode)){
if (shopList.getC_id()==null)shopList.setC_id(0);
shopListMapper.addShopList(shopList);
return LayuiCons.SUCCESS;
}
return LayuiCons.NO_PERMISSION;
}