【Redis基础篇】详细讲解Redis

这篇文章让你详细了解Redis的相关知识,有代码讲解以及图片剖析,让你更轻松掌握

制作不易,感觉不错,请点赞收藏哟 !!!


目录

1  redis基础

1.1  定义

1.2  SQL和NOSQL不同点

1.3  特征

1.4  Redis通用命令

1.5  Redis数据结构介绍

1.6  Redis的java客户端

2  Jedis快速入门

2.1  操作步骤

2.2  Jedis连接池

3  SpringDataRedis

3.1  定义

3.2  优势

3.3  API

3.4  操作步骤

3.5  乱码解决方案

3.5.1  GenericJackson2JsonRedisSerializer优势

3.5.2  GenericJackson2JsonRedisSerializer缺陷

3.5.3  改进方案

3.5.4  RedisTemplate的两种序列化实践方案:


史诗级mysqlicon-default.png?t=N7T8https://blog.csdn.net/2301_77358195/article/details/137121480

1  redis基础

1.1  定义

Redis诞生于2009年全称是Remote Dictionary Server,远程词典服务器,是一个基于内存的键值型NoSQL数据库。


1.2  SQL和NOSQL不同点

①.数据结构:SQL是结构化的,NOSQL是非结构化的
②.数据关联:SQL是关联的,NOSQL是无关联的
③.查询方式:SQL是SQL查询,NOSQL是非SQL查询
④.事务特性:SQL是ACID,NOSQL是BASE
⑤.存储方式:SQL数据保存在磁盘,NOSQL数据保存在内存


1.3  特征

①.键值(key-value)型,value支持多种不同数据结构,功能丰富
②.单线程,每个命令具备原子性
③.低延迟,速度快(基于内存、IO多路复用、良好的编码)。
④.支持数据持久化(会定期将内存数据保存到磁盘中)
⑤.支持主从集群、分片集群
⑥.支持多语言客户端

原子性(Atomicity)是指事务中的所有操作要么全部成功执行,要么全部失败回滚,不存在部分执行的情况。这确保了数据库在任何情况下都能保持一致性,即事务要么完全执行,要么完全不执行,不会出现中间状态。


1.4  Redis通用命令

①.KEYS:查看符合模板的所有keys,不建议在生产环境设备中使用(因为redis是单线程,当要查找的数据量很大时,redis服务会被阻塞)
,pattern可以是*,表示查找全部,a*表示查找以a开头的keys
②.DEL:删除一个指定的key
③.EXISTS:判断key是否存在
④.EXPIRE:给一个key设置有效期,有效期到期时该key会被自动删除
⑤.TTL:查看一个KEY的剩余有效期(-1表示永久有效,-2表示已被删除,整数代表还剩多长时间)

通过help [command] 可以查看一个命令的具体用法

1.5  Redis数据结构介绍

Redis是一个key-value的数据库,key一般是String类型,不过value的类型多种多样

数据类型的使用详细访问:https://www.redis.net.cn/tutorial/3508.html

基本数据类型:String、Hash、List、Set、SortedSet

特殊类型:GEO、BitMap、HelperLog


1.6  Redis的java客户端

①.Jedis:以Redis命令作为方法名称,学习成本低。但是Jedis实例是线程不安全的,多线程环境下需要基于线程池来连接

②.Lettuce:Lettuce是基于Netty实现的,支持同步,异步和响应式编程方式,并且是线程安全的。支持Redis的哨兵模式,集群和管道模式.

③.Spring Data Redis整合了这两个客户端,可以兼容Jedis,Lettuce,也就是说Spring Data Redis定义了一套API既可以用Jedis实现也可以用Lettuce实现


2  Jedis快速入门

访问官方网址:https://redis.io/docs/connect/clients/java/jedis/#jedis

Jedis里面的API很类似原生Redis的相关指令,因此比较容易上手


2.1  操作步骤

①.引入依赖
②.建立连接
Jedis jedis = new Jedis("host","port");
jedis.auth("password");
③.测试方法
④.关闭资源(可以使用 try-with-resources 语法来确保 Jedis 在使用完毕后被自动关闭)


2.2  Jedis连接池

Jedis本身是不安全的,并且频繁的创建和销毁连接会有性能的损耗,因此推荐使用Jedis连接池代替Jedis的直连方式

注意:如果是连接池通过getJedis取出来Jedis,Jedis.close()方法不是直接断开,而是pool.returnResource(this),归还给连接池

public class JedisConnectionConfig {
    private static final JedisPool jedisPool;

    static {
        //配置连接池
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        //最大连接数
        jedisPoolConfig.setMaxTotal(8);
        //最大空闲时间
        jedisPoolConfig.setMaxIdle(8);
        //最小空闲连接
        jedisPoolConfig.setMinIdle(0);
        //设置最长等待时间,ms
        jedisPoolConfig.setMaxWaitMillis(200);
        //创建连接池对象
         jedisPool = new JedisPool(jedisPoolConfig,"192.168.85.131",6379,1000,"root");

    }
    //获取Jedis对象
    public static Jedis getJedis(){

        return jedisPool.getResource();
    }
}


3  SpringDataRedis

3.1  定义

Spring Data Redis是Spring Data项目的一部分,旨在简化Spring应用程序中的数据访问。Spring Data Redis专门提供与Redis集成

官网地址:https://spring.io/projects/spring-data-redis

3.2  优势

①.提供了对不同Redis客户端的整合(Lettuce和Jedis)

②.提供了RedisTemplate统一API来操作Redis

③.支持基于JDK、JSON、字符串、Spring对象的数据序列化及反序列化

④.支持基于Redis的JDKCollection实现

3.3  API

API                        返回值类型                     说明
    
opsForValue()        ValueOperations            操作String类型
opsForHash()        HashOperations              操作Hash类型
opsForList()           ListOperations                操作List类型
opsForSet()            SetOperations                操作Set类型
opsForZSet()          ZSetOperations              操作SortedSet类型
redisTemplate                                                通用命令    

3.4  操作步骤

①.引入依赖(需要两个依赖)

//Redis依赖

    org.springframework.boot
    spring-boot-starter-data-redis


//连接池依赖(因为Jedis和Lettuce底层都会基于commons-pool来实现连接池效果)

    org.apache.commons
    commons-pool2

②.配置文件

spring:
  data:
    redis:
      host: localhost
      port: 6379
      #password: 123456
      database: 0 #操作的是0号数据库
      jedis:  #如果不配置这一项,默认为Lettuce
        #Redis连接池配置
        pool:
          max-active: 8 #最大连接数
          max-wait: 1ms #连接池最大阻塞等待时间
          max-idle: 4 #连接池中的最大空闲连接
          min-idle: 0 #连接池中的最小空闲连接

③.注入RedisTemplate

@Autowired
private RedisTemplate redisTemplate;

④.编写测试

SpringDataRedis的序列化方式

默认序列化器是 this.defaultSerializer = new JdkSerializationRedisSerializer,

如果你没有去实现其他序列化器,会导致中文乱码问题

@Configuration
public class RedisConfig extends CachingConfigurerSupport {
    //RedisTemplate 是一个通用的 Redis 操作模板,它支持对 Redis 中多种数据结构的操作
    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) {

        RedisTemplate redisTemplate = new RedisTemplate<>();

        //默认的Key序列化器为:JdkSerializationRedisSerializer
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());

        redisTemplate.setConnectionFactory(connectionFactory);

        return redisTemplate;
    }

}


3.5  乱码解决方案

自己配置序列化器,一般key是String类型,value是Object类型,value可能存储是一个对象

因此一般key实现StringRedisSerializer序列化器,value实现GenericJackson2JsonRedisSerializer序列化器

实现如下图:

@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory){
        // 创建RedisTemplate对象
        RedisTemplate template = new RedisTemplate<>();
        // 设置连接工厂
        template.setConnectionFactory(connectionFactory);
        // 创建JSON序列化工具
        GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        // 设置Key的序列化
        template.setKeySerializer(RedisSerializer.string());
        template.setHashKeySerializer(RedisSerializer.string());
        // 设置Value的序列化
        template.setValueSerializer(jsonRedisSerializer);
        template.setHashValueSerializer(jsonRedisSerializer);
        // 返回
        return template;
    }
}
 @Test
    void testSaveUser() {
        // 写入数据
        redisTemplate.opsForValue().set("user:100", new User("大老鼠", 21));
        // 获取数据
        User o = (User) redisTemplate.opsForValue().get("user:100");
        System.out.println("o = " + o);
    }

3.5.1  GenericJackson2JsonRedisSerializer优势

GenericJackson2JsonRedisSerializer好处就是会将User对象序列化成JSON格式,然后

再将JSON格式序列化为@class里面的User对象,而这些都是自动化进行的

【Redis基础篇】详细讲解Redis_第1张图片

3.5.2  GenericJackson2JsonRedisSerializer缺陷

GenericJackson2JsonRedisSerializer通过上面这张图,也可以看出

GenericJackson2JsonRedisSerializer的缺陷,就是为了记录序列化的对象占用的内存比数据本身

还多,如果数据量很多的话,就不能突显redis的效率快特性

3.5.3  改进方案

让key和value都实现StringRedisSerializer序列化器,然而这并不需要我们再去配置序列化器,

因为底层 StringRedisTemplate已经整合并实现了StringRedisSerializer序列化器,因此只需要

@Autowired
private  StringRedisTemplate  stringRedisTemplate;

但是序列化和反序列化要我们手动操作

private static final ObjectMapper mapper = new ObjectMapper();

    @Test
    void testSaveUser() throws JsonProcessingException {
        // 创建对象
        User user = new User("大老鼠", 21);
        // 手动序列化
        String json = mapper.writeValueAsString(user);
        // 写入数据
        stringRedisTemplate.opsForValue().set("user:200", json);
        // 获取数据
        String jsonUser = stringRedisTemplate.opsForValue().get("user:200");
        // 手动反序列化
        User user1 = mapper.readValue(jsonUser, User.class);
        System.out.println("user1 = " + user1);
    }

3.5.4  RedisTemplate的两种序列化实践方案:


方案一:
自定义RedisTemplate
修改RedisTemplate的序列化器为GenericJackson2JsonRedisSerializer

方案二(推荐):
使用StringRedisTemplate
写入Redis时,手动把对象序列化为JSON
读取Redis时,手动把读取到的JSON反序列化为对象

代码演示:

/**
    序列化
*/

// 尝试从 Redis 中获取数据
String userJson = stringRedisTemplate.opsForValue().get(redisKey);

// 将对象序列化为 JSON 字符串
userJson = objectMapper.writeValueAsString(user);

// 将数据存储到 Redis 中,设置过期时间为 5 分钟
stringRedisTemplate.opsForValue().set(redisKey, userJson, 5, TimeUnit.MINUTES);



/**
    反序列化
*/

// 示例 JSON 字符串
String userJson = "{\"id\":\"1\",\"name\":\"Alice\",\"age\":30}";

// 将 JSON 字符串反序列化为 User 对象
User user = objectMapper.readValue(userJson, User.class);

// 打印反序列化后的 User 对象
System.out.println("Deserialized User: ");
System.out.println("ID: " + user.getId());
System.out.println("Name: " + user.getName());
System.out.println("Age: " + user.getAge());

你可能感兴趣的:(redis数据库,redis,服务器,nosql,缓存,数据库,java,spring,boot)