Redis缓存的使用及配置

目录

背景简介

Redis 概述

Redis的初始操作

redis的基本操作

redis数据存储操作

简易数据存取

Key有效时间设计

Redis常用的数据类型

常用的数据类型

String类型操作实践

Hash类型应用实践(*)

List类型应用实践

Set类型应用实践

在JAVA中操作Redis

准备工作

创建工程

添加项目依赖

Jedis的应用

准备工作

快速入门实现

基础类型操作

连接池JedisPool的应用

RedisTemplate的应用

准备工作

StringRedisTemplate应用


背景简介

我们现在的项目架构中,基本上是Web服务器(Tomcat)和数据库独立部署,独占服务器资源,随着用户数的增长,并发读写数据库,会加大数据库访问压力,导致性能的下降,严重时直接导致系统宕机,例如:

Redis缓存的使用及配置_第1张图片

 此时,我们可以在Tomcat同服务器上增加本地缓存,并在外部增加分布式缓存,缓存热门数据。也就是通过缓存能把绝大多数请求在读写数据库前拦截掉,大大降低数据库压力。例如:

Redis缓存的使用及配置_第2张图片

 基于这样的一种架构设计,于是类似redis的一些分布式数据库就诞生了。

Redis 概述

Redis是一个key-value存储系统(官网:http://redis.io),是一个分布式缓存数据库。在DB-Engines.com的数据库排行中, Redis上升排行第七,如图所示:

Redis缓存的使用及配置_第3张图片

 版本及参考说明:

Redis的次版本号(第一个小数点后的数字)为偶数的版本是稳定版本(2.4、2.6等),奇数为非稳定版本(2.5、2.7),一般推荐在生产环境使用稳定版本。最新版本6.2.2,新增了stream的处理方式,性能更高。Redis官方是不支持windows平台的,windows版本是由微软自己建立的分支,基于官方的Redis源码上进行编译、发布、维护的,所以windows平台的Redis版本要略低于官方版本。


Redis 相关参考网址如下所示:

Bootnb 相关:https://www.runoob.com/redis/redis-tutorial.html
Redis 官网:https://redis.io/
源码地址:https://github.com/redis/redis
Redis 在线测试:http://try.redis.io/
Redis 命令参考:http://doc.redisfans.com/

Redis的初始操作

redis的基本操作

Docker环境下的启动(docker环境启动多个需要运行多个容器)
docker start redis01 #底层也是通过redis-server启动,start单词后的redis01为容器名

docker中查看redis服务   docker ps
查看启动的redis进程信息  ps -ef | grep redis

进入redis容器: docker exec -it redis01(容器名) bash

登录redis服务:
redis-cli
或者
redis-cli -p 6379
或者
redis-cli -p 6379 -a  password #-a后面为password,此操作需要开启redis.conf文件中的 requirepass选项

远程登录redis:redis-cli  -h ip  -p 6379  -a  password

查看redis的信息:首先登录redis,然后输入info指令:
例如:127.0.0.1:6379> info		#查看当前redis节点的详细配置信息

清除redis屏幕内容:
例如:127.0.0.1:6379> clear

退出redis服务
例如:127.0.0.1:6379> exit

关闭redis服务
例如:127.0.0.1:6379> shutdown

可以基于help指令查看相关指令帮助
例如:
127.0.0.1:6379> help
redis-cli 2.8.19
Type: "help @" to get a list of commands in 
      "help " for help on 
      "help " to get a list of possible help topics
      "quit" to exit

127.0.0.1:6379> help type

  TYPE key
  summary: Determine the type stored at key
  since: 1.0.0
  group: generic

redis数据存储操作

简易数据存取

基于查看redis中的所有key
例如:keys *

127.0.0.1:6379> keys *
(empty list or set)

基于key/value形式存储数据:set key value
例如:

127.0.0.1:6379> set test1 123
OK
127.0.0.1:6379> set test2 ab
OK
127.0.0.1:6379> keys *
1) "test1"
2) "test2"

基于key获取redis中存储的数据
例如:

127.0.0.1:6379> get test1
"123"
127.0.0.1:6379> get test2
"ab"
127.0.0.1:6379> get test3
(nil)
127.0.0.1:6379>

清除redis中的数据
清除当前数据库的数据:flushdb
清除所有数据库的数据:flushall

Key有效时间设计

实际工作中我们经常要控制redis中key的有效时长,例如秒杀操作的计时,缓存数据的有效时长等。

expire (设置生效时长-单位秒)

语法:EXPIRE key seconds


127.0.0.1:6379> set test 123
OK
127.0.0.1:6379> expire test 10
(integer) 1
127.0.0.1:6379> ttl test
(integer) 5
127.0.0.1:6379> ttl test
(integer) 3
127.0.0.1:6379> ttl test
(integer) 3
127.0.0.1:6379> ttl test
(integer) 2
127.0.0.1:6379> ttl test
(integer) 1
127.0.0.1:6379> ttl test
(integer) -2
127.0.0.1:6379> ttl test
(integer) -2
127.0.0.1:6379>

说明:TTL查看key的剩余时间,当返回值为-2时,表示键被删除。
当 key 不存在时,返回 -2 。 当 key 存在但没有设置剩余生存时间时,返回 -1 。

persist(取消时长设置)

语法:persist key

127.0.0.1:6379> set test 123
OK
127.0.0.1:6379> expire test 60
(integer) 1
127.0.0.1:6379> ttl test
(integer) 49
127.0.0.1:6379> persist test
(integer) 1
127.0.0.1:6379> ttl test
(integer) -1
127.0.0.1:6379>

其中,设置新的数据时需要重新设置该key的生存时间,重新设置值也会清除生存时间

pexpire(单位毫秒)

pexpire让key的生效时长以毫秒作为计量单位,这样可以更精确的做到时间控制

例如:可用于秒杀场景

语法:pexpire key milliseconds

127.0.0.1:6379> set test 123
OK
127.0.0.1:6379> pexpire test 10000
(integer) 1
127.0.0.1:6379> ttl test
(integer) 6
127.0.0.1:6379> ttl test
(integer) 3
127.0.0.1:6379> ttl test
(integer) -2
127.0.0.1:6379>

Redis常用的数据类型

概述:Redis作为一种key/value结构的数据存储系统,为了便于对数据进行进行管理,提供了多种数据类型。然后,基于指定类型存储我们项目中产生的数据,例如用户的登陆信息,购物车信息,商品详情信息等等。

常用的数据类型

Reids中基础数据结构包含字符串、散列,列表,集合,有序集合。工作中具体使用哪种类型要结合具体场景

String类型操作实践

字符串类型是redis中最简单的数据类型,它存储的值可以是字符串,其最大字符串长度支持到512M。基于此类型,可以实现博客的字数统计,将日志不断追加到指定key,实现一个分布式自增id,实现一个博客的的点赞操作等。

incr/incrby

存储的字符串是整数时,redis提供了一个实用的命令INCR,其作用是让当前键值递增并返回递增后的值

语法:incr key

127.0.0.1:6379> set num 1
(integer) 1
127.0.0.1:6379> incr num
(integer) 2
127.0.0.1:6379> keys *
1) "num"	
127.0.0.1:6379> incr num
127.0.0.1:6379>

说明:如果num不存在,则自动会创建,如果存在自动+1。

incrby:指定增长的系数

语法:INCRBY key increment

127.0.0.1:6379> incrby num 2
(integer) 5
127.0.0.1:6379> incrby num 2
(integer) 7
127.0.0.1:6379> incrby num 2
(integer) 9
127.0.0.1:6379>

decr/decrby

DECR key 按照默认步长(默认为1)进行递减
DECRBY key decrement 按照指定步长进行递减

append

向尾部追加值。如果键不存在则创建该键,其值为写的value,即相当于SET key value。返回值是追加后字符串的总长度。

语法:APPEND key value

127.0.0.1:6379> keys *
1) "num"
2) "test1"
3) "test"
127.0.0.1:6379> get test
"123"
127.0.0.1:6379> append test "abc"
(integer) 6
127.0.0.1:6379> get test
"123abc"
127.0.0.1:6379>

strlen

字符串长度,返回数据的长度,如果键不存在则返回0。注意,如果键值为空串,返回也是0。
语法:STRLEN key

127.0.0.1:6379> get test
"123abc"
127.0.0.1:6379> strlen test
(integer) 6
127.0.0.1:6379> strlen tnt
(integer) 0
127.0.0.1:6379> set tnt ""
OK
127.0.0.1:6379> strlen tnt
(integer) 0
127.0.0.1:6379> exists tnt
(integer) 1
127.0.0.1:6379>

说明:exists key判断是否存在该key,返回1 表示存在,0表示不存在

mset/mget

同时设置/获取多个键值
语法:MSET key value [key value …]
           MGET key [key …]

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> mset a 1 b 2 c 3
OK
127.0.0.1:6379> mget a b c
1) "1"
2) "2"
3) "3"
127.0.0.1:6379>

小结

博客的字数统计如何实现?(strlen)

如何将审计日志不断追加到指定key?(append)

你如何实现一个分布式自增id(incr-雪花算法)

如何实现一个博客的点赞操作?(incr,decr )

Hash类型应用实践(*)

Redis散列类型相当于Java中的HashMap,实现原理跟HashMap一致,一般用于存储对象信息,存储了字段(field)和字段值的映射,一个散列类型可以包含最多232-1个字段。

hset/hget

语法结构

hset key field value
hset key field
hmset key field value [field value…]
hmget key field [field]
hgetall key

 案例:

127.0.0.1:6379> hset user username chenchen
(integer) 1
127.0.0.1:6379> hget user username
"chenchen"
127.0.0.1:6379> hset user username chen
(integer) 0
127.0.0.1:6379> keys user
1) "user"
127.0.0.1:6379> hgetall user
1) "username"
2) "chen"
127.0.0.1:6379> 
127.0.0.1:6379> hset user age 18
(integer) 1
127.0.0.1:6379> hset user address "xi'an"
(integer) 1
127.0.0.1:6379> hgetall user
1) "username"
2) "chen"
3) "age"
4) "18"
3) "address"
4) "xi'an"
127.0.0.1:6379>

HSET命令不区分插入和更新操作,当执行插入操作时HSET命令返回1,当执行更新操作时返回0。

hincrby

127.0.0.1:6379> hdecrby article total 1		#执行会出错
127.0.0.1:6379> hincrby article total -1		#没有hdecrby自减命令
(integer) 1
127.0.0.1:6379> hget article total			#获取值

hmset/hmget

HMSET和HMGET设置和获取对象属性

127.0.0.1:6379> hmset person username tony age 18
OK
127.0.0.1:6379> hmget person age username
1) "18"
2) "tony"
127.0.0.1:6379> hgetall person
1) "username"
2) "tony"
3) "age"
4) "18"
127.0.0.1:6379>

说明:上面HMGET字段顺序可以自行定义

hexists

用于判断属性是否存在

属性是否存在
127.0.0.1:6379> hexists killer
(error) ERR wrong number of arguments for 'hexists' command
127.0.0.1:6379> hexists killer a
(integer) 0
127.0.0.1:6379> hexists user username
(integer) 1
127.0.0.1:6379> hexists person age
(integer) 1
127.0.0.1:6379>

hdel

删除属性

127.0.0.1:6379> hdel user age
(integer) 1
127.0.0.1:6379> hgetall user
1) "username"
2) "chen"
127.0.0.1:6379> hgetall person
1) "username"
2) "tony"
3) "age"
4) "18"
127.0.0.1:6379>

hkeys/kvals

只获取字段名hkeys 或者只获取字段值hvals

127.0.0.1:6379> hkeys person
1) "username"
2) "age"
127.0.0.1:6379> hvals person
1) "tony"
2) "18"
2.3.8	hlen
元素个数
127.0.0.1:6379> hlen user
(integer) 1
127.0.0.1:6379> hlen person
(integer) 2
127.0.0.1:6379>

小结

发布一篇博客需要写内存吗?(需要,hmset)

浏览博客内容会怎么做?(hmget)

如何判定一篇博客是否存在?(hexists)

删除一篇博客如何实现?(hdel)

List类型应用实践

Redis类型相当于java中的LinkdList,其原理就是一个双向链表,支持正向,反向查找等操作,插入删除速度比较快,经常用于实现热销榜,最新评论等的设计

lpush

在key对应的list的头部添加字符串元素

redis 127.0.0.1:6379> lpush mylist "world"
(integer) 1
redis 127.0.0.1:6379> lpush mylist "hello"
(integer) 2
redis 127.0.0.1:6379> lrange mylist 0 -1
1) "hello"
2) "world"
redis 127.0.0.1:6379>

其中,Redis Lrange返回列表中指定区间内的元素,区间以偏移量start和end指定,其中0表示列表的第一个元素,1表示列表的第二个元素,以此类推,你也可以使用负数的下标,以-1表示列表的最后一个元素,-2表示列表的倒数第二个元素,以此类推。

rpush

在key对应list的尾部添加字符串元素

redis 127.0.0.1:6379> rpush mylist2 "hello"
(integer) 1
redis 127.0.0.1:6379> rpush mylist2 "world"
(integer) 2
redis 127.0.0.1:6379> lrange mylist2 0 -1
1) "hello"
2) "world"
redis 127.0.0.1:6379>

del

redis 127.0.0.1:6379> del mylist

linsert

在key对应list的特定的位置之前或者之后添加字符串元素

redis 127.0.0.1:6379> rpush mylist3 "hello"
(integer) 1
redis 127.0.0.1:6379> rpush mylist3 "world"
(integer) 2
redis 127.0.0.1:6379> linsert mylist3 before "world" "there"
(integer) 3
redis 127.0.0.1:6379> lrange mylist3 0 -1
1) "hello"
2) "there"
3) "world"
redis 127.0.0.1:6379>

lset

设置list中指定下标的元素值(一般用于修改的操作

redis 127.0.0.1:6379> rpush mylist4 "one"
(integer) 1
redis 127.0.0.1:6379> rpush mylist4 "two"
(integer) 2
redis 127.0.0.1:6379> rpush mylist4 "three"
(integer) 3
redis 127.0.0.1:6379> lset mylist4 0 "four"
OK
redis 127.0.0.1:6379> lset mylist4 -2 "five"
OK
redis 127.0.0.1:6379> lrange mylist4 0 -1
1) "four"
2) "five"
3) "three"
redis 127.0.0.1:6379>

lrem

从key对应的list中删除count个和value相同的元素,count>0时,按从头到尾的顺序删除。

redis 127.0.0.1:6379> rpush mylist5 "hello"
(integer) 1
redis 127.0.0.1:6379> rpush mylist5 "hello"
(integer) 2
redis 127.0.0.1:6379> rpush mylist5 "foo"
(integer) 3
redis 127.0.0.1:6379> rpush mylist5 "hello"
(integer) 4
redis 127.0.0.1:6379> lrem mylist5 2 "hello"
(integer) 2
redis 127.0.0.1:6379> lrange mylist5 0 -1
1) "foo"
2) "hello"
redis 127.0.0.1:6379>
count<0时,按从尾到头的顺序删除
redis 127.0.0.1:6379> rpush mylist6 "hello"
(integer) 1
redis 127.0.0.1:6379> rpush mylist6 "hello"
(integer) 2
redis 127.0.0.1:6379> rpush mylist6 "foo"
(integer) 3
redis 127.0.0.1:6379> rpush mylist6 "hello"
(integer) 4
redis 127.0.0.1:6379> lrem mylist6 -2 "hello"
(integer) 2
redis 127.0.0.1:6379> lrange mylist6 0 -1
1) "hello"
2) "foo"
redis 127.0.0.1:6379>
count=0时,删除全部
redis 127.0.0.1:6379> rpush mylist7 "hello"
(integer) 1
redis 127.0.0.1:6379> rpush mylist7 "hello"
(integer) 2
redis 127.0.0.1:6379> rpush mylist7 "foo"
(integer) 3
redis 127.0.0.1:6379> rpush mylist7 "hello"
(integer) 4
redis 127.0.0.1:6379> lrem mylist7 0 "hello"
(integer) 3
redis 127.0.0.1:6379> lrange mylist7 0 -1
1) "foo"
redis 127.0.0.1:6379>

ltrim

保留指定key的值范围内的数据

redis 127.0.0.1:6379> rpush mylist8 "one"
(integer) 1
redis 127.0.0.1:6379> rpush mylist8 "two"
(integer) 2
redis 127.0.0.1:6379> rpush mylist8 "three"
(integer) 3
redis 127.0.0.1:6379> rpush mylist8 "four"
(integer) 4
redis 127.0.0.1:6379> ltrim mylist8 1 -1
OK
redis 127.0.0.1:6379> lrange mylist8 0 -1
1) "two"
2) "three"
3) "four"
redis 127.0.0.1:6379>

lpop

list的头部删除元素,并返回删除的元素

redis 127.0.0.1:6379> lrange mylist 0 -1
1) "hello"
2) "world"
redis 127.0.0.1:6379> lpop mylist
"hello"
redis 127.0.0.1:6379> lrange mylist 0 -1
1) "world"
redis 127.0.0.1:6379>

rpop

从list的尾部删除元素,并返回删除的元素

redis 127.0.0.1:6379> lrange mylist2 0 -1
1) "hello"
2) "world"
redis 127.0.0.1:6379> rpop mylist2
"world"
redis 127.0.0.1:6379> lrange mylist2 0 -1
1) "hello"
redis 127.0.0.1:6379>

llen

返回key对应的list的长度

redis 127.0.0.1:6379> llen mylist5
(integer) 2
redis 127.0.0.1:6379>

lindex

返回名称为key的list中的index位置的元素

redis 127.0.0.1:6379> lrange mylist5 0 -1
1) "three"
2) "foo"
redis 127.0.0.1:6379> lindex mylist5 0
"three"
redis 127.0.0.1:6379> lindex mylist5 1
"foo"
redis 127.0.0.1:6379>

rpoplpush

第一个list的尾部移除元素并添加到第二个list的头部,最后返回被移除的元素值,整个操作是原子的,如果第一个list是空或者不存在返回nIl

rpoplpush  lst1  lst1

rpoplpush lst1  lst2

小结

如何基于redis实现一个队列的结构?(lpush/rpop)

如何基于redis实现一个栈结构?(lpush/lpop)

如何基于redis实现一个阻塞时队列?(lpush/brpop)

如何实现秒杀活动的公平性?(先进先出-FIFO)

通过list结构实现一个消息队列(顺序)吗?(可以,FIFO--lpush,rpop)

用户注册时的邮件发送功能如何提高其效率?(邮件发送时要调用第三方服务,底层通过队列优化其效率,队列一般是list结构)

如何动态的更新商品的销量列表?(卖的好的排名靠前一些,linsert)

商家的粉丝列表使用什么结构实现呢?(list结构实现)

Set类型应用实践

Redis的Set类似于JAVA中的HashSet,是String类型的无序集合,集合成员是唯一的,这就意味着集合中不能出现重复的数据,Redis中的Set集合是荣国哈希表实现的,所以添加,删除,查找的复杂度都是O(1)

sadd

添加元素,重复元素添加失败,返回0

127.0.0.1:6379> sadd name tony
(integer) 1
127.0.0.1:6379> sadd name hellen
(integer) 1
127.0.0.1:6379> sadd name rose
(integer) 1
127.0.0.1:6379> sadd name rose
(integer) 0

smembers

获取内容

127.0.0.1:6379> smembers name

“hellen”
“rose”
“tony”

spop

移除并返回集合中的一个随机元素

127.0.0.1:6379> smembers internet
1) "amoeba"
2) "redis"
3) "rabbitmq"
4) "nginx"
127.0.0.1:6379> spop internet
"rabbitmq"
127.0.0.1:6379> spop internet
"nginx"
127.0.0.1:6379> smembers internet
1) "amoeba"
2) "redis"

scard

获取成员个数

127.0.0.1:6379> scard name
(integer) 3

smove

移除一个元素到另一个集合中去

127.0.0.1:6379> sadd internet amoeba nginx redis
(integer) 3
127.0.0.1:6379> sadd bigdata hadopp spark rabbitmq
(integer) 3
127.0.0.1:6379> smembers internet
1) "amoeba"
2) "redis"
3) "nginx"
127.0.0.1:6379> smembers bigdata
1) "hadopp"
2) "spark"
3) "rabbitmq"
127.0.0.1:6379> smove bigdata internet rabbitmq
(integer) 1
127.0.0.1:6379> smembers internet
1) "amoeba"
2) "redis"
3) "rabbitmq"
4) "nginx"
127.0.0.1:6379> smembers bigdata
1) "hadopp"
2) "spark"
127.0.0.1:6379>

sunion

两个集合的并集

127.0.0.1:6379> sunion internet bigdata
1) "redis"
2) "nginx"
3) "rabbitmq"
4) "amoeba"
5) "hadopp"
6) "spark"

小结

朋友圈的点赞功能你如何实现?(sadd,srem,smem,smember,scard)

如何实现一个网站投票统计程序?

你知道微博中的关注是如何实现的吗?

在JAVA中操作Redis

准备工作

创建工程

创建maven父工程,例如03-sca-redis,并在此工程下创建两个子工程,一个为sca-jedis,一个为sca-tempate,例如:

添加项目依赖

sca-jedis 工程依赖



    redis.clients
    jedis
    3.5.2



    junit
    junit
    4.12
    test



    com.google.code.gson
    gson
    2.8.6


添加sca-template工程依赖


        
            
                org.springframework.boot
                spring-boot-dependencies
                2.3.2.RELEASE
                import
                pom
            
        
    
    
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.springframework.boot
            spring-boot-starter-data-redis
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
    

Jedis的应用

Jedis是Java中操作redis的一个客户端,类似通过jdbc访问mysql数据库。

准备工作

第一步:从redis.io官方下载对应版本的redis.conf文件,地址如下:

https://redis.io/topics/config/

第二步:停止redis并删除挂载目录下(/usr/local/docker/redis01/conf)的redis.conf配置文件.
第三步:将下载的redis.conf文件拷贝到redis挂载目录(/usr/local/docker/redis01/conf)
第四步:基于vim打开redis.conf文件,然后注释 bind 127.0.0.1这一行,并修改(或者直接注释掉)protected-mode的值修改为no.
第五步:重启redis服务,并检查启动日志(docker logs 容器id)

快速入门实现

在Jedis工程中定义单元测试类,在类中定义单元测试方法:

基础类型操作

在项目的src/test/java目录创建单元测试类,例如:


@Test
public void testGetConnection(){
    //假如不能连通,要注释掉redis.conf中的两个相关的内容(上说),然后重启redis
    //重启redis命令:docker restart redis01
    Jedis jedis = new Jedis("192.168.126.130",6379);
    String ping = jedis.ping();
    System.out.println(ping);
    
}
//基于junit+redis对redis中的String类型进行测试
@Test
public void testStringOper() throws IntegetException{
    //1.建立连接
    Jedis jedis = new Jedis("192.168.126.130",6379);
    //2.向redis中存储数据
    jedis.set("id","1");
    jedis.set("name","Tony");
    jedis.set("token",UUID.randomUUID().toString);
    jedis.expire("token",2);
    //3.更新redis中的数据
    jedis.set("id","100");
    jedis.incr("id");
    jedis.incrby("id",2);
    jedis.decr("id");
    //4.删除redis中指定的数据
    jedis.del("name");
    //5.查看redis中的数据
    String id = jedis.get("id");
    String token = jedis.get("token");
    Long tokenStrLen = jedis.strlen("token");
    String name = redis.get("name");
    System.out.println("id="+id);
    System.out.println("name="+name);
    System.out.println("token="+token);
    System.out.println("token.length="+tokenStrLen);
    //Thread.sleep(2000);
    TimeUnit.SECONDS.sleep(2);
    token=jedis.get("token");
    System.out.println("token="+token);
    //6.释放资源
    jedis.close();
}

说明:TimeUnit是JAVA中的枚举类型,seconds为枚举类型的实例,sleep底层会调用Thread.sleep()方法.TimeUnit.SECONDS.sleep(1);//休眠1秒

json数据的练习
@Test
public void testJsonOper(){
    //构建对象
    Map map = new HashMap<>();
    map.put("id",100);
    map.put("title","spring 认证");
    map.put("content","very good");
    //将对象转换为json格式的字符串
    Gson gson = new Gson();
    String jsonStr = gson.toJson(map);
    //将json格式的字符串写入到redis中
    Jedis jedis=new Jedis("192.168.126.128",6379);
    jedis.set("user",jsonStr);
    //读取redis中的数据
    jsonStr=jedis.get("user");
    System.out.println(jsonStr);
    //将json串存入map集合
    Map obj=gson.fromJson(jsonStr,Map.class);
    System.out.println(obj);
    jedis.close();
}
hash类型的练习
@Test
public void testHashoPER01(){
    //1.建立连接
    Jedis jedis = new Jedis("192.168.126.130",6379);
    //2.基于hash类型存储对象信息
    jedis.hset("member","id","101");
    jedis.hset("member","username","jack");
    jedis.hset("member","mobile","11111");
    //3.更新hash类型存储的数据
    jedis.hset("member","username","tony");
    //4.获取hash类型数据的信息
    String username = jedis.hget("member","username");
    String mobile = jedis.hget("member","mobile");
    System.out.println(username);
    System.out.println(mobile);
    //5.释放资源
    jedis.close();
}
hash类型练习(直接存储map对象)
@Test
public void testHashOper02(){
    //1.建立连接
    Jedis jedis  = new Jedis("192.168.126.130",6379);
    //2.存储一篇博客信息
    Map map = new HashMap<>();
    map.put("x","100");
    map.put("y","200");
    jedis.hset("point",map);
    //3.获取博客内容并输出
    map = jedis.hgetAll("point");
    System.out.println(map);
    //4.释放资源
    jedis.close();

}
//测试:redis中list结构的应用
//基于FIFO(first in first out)算法,借助redis实现一个队列
@Test
public void testListOper01(){
    //1.建立连接
    Jedis jedis = new Jedis("192.168.126.130",6379);
    //2.存储数据
    jedis.lpush("lst1","A","B","C","C");
    //3.更新数据
    Long pos = jedis.lpos("lst1","A");//获取A元素的位置
    jedis.lset("lst1",pos,"D");//将A元素位置的内容修改为D
    //4.获取数据
    int len = jedis.llen("lst1").intValue();//获取lst1列表中的元素个数***
    List rpop = jedis.rpop("lst1",len);//获取lst1列表中的所有元素***
    System.out.println(rpop);
    //5.释放资源
    jedis.close();
    
}
List类型的练习:实现一个阻塞式队列
@Test
public void testListOper02(){
    //1.建立连接
    Jedis jedis = new Jedis("192.168.126.129",6379);
    //2.向队列存数据
    //jedis.lpush("list1","A","B","C");
    //3.按照先进先出的顺序从队列取数据
    List list = jedis.brpop(40,"list1");
    System.out.println(list);
    jedis.brpop(40,"list1");
    jedis.brpop(40,"list1");
    jedis.brpop(40,"list1");
    //4.释放资源
    jedis.close();
}
set类型的练习
@Test
public void testSetOper01(){
    //1.连接redis
    Jedis jedis = new Jedis("192.168.126.130",6379);
    //2.朋友圈点赞
    jedis.sadd("count","1","1","2");
    //3.取出点赞数
    Set set = jedis.smembers("count");
    System.out.println(set);
    //4.释放资源
    jedis.close();

}

连接池JedisPool的应用

我们直接基于Jedis访问redis时,每次获取连接,释放连接会带来很大的性能开销,可以借助Jedis的连接池,重用创建好的连接,来提高其性能,简易应用方式如下:

@Test
public void testJedisPool(){
    //1.定义连接池的配置
    JedisPoolConfig config = new JedisPoolConfig();
    config.setMaxTotal(1000);//最大连接数
    config.setMaxIdle(60);//最大空闲时间(连接不了要释放)
    //创建连接池
    JedisPool jedisPool = new JedisPool(config,"192,168.126.130",6379);
    //从池中获取一个连接
    Jedis resource  = jedisPool.getResource();
    resource.auth("123456");
    //通过redis连接存储数据
    resource.set("class","test");
    String clazz = resource.get("class");
    System.out.println(clazz);
    //将连接返回池中
    resource.close();
    //关闭连接池
    jedisPool.close();
    
}

RedisTemplate的应用

RedisTemplate为SpringBoot工程中操作redis数据库的一个JAVA对象,此对象封装了对redis的一些基本操作

准备工作

第一步:创建工程配置文件application.yml,其内容如下:

spring:
  redis:
    host: 192.168.64.129  #写自己的ip
    port: 6379

第二步:创建工程启动类

package com.jt;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class RedisApplication {
    public static void main(String[] args) {
        SpringApplication.run(RedisApplication.class,args);
    }
}

快速入门实现:

StringRedisTemplate应用

StringRedisTemplate是一个专门用于操作redis字符串类型数据的一个对象,应用方式如下:

package com.jt.redis
@SpringBootTest
public class StringRedisTemplateTests{
    //此对象为spring提供的一个用于操作redis数据库中字符串的一个对象
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Test
    public void testConnection(){
        RedisConnection connection = 
            stringRedisTemplate.getConnectionFactory().getConnection();
        String ping = connection.ping();
        System.out.println(ping);

    }
    
    @Test
    public void testRedisStringOper() throws Exception{
        //获取用于操作字符串的值对象
        ValueOperations valueOperations = 
                stringRedisTemplate.opsForValue();
        //向redis中存储数据
         valueOperations.set("ip", "192.168.174.130");
         valueOperations.set("state","1",1, TimeUnit.SECONDS);
         valueOperations.decrement("state");
         //从redis中取数据
         String ip=valueOperations.get("ip");
         System.out.println("ip="+ip);
         String state=valueOperations.get("state");
         System.out.println("state="+state); 
    }
}

未完待续...

你可能感兴趣的:(redis,redis,数据库,tomcat)