@MRsunhuimin
2019-10-16T14:10:30.000000Z
字数 13002
阅读 1112
SpringBoot
redis是一个key-value。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步
Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets)与范围查询, bitmaps, hyperloglogs和 地理空间(geospatial)索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions)和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)
- Redis将其数据库完全保存在内存中,仅使用磁盘进行持久化。
- 与其它键值数据存储相比,Redis有一组相对丰富的数据类型
- Redis可以将数据复制到任意数量的从机中。
- 异常快
Redis非常快,每秒可执行大约110000次的设置(SET)操作,每秒大约可执行81000次的读取/获取(GET)操作。- 支持丰富的数据类型
Redis支持开发人员常用的大多数数据类型,例如列表,集合,排序集和散列等等。这使得Redis很容易被用来解决各种问题,因为我们知道哪些问题可以更好使用地哪些数据类型来处理解决。- 操作具有原子性
所有Redis操作都是原子操作,这确保如果两个客户端并发访问,Redis服务器能接收更新的值。- 多实用工具
Redis是一个多实用工具,可用于多种用例,如:缓存,消息队列(Redis本地支持发布/订阅),应用程序中的任何短期数据,例如,web应用程序中的会话,网页命中计数等。
下载包
https://github.com/MicrosoftArchive/redis/releases
解压到D盘目录下
在这个目录下cmd,然后直接redis-server.exe redis.windows.conf,即可启动redis
或新建记事本文件startup.bat,输入redis-server.exe redis.windows.conf
解压目录下找到redis.windows.conf
大概在387行左右requirepass 下添加requirepass 密码,保存,重新运行即可
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-redis</artifactId><version>1.3.8.RELEASE</version></dependency>
# Redis数据库索引(默认为0)spring.redis.database=0# Redis服务器地址spring.redis.host=127.0.0.1# Redis服务器连接端口spring.redis.port=6379# Redis服务器连接密码(默认为空)spring.redis.password=123456# 连接池最大连接数(使用负值表示没有限制)spring.redis.pool.max-active=8# 连接池最大阻塞等待时间(使用负值表示没有限制)spring.redis.pool.max-wait=-1# 连接池中的最大空闲连接spring.redis.pool.max-idle=8# 连接池中的最小空闲连接spring.redis.pool.min-idle=0# 连接超时时间(毫秒)spring.redis.timeout=0
常用方法
- redisTemplate.opsForValue();//操作字符串
- redisTemplate.opsForHash();//操作hash
- redisTemplate.opsForList();//操作list
- redisTemplate.opsForSet();//操作set
- redisTemplate.opsForZSet();//操作有序set
package com.hz.controller;import com.hz.pojo.SfUser;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.serializer.RedisSerializer;import org.springframework.data.redis.serializer.StringRedisSerializer;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;import java.util.ArrayList;import java.util.List;import java.util.concurrent.TimeUnit;@RestControllerpublic class IndexTestController {@Resourceprivate RedisTemplate redisTemplate;@RequestMapping("getTestRedis")public String getTestRedis(){// 存储字符串,并设置失效时间// redisTemplate.opsForValue().set("name","张三",10,TimeUnit.SECONDS);// Object obj = redisTemplate.opsForValue().get("name");// System.out.println(obj);// 支持整型与浮点型(increment)// increment插入的内容不能通过get获得// Object age = redisTemplate.opsForValue().increment("age",15);// System.out.println(age);double age = redisTemplate.opsForValue().increment("age",+1);System.out.println(age);// set 设定该Key持有指定的字符串Value,如果该Key已经存在,则覆盖其原有值// append 如果该Key已经存在,APPEND命令将参数Value的数据追加到已存在Value的末尾。// 如果该Key不存在,APPEND命令将会创建一个新的Key/Value,它被创建并设置为空字符串,此种情况下类似于set。// redisTemplate.opsForValue().set("name","张三");// redisTemplate.opsForValue().set("name","李四");// redisTemplate.opsForValue().append("name","王五");// System.out.println(redisTemplate.opsForValue().get("name"));// 取出结果为最左边内容// 截取key所对应的value字符串// System.out.println("截取姓名为:"+redisTemplate.opsForValue().get("name",0,2));// 存入单个对象,并获取对象属性下的值// SfUser sfUser = new SfUser();// sfUser.setUser_name("小明");// sfUser.setUser_password("123456");// RedisSerializer redisSerializer = new StringRedisSerializer();// redisTemplate.opsForValue().set("sfuser",sfUser);// SfUser sfUser1 = (SfUser) redisTemplate.opsForValue().get("sfuser");// System.out.println("setUser_name=="+sfUser1.getUser_name());// System.out.println("setUser_password=="+sfUser1.getUser_password());// 存入多个对象,类似于Push栈,先进后出// redisTemplate.opsForList().leftPush("names","萧红");// redisTemplate.opsForList().leftPush("names","小皇");// redisTemplate.opsForList().leftPush("names","小兰");// redisTemplate.opsForList().leftPush("names","小路");// redisTemplate.opsForList().leftPush("names","小紫");// 移除指定对象// count> 0:删除等于从头到尾移动的值的元素。// count <0:删除等于从尾到头移动的值的元素。// count = 0:删除等于value的所有元素// redisTemplate.opsForList().remove("names",0,"萧红");// 0,-1:输出全部// List list = redisTemplate.opsForList().range("names",0,-1);// for (Object objnames :list){// System.out.println(objnames);// }// 返回key所对应的value值得长度// System.out.println("names的长度为:"+redisTemplate.opsForValue().size(""));// 存入对象数组// List<SfUser> sfUserList = new ArrayList<SfUser>();//// SfUser sfUser1 = new SfUser();// sfUser1.setUser_name("张三");//// SfUser sfUser2 = new SfUser();// sfUser2.setUser_name("张三");//// sfUserList.add(sfUser1);// sfUserList.add(sfUser2);// RedisSerializer redisSerializer = new StringRedisSerializer();// redisTemplate.setStringSerializer(redisSerializer);//// redisTemplate.opsForValue().set("sfUserList",sfUserList);// List<SfUser> sfUserList1 = (List<SfUser>) redisTemplate.opsForValue().get("sfUserList");//// System.out.println(sfUserList1.size());return "Redis存入成功!";}}
存储字符串使用:redisTemplate.opsForValue().set("name","tom");结果:redisTemplate.opsForValue().get("name") 输出结果为tom------------------------------------------------------------------设置失效时间使用:redisTemplate.opsForValue().set("name","tom",10, TimeUnit.SECONDS);TimeUnit.DAYS //天TimeUnit.HOURS //小时TimeUnit.MINUTES //分钟TimeUnit.SECONDS //秒TimeUnit.MILLISECONDS //毫秒结果:redisTemplate.opsForValue().get("name")由于设置的是10秒失效,十秒之内查询有结果,十秒之后返回为null-------------------------------------------------------------------支持整型与浮点型(increment)使用:template.opsForValue().increment("sex",1);//System.out.println(template.opsForValue().get("sex"));//increment存不能用get取,set和get配对使用结果:1--------------------------------------------------------------------如果key已经存在并且是一个字符串,则该命令将该值追加到字符串的末尾。如果键不存在,则它被创建并设置为空字符串,因此APPEND在这种特殊情况下将类似于SET使用:template.opsForValue().append("name"," hello");System.out.println(template.opsForValue().get("name"));结果:tom Hello--------------------------------------------------------------------截取key所对应的value字符串System.out.println("*********"+template.opsForValue().get("name",0,3));结果:tom--------------------------------------------------------------------返回key所对应的value值得长度System.out.println("***************"+template.opsForValue().size("key"));--------------------------------------------------------------------存储一个对象(此类必须先序列化实现接口Serializable)RedisSerializer rs = new StringRedisSerializer();redisTemplate.setStringSerializer(rs);ValueOperations ops = redisTemplate.opsForValue();ops.set("user",user);//放入redis//取出对象User setuser = (User) redisTemplate.opsForValue().get("user");
将所有指定的值插入存储在键的列表的头部。如果键不存在,则在执行推送操作之前将其创建为空列表。(从左边插入)redisTemplate.opsForList().leftPush("names","张三");redisTemplate.opsForList().leftPush("names","李四");--------------------------------------------------------------------将所有指定的值插入存储在键的列表的头部。如果键不存在,则在执行推送操作之前将其创建为空列表。(从右边插入)redisTemplate.opsForList().rightPush("names","王五");redisTemplate.opsForList().rightPush("names","马六");--------------------------------------------------------------------获取集合长度redisTemplate.opsForList().size("names");--------------------------------------------------------------------返回存储在键中的列表的指定元素使用:System.out.println(redisTemplate.opsForList().range("list",0,-1));结果:[c#, c++, python, java, c#, c#]--------------------------------------------------------------------在列表中index的位置设置value值(如果index不存在则报错)redisTemplate.opsForList().set("names",1,"岳不群");--------------------------------------------------------------------批量把一个数组插入到列表中String[] stringarrays = new String[]{"1","2","3"};redisTemplate.opsForList().leftPushAll("listarray",stringarrays);--------------------------------------------------------------------从存储在键中的列表中删除等于值的元素的第一个计数事件count> 0:删除等于从头到尾移动的值的元素。count <0:删除等于从尾到头移动的值的元素。count = 0:删除等于value的所有元素redisTemplate.opsForList().remove("names",1,"王五");--------------------------------------------------------------------根据下表获取列表中的值,下标是从0开始的redisTemplate.opsForList().index("names",2);
无序集合中添加元素,返回添加个数使用:String[] strarrays = new String[]{"strarr1","sgtarr2"};System.out.println(redisTemplate.opsForSet().add("setTest", strarrays));结果:2--------------------------------------------------------------------返回集合中的所有成员使用:System.out.println(redisTemplate.opsForSet().members("setTest"));结果:[ddd, bbb, aaa, ccc]--------------------------------------------------------------------移除集合中一个或多个成员使用:String[] strarrays = new String[]{"strarr1","sgtarr2"};System.out.println(redisTemplate.opsForSet().remove("setTest",strarrays));结果:2--------------------------------------------------------------------无序集合的大小长度使用:System.out.println(redisTemplate.opsForSet().size("setTest"));结果:1--------------------------------------------------------------------判断 ccc 元素是否是集合 key 的成员使用:System.out.println(redisTemplate.opsForSet().isMember("setTest","ccc"));结果:true--------------------------------------------------------------------随机获取key无序集合中的一个元素redisTemplate.opsForSet().randomMember("setTest");
新增一个有序集合,存在的话为false,不存在的话为true使用:System.out.println(template.opsForZSet().add("zset1","zset-1",1.0));结果:true--------------------------------------------------------------------从有序集合中移除一个或者多个元素使用:System.out.println(template.opsForZSet().range("zset1",0,-1));System.out.println(template.opsForZSet().remove("zset1","zset-6"));System.out.println(template.opsForZSet().range("zset1",0,-1));结果:[zset-1, zset-2, zset-3, zset-4, zset-5, zset-6]1[zset-1, zset-2, zset-3, zset-4, zset-5]--------------------------------------------------------------------增加元素的score值,并返回增加后的值使用://原为1.1System.out.println(template.opsForZSet().incrementScore("zset1","zset-1",1.1));结果:2.2--------------------------------------------------------------------通过分数返回有序集合指定区间内的成员,其中有序集成员按分数值递增(从小到大)顺序排列使用:System.out.println(redisTemplate.opsForZSet().add("zset1","zset-1",1.0));System.out.println(redisTemplate.opsForZSet().add("zset1","zset-2",6.0));System.out.println(redisTemplate.opsForZSet().add("zset1","zset-3",8.0));System.out.println(redisTemplate.opsForZSet().add("zset1","zset-4",4.0));System.out.println(redisTemplate.opsForZSet().add("zset1","zset-5",10.0));System.out.println(redisTemplate.opsForZSet().add("zset1","zset-6",2.0));System.out.println(redisTemplate.opsForZSet().rangeByScore("zset1",0,5));结果:[zset-1, zset-6, zset-4]--------------------------------------------------------------------通过分数返回有序集合指定区间内的成员个数使用:System.out.println(template.opsForZSet().rangeByScore("zset1",0,5));System.out.println(template.opsForZSet().count("zset1",0,5));结果:[zset-1, zset-6, zset-4]3--------------------------------------------------------------------获取有序集合的成员数(zCard与size一样)使用:System.out.println(template.opsForZSet().size("zset1"));结果:6--------------------------------------------------------------------获取指定成员的score值使用:System.out.println(template.opsForZSet().score("zset1","zset-1"));结果:1.0
- 两者的关系是StringRedisTemplate继承RedisTemplate
- 两者的数据是不共通的;也就是说StringRedisTemplate只能管理StringRedisTemplate里面的数据,RedisTemplate只能管理RedisTemplate中的数据。
- (序列化类)RedisTemplate使用的是JdkSerializationRedisSerializer 存入数据会将数据先序列化成字节数组然后在存入Redis数据库。 StringRedisTemplate使用的是StringRedisSerializer
当你的redis数据库里面本来存的是字符串数据或者你要存取的数据就是字符串类型数据的时候,那么你就使用StringRedisTemplate即可。
但是如果你的数据是复杂的对象类型,而取出的时候又不想做任何的数据转换,直接从Redis里面取出一个对象,那么使用RedisTemplate是更好的选择。
redisTemplate 中存取数据都是字节数组。当redis中存入的数据是可读形式而非字节数组时,使用redisTemplate取值的时候会无法获取导出数据,获得的值为null
//向redis里存入数据和设置缓存时间stringRedisTemplate.opsForValue().set("test", "100",60*10,TimeUnit.SECONDS);//val做-1操作stringRedisTemplate.boundValueOps("test").increment(-1);//根据key获取缓存中的valstringRedisTemplate.opsForValue().get("test")//val +1stringRedisTemplate.boundValueOps("test").increment(1);//根据key获取过期时间stringRedisTemplate.getExpire("test")//根据key获取过期时间并换算成指定单位stringRedisTemplate.getExpire("test",TimeUnit.SECONDS)//根据key删除缓存stringRedisTemplate.delete("test");//检查key是否存在,返回boolean值stringRedisTemplate.hasKey("546545");//向指定key中存放set集合stringRedisTemplate.opsForSet().add("red_123", "1","2","3");//设置过期时间stringRedisTemplate.expire("red_123",1000 , TimeUnit.MILLISECONDS);//根据key查看集合中是否存在指定数据stringRedisTemplate.opsForSet().isMember("red_123", "1")//根据key获取set集合stringRedisTemplate.opsForSet().members("red_123");**使用**@RestController@RequestMapping("/user")public class UserResource {@Autowiredpublic StringRedisTemplate stringRedisTemplate;@RequestMapping("/num")public String countNum() {String userNum = stringRedisTemplate.opsForValue().get("userNum");if(StringUtils.isNull(userNum)){stringRedisTemplate.opsForValue().set("userNum", userService.countNum().toString());}return userNum;}