1. String
2. List
3. Set(集合)
4. Hash(集合)
5. Zset(有序集合)
三、Redis三大特殊数据类型
1. geospatial
2. hyperloglogs
3. Bitmaps
一、Redis基础简介
Redis全称为(REmote DIctionary Server)远程服务字典,是一个高性能,可集群,可持久化,针对多种语言都可使用的键值对数据库。
Redis包含五种基本数据类型,3种特殊的数据类型针对地图信息分析,订阅系统发布,计数器,热点数据等让开发人员更加方便快捷的操作和存储数据。是当前针对于大数据时代的3V(海量,多样,实时)最有利的技术之一。我相信对于技术渴望且优秀的你,不会不知道这个技术的存在。如果可以让我带你遨游它的世界。
二、Redis五大数据类型
前戏做足!能更好的进入状态!
查看所有的键
127.0.0.1:6379> keys *
1) "a"
由于之前残留的键,那么为了更好的测试操作
清理当前数据库,Redis默认是16个数据库(可在配置文件中查看),且我们默认操作的为0号数据库。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> keys *
(empty array)
我们不想在默认数据库中,想进10号数据库
127.0.0.1:6379> select 10
OK
并简单设置一个键值
127.0.0.1:6379[10]> set a b
OK
那么如何把全部数据库都清除呢
127.0.0.1:6379[6]> flushall
OK
127.0.0.1:6379[6]> select 10
OK
127.0.0.1:6379[10]> keys *
(empty array)
如何将数据移到从当前数据库移到2号数据库
127.0.0.1:6379> set a b
OK
127.0.0.1:6379> move a 2
(integer) 1
127.0.0.1:6379> select 2
OK
127.0.0.1:6379[2]> get a
"b"
如何判断键是否存在
127.0.0.1:6379[2]> EXISTS a
(integer) 1 存在
127.0.0.1:6379[2]> EXISTS b
(integer) 0 不存在
如何根据键去获取值
127.0.0.1:6379[2]> get a
"b"
Redis只是起到一个缓存的作用,所以键值具有一个过期时间
设置过期时间
127.0.0.1:6379[2]> EXPIRE a 10 (单位默认为秒)
(integer) 1
查看剩余过期时间
127.0.0.1:6379[2]> ttl a
(integer) 7
127.0.0.1:6379[2]> ttl a
(integer) -2 已过期
127.0.0.1:6379[2]> get a
(nil)
如何判断键值对类型 默认都是string类型
127.0.0.1:6379[2]> set a 10
OK
127.0.0.1:6379[2]> set b "aaa"
OK
127.0.0.1:6379[2]> type a
string
127.0.0.1:6379[2]> type b
string
1. String
学习方法:可以结合Java String类对照记忆,基本一样。
设置键值对
127.0.0.1:6379> set k1 v1
OK
根据键得到值
127.0.0.1:6379> get k1
"v1"
查看键的数据类型
127.0.0.1:6379> type k1
string
在存在的键对应值增加字符串,如果不存在相当于设置键值对
127.0.0.1:6379> APPEND k1 v1s
(integer) 5
127.0.0.1:6379> APPEND k1 lidadaibiao
(integer) 16
127.0.0.1:6379> get k1
"v1v1slidadaibiao"
获得键对应值,字符串长度
127.0.0.1:6379> STRLEN k1
(integer) 16
自增(字符串为数字的情况下)
127.0.0.1:6379> set step 1
OK
127.0.0.1:6379> INCR step
(integer) 2
127.0.0.1:6379> get step
"2"
指定增
127.0.0.1:6379> INCRBY step 2
(integer) 4
127.0.0.1:6379> get step
"4"
自减
127.0.0.1:6379> DECR step
(integer) 3
127.0.0.1:6379> get step
"3"
指定减
127.0.0.1:6379> DECRBY step 2
(integer) 1
127.0.0.1:6379> get step
"1"
设置带过期时间的key-value
127.0.0.1:6379> SETEX k1 10 v1
OK
127.0.0.1:6379> ttl k1
(integer) 6
127.0.0.1:6379> ttl k1
(integer) -2
先判断是否存在,在设置,存在则不设置,不存在则设置
127.0.0.1:6379> SETNX k1 v1
(integer) 1
127.0.0.1:6379> SETNX k1 v2
(integer) 0
127.0.0.1:6379> get k1
"v1"
范围取值
127.0.0.1:6379> set k2 abcdefgh
OK
127.0.0.1:6379> GETRANGE k2 0 -1 取出全部
"abcdefgh"
127.0.0.1:6379> GETRANGE k2 0 2 取出索引为0 1 2的值
"abc"
根据索引替换值
127.0.0.1:6379> SETRANGE k2 1 1 将索引为1的值替换成1
(integer) 8
127.0.0.1:6379> get k2
"a1cdefgh"
批量设置
127.0.0.1:6379> MSET a1 b1 a2 b2 a3 b3 a4 b4
OK
批量获取
127.0.0.1:6379> MGET k1 a1 a2 a3
1) "v1"
2) "b1"
3) "b2"
4) "b3"
先获取在设置,然后覆盖原先的
127.0.0.1:6379> getset k1 vv1
"v1"
127.0.0.1:6379> get k1
"vv1"
删除键值对
127.0.0.1:6379> del k1
(integer) 1
127.0.0.1:6379> get k1
(nil)
运用场景:
- incr decr结合可以作为计数器
- del setnx expire可以作为分布式锁
- json作为key,set时可以存储对象
2. List
List是列表,它的用处更多。
设置列表数据 左插入(头插法)
127.0.0.1:6379> lpush mylist 1 2 3 4
(integer) 4
取出列表数据
127.0.0.1:6379> lrange mylist 0 -1 全部取出
1) "4"
2) "3"
3) "2"
4) "1"
127.0.0.1:6379> lrange mylist 0 1 只取出0 1索引指定的数据
1) "4"
2) "3"
设置列表数据 右插入(与左插入是相反的)
127.0.0.1:6379> rpush mylist 1 2 3 4
(integer) 4
取出列表数据
127.0.0.1:6379> lrange mylist 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
lpush插入图示:
lrange取出图示:
获取列表内的值,拿出来(列表内就没有了)
从左开始拿
127.0.0.1:6379> lpop mylist
"1" 原先1234 从左拿出1 剩余234
从右开始拿
127.0.0.1:6379> rpop mylist
"4" 剩余234 从右拿出4 剩余23
127.0.0.1:6379> lrange mylist 0 -1
1) "2"
2) "3"
根据下标索引取出指定值
127.0.0.1:6379> lpush mylist 1 2 3 4 4 4 4
(integer) 7
127.0.0.1:6379> lrange mylist 0 -1
1) "4"
2) "4"
3) "4"
4) "4"
5) "3"
6) "2"
7) "1"
127.0.0.1:6379> LINDEX mylist 1
"4"
127.0.0.1:6379> LINDEX mylist 3
"4"
根据值查找并移除指定个数的该值
127.0.0.1:6379> LREM mylist 1 4 删除1个值4
(integer) 1
127.0.0.1:6379> lrange mylist 0 -1
1) "4"
2) "4"
3) "4"
4) "3"
5) "2"
6) "1"
127.0.0.1:6379> LREM mylist 2 4 删除2个值4
(integer) 2
127.0.0.1:6379> lrange mylist 0 -1
1) "4"
2) "3"
3) "2"
4) "1"
通过下标截取,截取部分留在列表其余删除
127.0.0.1:6379> LTRIM mylist 1 2
OK
127.0.0.1:6379> lrange mylist 0 -1
1) "3"
2) "2"
将列表1的最后一个值移到列表2中(列表1该值将被删除)
127.0.0.1:6379> RPOPLPUSH mylist otherlist
"2"
127.0.0.1:6379> lrange mylist 0 -1
1) "3"
127.0.0.1:6379> lrange otherlist 0 -1
1) "2"
相当于
127.0.0.1:6379> rpush mylist 2 还原mylist
(integer) 2
127.0.0.1:6379> lrange mylist 0 -1
1) "3"
2) "2"
127.0.0.1:6379> rpop mylist 右边也就是最后一个弹出
"2"
127.0.0.1:6379> lpush otherlist1 2 然后从左边插入另一表
(integer) 1
将某个值插入列表某个值的前面或者后面
127.0.0.1:6379> lpush mylist 1 2
(integer) 3
127.0.0.1:6379> lrange mylist 0 -1
1) "2"
2) "1"
3) "3"
127.0.0.1:6379> LINSERT mylist before 1 a 在1的前面插入a
(integer) 4
127.0.0.1:6379> lrange mylist 0 -1
1) "2"
2) "a"
3) "1"
4) "3"
127.0.0.1:6379> LINSERT mylist after 1 b 在1的后面插入b
(integer) 5
127.0.0.1:6379> lrange mylist 0 -1
1) "2"
2) "a"
3) "1"
4) "b"
5) "3"
判断列表是否存在
127.0.0.1:6379> EXISTS mylist
(integer) 1 存在
127.0.0.1:6379> EXISTS nolist
(integer) 0 不存在
更新列表,存在即更新,不存在报错
127.0.0.1:6379> lset mylist 1 newa
OK
127.0.0.1:6379> lrange mylist 0 -1
1) "2"
2) "newa"
3) "1"
4) "b"
5) "3"
127.0.0.1:6379> lset nolist 1 a
(error) ERR no such key 不存在key
127.0.0.1:6379> lset mylist 10 a
(error) ERR index out of range 索引越界
List:
列表也可以看做链表,双向链表,左侧插入(lpush),右侧插入(rpush),指定值前后插入(befor.after)
也可以作为消息队列(先进先出,lpush插入,rpop拿取),也可以作为栈(先进后出,lpush插入,lpop拿取),效率方面明显看出边界插入改动效率最高,中间插取改动效率最低。
3. Set(集合)
Set这个数据类型,其实和JAVA里面的也是差不多的,可以对比学习。
同理和JAVA一样Set(集合)也是不可重复且不能重复读的。(所以当我们有相应去重的需求可以采用该数据类型)
向set中添加元素
127.0.0.1:6379> SADD myset a
(integer) 1
127.0.0.1:6379> sadd myset a b c d 因为a已经存在 故只添加 b c d
(integer) 3
查看set中元素
127.0.0.1:6379> SMEMBERS myset
1) "a"
2) "b"
3) "d"
4) "c"
判断元素是否存在set中
127.0.0.1:6379> SISMEMBER myset a
(integer) 1 存在
127.0.0.1:6379> SISMEMBER myset 2
(integer) 0 不存在
查看set集合中的个数
127.0.0.1:6379> SCARD myset
(integer) 4
移除集合中指定的元素
127.0.0.1:6379> SREM myset a
(integer) 1
127.0.0.1:6379> SMEMBERS myset
1) "b"
2) "d"
3) "c"
随机抽选中set中的集合(也可以指定个数进行抽取)
127.0.0.1:6379> SRANDMEMBER myset 默认是一个
"b"
127.0.0.1:6379> SRANDMEMBER myset 2 抽选两个查看
1) "c"
2) "d"
取出指定个数的元素,取出即删除 取出是随机取出的
127.0.0.1:6379> SPOP myset 1
1) "b"
127.0.0.1:6379> SPOP myset 2
1) "c"
2) "d"
127.0.0.1:6379> SPOP myset 2
(empty array)
127.0.0.1:6379> sadd myset a b c d e f
(integer) 6
127.0.0.1:6379> SPOP myset 1
1) "e"
127.0.0.1:6379> SPOP myset 2
1) "d"
2) "a"
移动set1中指定的元素到set2中去
127.0.0.1:6379> SMEMBERS otherset
1) "b"
127.0.0.1:6379> SMEMBERS myset
1) "f"
2) "c"
取集合差集
127.0.0.1:6379> SADD myset a b c d e f
(integer) 6
127.0.0.1:6379> SADD myset2 b c d e f g
(integer) 6
127.0.0.1:6379> SDIFF myset myset2
1) "a"
取集合交集
127.0.0.1:6379> SINTER myset myset2
1) "b"
2) "d"
3) "c"
4) "e"
5) "f"
取集合并集
127.0.0.1:6379> SUNION myset myset2
1) "a"
2) "e"
3) "b"
4) "f"
5) "d"
6) "c"
7) "g"
set应用场景
由于set具有不重复,唯一性的特点。
- 粉丝,好友,关注等集合
增加粉丝/好友的时候:sadd
共同好友/粉丝的时候:sinter(交集)
删除好友/粉丝的时候: srem
克隆好友/粉丝的时候: smove
判断是否为好友/粉丝的时候: sismember
2.随机获取和展示
srandmember 从集合中随机抽取指定需要展示的元素。
比如彩票抽取随机几个人,歌曲,电视随机抽取展示等。
4. Hash(集合)
Hash(集合),对比hash表去学习就没错啦。相信大家都知道Hash的本质是Map,也就是说在Map里面也是Key-value,那不就是套中套吗。对比String去理解就好了,相当于String又套了一个key值而已啦。
命令和string很是雷同。
设置一个key-value
127.0.0.1:6379> HSET myhash k1 v1
(integer) 1
拿出一个value
127.0.0.1:6379> HGET myhash k1
"v1"
批量设置具体的key-value
127.0.0.1:6379> HMSET myhash k2 v2 k3 v3 k4 v4
OK
得到全部的key-value
127.0.0.1:6379> HGETALL myhash
1) "k1"
2) "v1"
3) "k2"
4) "v2"
5) "k3"
6) "v3"
7) "k4"
8) "v4"
删除指定key对应的value
127.0.0.1:6379> HDEL myhash k1
(integer) 1
127.0.0.1:6379> HGET myhash k1
(nil)
删除多个value
127.0.0.1:6379> HDEL myhash k2 k3
(integer) 2
127.0.0.1:6379> HGETALL myhash
1) "k4"
2) "v4"
获取hash表中的key-value数量
127.0.0.1:6379> HLEN myhash
(integer) 1
判断一个hash值是否存在
127.0.0.1:6379> HEXISTS myhash k4
(integer) 1 存在
127.0.0.1:6379> HEXISTS myhash k1
(integer) 0 不存在
创建前判断,存在不创建,不存在创建
127.0.0.1:6379> HSETNX myhash k1 v1
(integer) 1 不存在
127.0.0.1:6379> HSETNX myhash k1 v2
(integer) 0 存在
127.0.0.1:6379> HGETALL myhash
1) "k4"
2) "v4"
3) "k1"
4) "v1"
获取所有的键
127.0.0.1:6379> HKEYS myhash
1) "k4"
2) "k1"
获取所有的值
127.0.0.1:6379> HVALS myhash
1) "v4"
2) "v1"
自增
127.0.0.1:6379> HINCRBY myhash k2 1
(integer) 2
127.0.0.1:6379> HINCRBY myhash k2 2
(integer) 4
自减
127.0.0.1:6379> HINCRBY myhash k2 -1
(integer) 3
127.0.0.1:6379> HINCRBY myhash k2 -2
(integer) 1
自增自减浮点数
127.0.0.1:6379> HINCRBYFLOAT myhash k2 0.1
"1.1"
127.0.0.1:6379> HINCRBYFLOAT myhash k2 -0.1
"1"
hash应用场景:
- hash表中存key-value,可以更好的去存储对象。
hset user1 name lidadaibiao
hset user1 age 18
hset user1 hobby money
5. Zset(有序集合)
Zset(有序集合),在set基础上增加了分值score,也就是我们可以根据score去排序,因此叫做有序集合。
添加一个值
127.0.0.1:6379> ZADD myzset 1 a 1就是score
(integer) 1
添加多个值
127.0.0.1:6379> ZADD myzset 1 a 2 b 3 c 也是不可重复的哦 同set
(integer) 2
遍历所有值
127.0.0.1:6379> ZRANGE myzset 0 -1 默认是倒叙取出,分值最小的在前面
1) "a"
2) "b"
3) "c"
删除一个范围的值 -inf(负无穷) +inf(正无穷)这里是全删 根据分数
127.0.0.1:6379> ZREMRANGEBYSCORE myzset -inf +inf
(integer) 3
127.0.0.1:6379> ZADD myzset 1 a 2 b 3 c 4 e 5 f
(integer) 5
取出在分值范围内的值
127.0.0.1:6379> ZRANGEBYSCORE myzset -inf +inf
1) "a"
2) "b"
3) "c"
4) "e"
5) "f"
127.0.0.1:6379> ZRANGEBYSCORE myzset 0 2
1) "a"
2) "b"
删除指定的值
127.0.0.1:6379> ZREM myzset a
(integer) 1
127.0.0.1:6379> ZRANGE myzset 0 -1
1) "b"
2) "c"
3) "e"
4) "f"
输出在分值范围内的值个数
127.0.0.1:6379> ZCOUNT myzset 0 -1
(integer) 0
127.0.0.1:6379> ZCOUNT myzset 0 4
(integer) 3
输出zset集合中总个数
127.0.0.1:6379> ZCARD myzset
(integer) 4
其余。。。。。。。类比set是一样的啦。
zset应用场景
- 当带有权重判断时候(score)
- 王者荣耀排行榜类似需要排行的需求
- 成绩表,工资表等需要排序的表
- 创建时间可作为score,直接排序撒。等等。。。。
三、Redis三大特殊数据类型
6. geospatial
Redis的GEO很早就已经被退出,我们通过它可以推算地理位置信息,两地之间的距离,以及你附近方圆几里的人。我们通过查询官网可以知道它有以下几种命令。我们一一实验即可。
##GEOADD 可以实现对地理位置的添加,在工作中,我们一般会下载城市数据,通过java程序直接进行添加,这里
##我们简单手动录入几个作为实验数据就好,经纬度我们可以通过百度去搜索就好了。
127.0.0.1:6379> GEOADD china:city 113.88 22.55 shenzhen
(integer) 1
127.0.0.1:6379> GEOADD china:city 116.23 40.22 beijing
(integer) 1
127.0.0.1:6379> GEOADD china:city 121.48 31.40 shanghai 113.64 34.72 zhengzhou 114.02 30.58 wuhan 104.10 30.65 chengdu 118.89 31.32 nanjing 112.98 28.25 changsha
(integer) 6
##因为GEO底层原理是基于Zset!我们也可以通过Zset来操作GEO的!
127.0.0.1:6379> ZRANGE china:city 0 -1 查看我们所添加全部城市
1) "chengdu"
2) "shenzhen"
3) "changsha"
4) "wuhan"
5) "nanjing"
6) "shanghai"
7) "zhengzhou"
8) "beijing"
##GEODIST通过该命令,我们可以直接得到两点之间直线距离,单位自选:m,km,mi,ft
127.0.0.1:6379> GEODIST china:city chengdu beijing km 百度一下两地差不多这点距离哈。
"1527.3545"
##GEOHASH这里将2维空间的经纬度直接转换为一个11个字符的GEOHASH字符串!(基本不使用,可以忽略)
127.0.0.1:6379> GEOHASH china:city shenzhen
1) "ws0br3hgk20"
##GEOPOS可以通过该命令获得指定地点的经纬度(前提指定地点是你录入过的哦)
127.0.0.1:6379> GEOPOS china:city shenzhen
1) 1) "113.87999922037124634"
2) "22.5500010475923105"
127.0.0.1:6379> GEOPOS china:city wuhan zhengzhou
1) 1) "114.01999980211257935"
2) "30.58000021509926825"
2) 1) "113.64000052213668823"
2) "34.72000084018613109"
##GEORADIUS返回一个排序集是以指定位置,筛选出距离中心点的最大距离(半径)范围内的所有成员。
127.0.0.1:6379> GEORADIUS china:city 110 30 1000 km
1) "chengdu"
2) "shenzhen"
3) "changsha"
4) "wuhan"
5) "nanjing"
6) "zhengzhou"
##GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC]对个别参数的解释和实验
127.0.0.1:6379> GEORADIUS china:city 100 30 1000 km WITHCOORD 返回在该范围内的名称和经纬度
1) 1) "chengdu"
2) 1) "104.09999996423721313"
2) "30.6499990746355806"
127.0.0.1:6379> GEORADIUS china:city 100 30 1000 km WITHDIST 返回在该范围内的名称和直线距离
1) 1) "chengdu"
2) "400.1909"
127.0.0.1:6379> GEORADIUS china:city 100 30 1000 km WITHHASH 返回在该范围内的名称和唯一HASH值
1) 1) "chengdu"
2) (integer) 4026137819636205
127.0.0.1:6379> GEORADIUS china:city 100 30 2500 km DESC 返回该范围内的名称按倒叙排序(远-》近)
1) "shanghai"
2) "beijing"
3) "nanjing"
4) "shenzhen"
5) "zhengzhou"
6) "wuhan"
7) "changsha"
8) "chengdu"
127.0.0.1:6379> GEORADIUS china:city 100 30 2500 km COUNT 2 返回指定前2个
1) "chengdu"
2) "changsha"
##GEORADIUSBYMEMBER和GEORADIUS基本一样,区别在于它不在使用经纬度,而是地理空间索引内已经存在
##的成员名称作为中心点。
127.0.0.1:6379> GEORADIUSBYMEMBER china:city chengdu 1000 km 其余参数同上
1) "chengdu"
2) "changsha"
3) "wuhan"
GEOSEARCH,GEOSEARCHSTORE是GEORADIUS扩展,支持了矩形范围的搜索。
GEO的应用场景
- QQ,微信附近的人 GEORADIUS GEORADIUSBYMEMBER
- 地图定位等等。
7. hyperloglogs
通过官方文档可以知道,该数据结构是一个基数统计的算法。大家可以百度查查基数的概念。我这里的理解就是不重复元素的数量。(有其他的理解也可以下面评论告诉我,我的理解只是片面的)
打个比喻:中国人口14亿,那么14亿就是一个人口基数当然是可以接受误差的,因为没有那两个人是重复(复制出来的)
再例如:{1.2.3.4.5.6.1} 那么它的基数就是6,因为1有两个但是重复了,所以算为1个。
hyperloglogs是从2.8.9版本更新的一种数据结构。
优点占用的内存是固定的,2^64不同的元素的技术,只需要占用12kb的内存,所以从内存上考虑的话hyperloglogs是首选的。
添加元素
127.0.0.1:6379> PFADD islogs a b a b c 这里其实只进去了 3个(可以对比set是不重复的)
(integer) 1
打印元素的数量
127.0.0.1:6379> PFCOUNT islogs
(integer) 3
两组合二为一
127.0.0.1:6379> PFADD isnewlogs a c d f f g h
(integer) 1
127.0.0.1:6379> PFMERGE ismergelogs islogs isnewlogs
OK
127.0.0.1:6379> PFCOUNT ismergelogs
(integer) 7
hyperloglogs应用场景
- 网页UV是最明显的应用场景,一个人访问该网页多次,其实只算作一个人。这样方便统计访问网站的人员真实数量,而不是访问量。
- 对比set,它占内存极少,但是有一定的出错率(0.81%)如果允许容错,我们选该数据结构极佳。不允许我们也可以用传统方式,set。
8. Bitmaps
Bitmaps:也就是位图存储(位存储)是一种数据结构,都是使用二进制位进行记录的(0 1),也就是只有0和1两种状态!
这里我们可以通过模仿打卡去理解和应用位存储,并体会他的好处。
模拟打卡(周一---周日 0未打卡,1打卡)
127.0.0.1:6379> SETBIT clockin 1 1
(integer) 0
127.0.0.1:6379> SETBIT clockin 2 1
(integer) 0
127.0.0.1:6379> SETBIT clockin 3 0
(integer) 0
127.0.0.1:6379> SETBIT clockin 4 0
(integer) 0
127.0.0.1:6379> SETBIT clockin 5 1
(integer) 0
127.0.0.1:6379> SETBIT clockin 6 0
(integer) 0
127.0.0.1:6379> SETBIT clockin 7 1
(integer) 0
查看周五是否打卡
127.0.0.1:6379> GETBIT clockin 5
(integer) 1
统计该周正常打卡次数
127.0.0.1:6379> BITCOUNT clockin
(integer) 4 正常打卡四天
bitmaps应用场景
- 上班打卡 两个状态 打卡 未打卡
- 登录状态 两个状态 登录 未登录
那么很明确,只要一种现象如果只有两种状态,那么选Bitmaps是最好的存储方式了。你觉得呢。
四、Redis整合SpringBoot及数据类型的操作
操作之间我们需要新建一个简单Springboot项目,并导入相关依赖。我们通过Redis官方文档可以查看对应的客户端操作类Java客户端Api
先用Jedis来进行简单操作。测试下连接远程服务器
我这里是连接的阿里云服务器,所以需要关闭防火墙,在redis.conf配置文件中将保护模式改为no,以及在阿里云配置安全组开发端口。这里我没有设置redis登录密码,有密码的需要输入密码。
用虚拟机的只需要关闭防火墙就可以了。
如果用windos安装redis则这些都不需要
测试连接
@Test
void contextLoads() {
//连接数据库
Jedis jedis = new Jedis("127.0.0.0.1",6379);
//测试一下
System.out.println(jedis.ping());
}
这就是连接成功。本来是想着用Jedis进行操作,但是当我进入它的底层,我发现源码里面没有Jedis.
郁闷了,是不用了吗?
最后从官方文档发现了它
原来是被替换成了更牛逼的lettuce.
lettuce采用netty,实现了在多个线程中可以进行共享,解决了线程不安全的问题。而Jedis采用的是直连的方式,多线程情况下是不安全的、
我们已经导入了SpringBoot整合包了。spring-boot-starter-data-redis
我们在application.properties进行简单的配置
#配置Redis
spring.redis.host=47.113.81.164
spring.redis.port=6379
测试连接
在Springboot测试类进行测试
@SpringBootTest
class SpringbootredisApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
@Test
void contextLoads() {
//获取连接
RedisConnection redisConnection = redisTemplate.getConnectionFactory().getConnection();
System.out.println(redisConnection.ping());
}
}
连接成功!
我们连接成功以后,可以通过redisTemplate进行API的操作。这里我就不详细写了,因为和命令是差不多的。
RedisConnection redisConnection = redisTemplate.getConnectionFactory().getConnection();
redisConnection.flushAll();
redisTemplate.opsForValue().set("k1","v1");
System.out.println("添加数据--输出数据:"+redisTemplate.opsForValue().get("k1"));
System.out.println("查看键的数据类型:"+redisTemplate.type("k1"));
//opsForValue() string
//opsForList() list
//opsForHash() hash
//opsForGeo() gep
//opsForSet() set
//opsForHyperLogLog() HyperLogLog