【Redis系列笔记】Redis入门

本文涉及的产品
云原生多模数据库 Lindorm,多引擎 多规格 0-4节点
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 本文介绍了Redis常用命令,以及SpringBoot集成Spring Data Redis和Spring Cache。Spring Data Redis 提供了对 Redis 的操作方法,而 Spring Cache 则提供了基于注解的缓存功能,可以方便地将方法的返回值缓存到 Redis 中,以提高性能和减少对数据源的访问次数。这样的集成可以帮助开发者更便捷地利用 Redis 来管理应用程序的数据和缓存。

1. 数据类型及常用命令

  • 字符串(string):普通字符串,Redis中最简单的数据类型
  • 哈希(hash):也叫散列,类似于Java中的HashMap结构,类似于对象
  • 列表(list):按照插入顺序排序,可以有重复元素,类似于Java中的LinkedList
  • 集合(set):无序集合,没有重复元素,类似于Java中的HashSet
  • 有序集合( zset):集合中每个元素关联一个分数(score),根据分数升序排序,没有重复元素
SET key value 
设置指定key的值
GET key    
获取指定key的值
SETEX key seconds value
设置指定key的值,并将 key 的过期时间设为 seconds 秒
SETNX key value 
只有在 key不存在时设置 key 的值
========================================================= 
HSET key field value  
将哈希表 key 中的字段 field 的值设为 value
HGET key field 
获取存储在哈希表中指定字段的值
HDEL key field  
删除存储在哈希表中的指定字段
HKEYS key  
获取哈希表中所有字段
HVALS key 
获取哈希表中所有值
========================================================= 
LPUSH key value1 [value2]
将一个或多个值插入到列表头部
LRANGE key start stop    
获取列表指定范围内的元素
RPOP key
移除并获取列表最后一个元素
LLEN key
获取列表长度
BRPOP key1 [key2 ] timeout
移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表
直到等待超时或发现可弹出元素为止
========================================================= 
SADD key member1 [member2]
向集合添加一个或多个成员
SMEMBERS key 
返回集合中的所有成员
SCARD key
获取集合的成员数
SINTER key1 [key2]
返回给定所有集合的交集
SUNION key1 [key2] 
返回所有给定集合的并集
SREM key member1 [member2] 
移除集合中一个或多个成员
========================================================= 
ZADD key score1 member1 [score2 member2] 
向有序集合添加一个或多个成员
ZRANGE key start stop [WITHSCORES] 
通过索引区间返回有序集合中指定区间内的成员
ZINCRBY key increment member  
有序集合中对指定成员的分数加上增量 increment
ZREM key member [member ...] 
移除有序集合中的一个或多个成员
========================================================= 
KEYS pattern 
查找所有符合给定模式( pattern)的 key 
EXISTS key 
检查给定 key 是否存在
TYPE key
返回 key 所储存的值的类型
DEL key  
该命令用于在 key 存在是删除 key

2. Spring Data Redis

2.1. 概述

前面我们讲解了Redis的常用命令,这些命令是我们操作Redis的基础,那么我们在java程序中应该如何操作Redis呢?这就需要使用Redis的Java客户端,就如同我们使用JDBC操作MySQL数据库一样。

Redis 的 Java 客户端很多,常用的几种:

  • Jedis
  • Lettuce
  • Spring Data Redis

Spring 对 Redis 客户端进行了整合,提供了 Spring Data Redis,在Spring Boot项目中还提供了对应的Starter,即 spring-boot-starter-data-redis。

Spring Data Redis 是 Spring 的一部分,提供了在 Spring 应用中通过简单的配置就可以访问 Redis 服务,对 Redis 底层开发包进行了高度封装。在 Spring 项目中,可以使用Spring Data Redis来简化 Redis 操作。

2.2. 操作步骤

  1. 导入Spring Data Redis 的maven坐标
<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
        <version>2.7.3</version>
      </dependency>
  1. 配置Redis数据源
spring:
    redis:
      host: 192.168.200.128
      port: 6379
      password: redis
      database: 0
  1. 编写配置类,创建RedisTemplate对象
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
@Slf4j
public class RedisConfiguration {
    //提前步骤
    //添加依赖spring-boot-starter-data-redis
    //配置数据源yml,指定数据库位置,端口,密码
    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        log.info("开始创建redis模板对象");
        RedisTemplate redisTemplate = new RedisTemplate<>();
        //设置redis的连接工厂对象
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        //设置redis key的序列化器
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        return redisTemplate;
    }
}
  1. 通过RedisTemplate对象操作Redis
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.*;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@SpringBootTest
public class SpringRedisTest {
    @Autowired
    private RedisTemplate<String,String> redisTemplate;
    /**
     * redis 通用字符串命令
     */
    @Test
    public void testCommon(){
        /*
        KEYS pattern    查找所有符合给定模式( pattern)的 key
        EXISTS key    检查给定 key 是否存在
        TYPE key    返回 key 所储存的值的类型
        DEL key     该命令用于在 key 存在是删除 key
         */
        System.out.println(redisTemplate.keys("*"));
        System.out.println(redisTemplate.hasKey("age"));
        System.out.println(redisTemplate.type("age"));
        redisTemplate.rename("Student","Teacher");
        redisTemplate.delete("myset1");
    }
    // @Test
    // public void testOperation(){
    //     //获取字符串操作对象
    //     ValueOperations valueOperations = redisTemplate.opsForValue();
    //     HashOperations hashOperations = redisTemplate.opsForHash();
    //     ListOperations listOperations = redisTemplate.opsForList();
    //     SetOperations setOperations = redisTemplate.opsForSet();
    //     ZSetOperations zSetOperations = redisTemplate.opsForZSet();
    //
    // }
    /**
     * redis String字符串命令
     */
    @Test
    public void testString() {
        /*
        SET key value     设置指定key的值
        GET key     获取指定key的值
        SETEX key seconds value 设置指定key的值,并将 key 的过期时间设为 seconds 秒
        SETNX key value   只有在 key 不存在时设置 key 的值
         */
        ValueOperations valueOperations = redisTemplate.opsForValue();
        valueOperations.set("age", "刚满18岁");
        String age = (String) valueOperations.get("age");
        System.out.println(age);
        valueOperations.set("code", "120", 3, TimeUnit.SECONDS);
        valueOperations.setIfAbsent("lock", 1); 
        valueOperations.setIfAbsent("lock", 2);
    }
    /**
     * redis Hash字符串命令
     */
    @Test
    public void testHash() {
    /*
    HSET key field value  将哈希表 key 中的字段 field 的值设为 value
    HGET key field  获取存储在哈希表中指定字段的值
    HDEL key field    删除存储在哈希表中的指定字段
    HKEYS key     获取哈希表中所有字段
    HVALS key     获取哈希表中所有值
    */
        HashOperations hashOperations = redisTemplate.opsForHash();
        hashOperations.put("Student", "name", "xiaoming");
        hashOperations.put("Student","age","18");
        System.out.println(hashOperations.get("Student", "name"));
        System.out.println(hashOperations.get("Student", "age"));
        Set keys = hashOperations.keys("Student");
        List values = hashOperations.values("Student");
        System.out.println("keys = " + keys);
        System.out.println("values = " + values);
        hashOperations.delete("Student","age");
    }
    /**
     * redis List字符串命令
     */
    @Test
    public void testList(){
        /*
        LPUSH key value1 [value2]   将一个或多个值插入到列表头部
        LRANGE key start stop     获取列表指定范围内的元素
        RPOP key      移除并获取列表最后一个元素
        LLEN key      获取列表长度
         */
        ListOperations listOperations = redisTemplate.opsForList();
        listOperations.leftPushAll("list","a","b","c");
        listOperations.leftPush("list","e");
        System.out.println(listOperations.range("list", 0, -1));
        listOperations.leftPop("list");
        listOperations.rightPop("list");
        Long size = listOperations.size("list");
        System.out.println("size = " + size);
    }
    /**
     * redis Set字符串命令
     */
    @Test
    public void testSet(){
        /*
        SADD key member1 [member2]  向集合添加一个或多个成员
        SMEMBERS key    返回集合中的所有成员
        SCARD key       获取集合的成员数
        SINTER key1 [key2]    返回给定所有集合的交集
        SUNION key1 [key2]    返回所有给定集合的并集
        SREM key member1 [member2]  删除集合中一个或多个成员
         */
        SetOperations setOperations = redisTemplate.opsForSet();
        setOperations.add("myset1","x","y","z");
        setOperations.add("myset2","a","b","y");
        Set myset1 = setOperations.members("myset1");
        System.out.println("myset1 = " + myset1);
        Long size = setOperations.size("myset1");
        System.out.println("size = " + size);
        System.out.println(setOperations.intersect("myset1", "myset2"));
        System.out.println(setOperations.union("myset1", "myset2"));
        setOperations.remove("myset1","x");
    }
    /**
     * redis ZSet字符串命令
     */
    @Test
    public void testZSet(){
    /*
    ZADD key score1 member1 [score2 member2]  向有序集合添加一个或多个成员
    ZRANGE key start stop [WITHSCORES]    通过索引区间返回有序集合中指定区间内的成员
    ZINCRBY key increment member      有序集合中对指定成员的分数加上增量 increment
    ZREM key member [member ...]      移除有序集合中的一个或多个成员
     */
        ZSetOperations zSetOperations = redisTemplate.opsForZSet();
        zSetOperations.add("zset1","a",10);
        zSetOperations.add("zset1","b",15);
        zSetOperations.add("zset1","c",11);
        zSetOperations.add("zset1","d",11);
        Set zset1 = zSetOperations.range("zset1", 0, -1);
        System.out.println("zset1 = " + zset1);
        zSetOperations.incrementScore("zset1","a",15);
        zSetOperations.remove("zset1","b");
    }
}

3. Spring Cache

3.1. 概述

在 Spring 3.1 中引入了多 Cache 的支持,在 spring-context 包中定义了org.springframework.cache.Cache 和 org.springframework.cache.CacheManager 两个接口来统一不同的缓存技术。Cache 接口包含缓存的常用操作:增加、删除、读取等。CacheManager 是 Spring 各种缓存的抽象接口。 Spring 支持的常用 CacheManager 如下:

CacheManager

描述

SimpleCacheManager

使用简单的 Collection 来存储缓存

ConcurrentMapCacheManager

使用 java.util.ConcurrentHashMap 来实现缓存

NoOpCacheManager

仅测试用,不会实际存储缓存

EhCacheCacheManger

使用EhCache作为缓存技术。EhCache 是一个纯 Java 的进程内缓存框架,特点快速、精干,是 Hibernate 中默认的 CacheProvider,也是 Java 领域应用最为广泛的缓存

JCacheCacheManager

支持JCache(JSR-107)标准的实现作为缓存技术

CaffeineCacheManager

使用 Caffeine 作为缓存技术。用于取代 Guava 缓存技术。

RedisCacheManager

使用Redis作为缓存技术

HazelcastCacheManager

使用Hazelcast作为缓存技术

CompositeCacheManager

用于组合 CacheManager,可以从多个 CacheManager 中轮询得到相应的缓存

Spring Cache 提供了 @Cacheable 、@CachePut 、@CacheEvict 、@Caching 等注解,在方法上使用。通过注解 Cache 可以实现类似事务一样、缓存逻辑透明的应用到我们的业务代码上,且只需要更少的代码。 核心思想:当我们调用一个方法时会把该方法的参数和返回结果最为一个键值对存放在缓存中,等下次利用同样的参数来调用该方法时将不会再执行,而是直接从缓存中获取结果进行返回。

注解

说明

@EnableCaching

开启缓存注解功能,通常加在启动类上

@Cacheable

在方法执行前先查询缓存中是否有数据,如果有数据,则直接返回缓存数据;

如果没有缓存数据,调用方法并将方法返回值放到缓存中

@CachePut

将方法的返回值放到缓存中

@CacheEvict

将一条或多条数据从缓存中删除

@Caching

缓存的结合体,可以组合以上注解在一个方法中使用,比如有新增,有删除

3.2. 操作步骤

  1. 依赖导入
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
  1. 配置
spring:
  redis:
    host: 127.0.0.1
    port: 6379
    password: 123456
    database: 1
  1. 对应代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;
    /**
     * 将方法返回值放入缓存
     * @param user
     * @return
     */
    @CachePut(value = "userCache",key = "#user.id")
    public User insert(User user){
        userMapper.insert(user);
        return user;
    }
    /**
     *
     * @param id
     * @return
     */
    @Cacheable(cacheNames = "userCache",key = "#id")
    public User getById(Long id){
        //1.查询redis
        // String userStr = redisTemplate.opsForValue().get("redis:" + id);
        // if (userStr!=null){
        //     //命中
        //     User user = JSONObject.parseObject(userStr, User.class);
        //     return user;
        // }
        //未命中
        User user = userMapper.getById(id);
        if(user == null){
            throw new RuntimeException("用户不存在");
        }
        //同步数据到redis中
        //redisTemplate.opsForValue().set("redis:" + id, JSON.toJSONString(user));
        return user;
    }
    /**
     * 删除某个key对应的缓存数据
     * @param id
     */
    @CacheEvict(cacheNames = "userCache",key = "#id")
    public void deleteById(Long id){
        userMapper.deleteById(id);
    }
    /**
     * 删除所有数据,清理所有缓存
     */
    @CacheEvict(cacheNames = "userCache",allEntries = true)
    public void deleteAll(){
        userMapper.deleteAll();
    }
    /**
     * hashcode的特点是,只要参数相同,则生成后的hashcode值肯定相同
     * 如果返回结果为空,则不缓存unless="#result == null"或unless="#result.size()==0"
     * unless ="#result.size()==0" result是一个关键字,
     * @param userDto
     * @return
     */
    @Cacheable(value = "userCache",key = "#userDto.hashCode()",unless = "#result.size() == 0")
    public List<User> getList(UserDto userDto){
        List<User> list = userMapper.getList("%" + userDto.getName() + "%", userDto.getAge());
        return list;
    }
}
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
1月前
|
缓存 NoSQL Java
springboot的缓存和redis缓存,入门级别教程
本文介绍了Spring Boot中的缓存机制,包括使用默认的JVM缓存和集成Redis缓存,以及如何配置和使用缓存来提高应用程序性能。
94 1
springboot的缓存和redis缓存,入门级别教程
|
1月前
|
存储 消息中间件 NoSQL
Redis 入门 - C#.NET Core客户端库六种选择
Redis 入门 - C#.NET Core客户端库六种选择
58 8
|
3月前
|
SQL 存储 NoSQL
Redis6入门到实战------ 一、NoSQL数据库简介
这篇文章是关于NoSQL数据库的简介,讨论了技术发展、NoSQL数据库的概念、适用场景、不适用场景,以及常见的非关系型数据库。文章还提到了Web1.0到Web2.0时代的技术演进,以及解决CPU、内存和IO压力的方法,并对比了行式存储和列式存储数据库的特点。
Redis6入门到实战------ 一、NoSQL数据库简介
|
3月前
|
NoSQL 算法 安全
Redis6入门到实战------ 四、Redis配置文件介绍
这篇文章详细介绍了Redis配置文件中的各种设置,包括单位定义、包含配置、网络配置、守护进程设置、日志记录、密码安全、客户端连接限制以及内存使用策略等。
Redis6入门到实战------ 四、Redis配置文件介绍
|
3月前
|
NoSQL Redis 数据安全/隐私保护
Redis6入门到实战------ 二、Redis安装
这篇文章详细介绍了Redis 6的安装过程,包括下载、解压、编译、安装、配置以及启动Redis服务器的步骤。还涵盖了如何设置Redis以在后台运行,如何为Redis设置密码保护,以及如何配置Redis服务以实现开机自启动。
Redis6入门到实战------ 二、Redis安装
|
3月前
|
NoSQL Java Redis
Redis6入门到实战------思维导图+章节目录
这篇文章提供了Redis 6从入门到实战的全面学习资料,包括思维导图和各章节目录,涵盖了NoSQL数据库、Redis安装配置、数据类型、事务、持久化、主从复制、集群等核心知识点。
Redis6入门到实战------思维导图+章节目录
|
3月前
|
NoSQL 安全 Java
Redis6入门到实战------ 三、常用五大数据类型(字符串 String)
这篇文章深入探讨了Redis中的String数据类型,包括键操作的命令、String类型的命令使用,以及String在Redis中的内部数据结构实现。
Redis6入门到实战------ 三、常用五大数据类型(字符串 String)
|
3月前
|
NoSQL 关系型数据库 Redis
Redis6入门到实战------ 九、10. Redis_事务_锁机制_秒杀
这篇文章深入探讨了Redis事务的概念、命令使用、错误处理机制以及乐观锁和悲观锁的应用,并通过WATCH/UNWATCH命令展示了事务中的锁机制。
Redis6入门到实战------ 九、10. Redis_事务_锁机制_秒杀
|
3月前
|
NoSQL Java Redis
Redis6入门到实战------ 八、Redis与Spring Boot整合
这篇文章详细介绍了如何在Spring Boot项目中整合Redis,包括在`pom.xml`中添加依赖、配置`application.properties`文件、创建配置类以及编写测试类来验证Redis的连接和基本操作。
Redis6入门到实战------ 八、Redis与Spring Boot整合
|
3月前
|
存储 NoSQL 算法
Redis6入门到实战------ 三、常用五大数据类型(列表(List)、集合(Set)、哈希(Hash)、Zset(sorted set))
这是关于Redis 6入门到实战的文章,具体内容涉及Redis的五大数据类型:列表(List)、集合(Set)、哈希(Hash)、有序集合(Zset(sorted set))。文章详细介绍了这些数据类型的特点、常用命令以及它们背后的数据结构。如果您有任何关于Redis的具体问题或需要进一步的帮助,请随时告诉我。

相关产品

  • 云数据库 Tair(兼容 Redis)