Redis-常用语法以及java互联实践案例

简介: 本文详细介绍了Redis的数据结构、常用命令及其Java客户端的使用,涵盖String、Hash、List、Set、SortedSet等数据类型及操作,同时提供了Jedis和Spring Boot Data Redis的实战示例,帮助开发者快速掌握Redis在实际项目中的应用。

题记

本文涵盖了Redis的各种数据结构和命令,Redis的各种常见Java客户端的应用和最佳实践

jedis案例github地址:https://github.com/whltaoin/fedis_java_demo

SpringbootDataRedis案例github地址:https://github.com/whltaoin/springbootDataRedis_demo

一、初始Redis

1. SQL与NoSQL对比

  1. 结构化(Structured)对比
  1. SQL具有严格的结构化格式(左图)
  2. NoSQL的数据存储格式相对随意(右图)

  1. 关系对比
  1. SQL在表和表间可能存在联系,在操作一张表时,需要考虑对应关联表的完整性。

  1. NoSQL数据间是无关联的,(下图为存储方式)

  1. 查询对比
  1. SQL查询有固定的语法,只要是SQL都可以使用相同的语句查询。

  1. NoSQL没有固定的语法,每个NoSQL都有自己的语法糖(下图为查询同一个东西,出现了不同的语法)

  1. SQL需要满足事务的ACID特性(原子性、一致性、隔离性、持久性)
  2. NoSQL只是基本满足事务的ACID
  3. 差异总结:

2. 初始Redis

  1. 简介

Redis(远程词典服务器),是一个基于内存的键值型NoSQL数据库

  1. 特征:
  1. 键值型:key-value
  2. 单线程:命令具有原子性
  3. 低延迟、数据块原因:(基于内存、IO多路复用、良好的编码)
  4. 支持数据持久化
  5. 支持主从集群(主服务器和副服务器)、分片集群(将数据拆分,分别存在不同的服务器上)
  6. 支持多语言客户端(java、C...)

3. 安装Redis(Linux安装)

忽略...

二、Redis常见命令

1. 数据类型介绍

  1. String

  1. Hash
  1. 哈希表
  1. List
  1. 有序集合,本质是链表
  1. Set
  1. 无序集合,不可重复
  1. SortedSet
  1. 有序集合,不可重复
  1. GEO
  1. 地理坐标

2. 通用命令

  1. 查询所有通用命令:
help @generic

  1. 查看符合模版的所有key
  1. 注意:不建议在生产环境设备上使用该命令,因为模糊查询,效率不高且浪费资源

# 语法
keys +[pattern]

  1. 删除key
  1. 可以单个删除,也可以多个一起删除
del [key]

删除一个或多个示例

  1. 判断key是否存在
  1. 可以判断单个,也可以判断多个
exists [key]

判断单个和多个示例

  1. 给key设置有效期,到期后自动删除(单位秒)
  1. TTL查看可以的有效时间
expire [key] [seconds]
ttl key

示例:设置age1的有效期为10s,到期后自动删除

  1. 总结

3. String类型

  1. set

  1. get

  1. mset

  1. mget

  1. incr

  1. incrby

  1. incrbyfloat

  1. setnx(新增,存在则不创建)
  1. 等价于:set [key value] nx

  1. setex
  1. 等价于:set

4. Key的层级格式

  1. 思考:

  1. 解决方法

  1. 示例

heima:user:1
herma:product:1

层级结构:

5. Hash类型

  1. Hash类型(散列),其中的value是一个无序字典
  1. 类似于java 中的HashMap结构
  1. 使用场景:
  1. 当要修改JSON数据中某个属性的值时,使用String存储的需要重新覆盖数据,而我们的需求只是想要修改某个值
  1. 常用命令

  1. 示例
  1. hset

  1. hget

  1. hmset

  1. hmget

  1. hgetall

  1. hkeys

  1. hvals

  1. hincrby

  1. hsetnx(已存在,不新建)

6. List类型

  1. Redis中的List类型于java中的LinkedList类似,可以当它是一个双向链表结构。
  1. 既可以支持正向检索也可以支持反向检索。
  1. 特征:
  1. 有序
  2. 元素可重复
  3. 插入和删除快
  4. 查询速度一般
  1. 使用场景举例:
  1. 朋友圈点赞列表,评论列表等
  1. 常用命令:

  1. 示例:

7. Set类型

  1. Redis的Set结构和Java中的HashSet类似,可以看做一个value为null的HashMap。
  2. 特征:
  1. 无序
  2. 元素不可重复
  3. 查找快
  4. 支持交集、并集、差集等功能
  1. 单个set常见命令

  1. 示例

  1. 多个set操作命令
  1. 求交集(sinter):两集合公共的

  1. 求并集(sunion):所有元素合并

  1. 求差集(sdiff):set中有,但是set2中没有

  1. 练习题:

  1. 张三的好友人数

  1. 张三和李四的共同好友

  1. 查询那些人是张三的好友但是不是李四的好友

  1. 查询张三和李四的共同好友

  1. 判断李四是否是张三的好友

  1. 判断张三是否是李四的好友

  1. 将李四从张三的好友列表中移除

8. SortedSet类型

  1. 特性:
  1. 可排序
  2. 元素不可重复
  3. 查询快
  1. 应用场景:
  1. 因为可排序,常用于实现排行榜功能
  1. 常用命令

  1. 练习题:

  1. 添加数据

  1. 删除Tom

  1. 获取Amy分数

  1. 获取Rose排名

  1. 查询80分以上人数

  1. 给Amy加2分

  1. 查询排名前三的同学

  1. 查询80以下的同学

三、Redis的Java客户端

1. 常用Java客户端的优缺点对比

2. Jedis使用(单线程)

github地址:https://github.com/whltaoin/fedis_java_demo

  1. 使用Jedis分为了四步骤:
  1. 导入依赖
  2. 初始化Jedis对象
  3. 执行Jedis中的操作方法
  4. 释放Jedis对象
  1. 具体实现
  1. 导入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.example</groupId>
    <artifactId>jedis-test</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
  <dependencies>
<!--    核心-->
      <dependency>
          <groupId>redis.clients</groupId>
          <artifactId>jedis</artifactId>
          <version>6.0.0</version>
      </dependency>
<!--      测试类-->
      <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.13.2</version>
          <scope>test</scope>
      </dependency>
  </dependencies>
</project>

  b. 测试类方法内容

package cn.varin;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import redis.clients.jedis.Jedis;
public class JedisTest {
    private Jedis jedis;
    @Before
    public void init(){
        jedis = new Jedis("ip",6379);
        jedis.auth("密码");
        jedis.select(0);
    }
    @Test
    public void StringTest(){
        String set = jedis.set("name", "varin");
        System.out.println("执行set后结果为:"+set);
        String name = jedis.get("name");
        System.out.println("key为name的value为:"+name);
    }
    @After
    public void close(){
        if(jedis !=null){
            jedis.close();
        }
    }
}
  1. 执行结果

3. Jedis使用(使用连接池)

github地址:https://github.com/whltaoin/fedis_java_demo

  1. 使用步骤:
  1. 创建连接池
  2. 获取Jedis对象
  3. 操作Jedis对象
  4. 归还连接池对象
  1. 具体代码
  1. 创建连接池对象
package cn.varin.jedis.utils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
// Jedis连接池对象
public class JedisConnectionFactory {
    //
    static  public final JedisPool jedisPool;
    static {
        // 创建配置
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        // 最大连接数
        jedisPoolConfig.setMaxTotal(10);
        // 最大空闲数
        jedisPoolConfig.setMaxIdle(10);
        // 最小空闲数
        jedisPoolConfig.setMinIdle(2);
        // 空闲等待时间
        jedisPoolConfig.setMaxWaitMillis(1000);
        jedisPool = new JedisPool(jedisPoolConfig,"host",6379,100,"password");
    }
    public static Jedis getResource(){
       return jedisPool.getResource();
    }
}
  1. 测试类代码
package cn.varin;
import cn.varin.jedis.utils.JedisConnectionFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import redis.clients.jedis.Jedis;
public class JedisTest {
    private Jedis jedis;
    @Before
    public void init(){
        jedis = JedisConnectionFactory.getResource();
        jedis.select(0);
    }
    @Test
    public void StringTest(){
        String set = jedis.set("name", "varya");
        System.out.println("执行set后结果为:"+set);
        String name = jedis.get("name");
        System.out.println("key为name的value为:"+name);
    }
    @After
    public void close(){
        if(jedis !=null){
            jedis.close();
        }
    }
}
  1. 执行结果:

4. SpringDataRedis使用

github示例案例地址:https://github.com/whltaoin/springbootDataRedis_demo

4.1. springData介绍
  1. 项目地址:https://spring.io/projects/spring-data-redis#learn

  1. Redis模版版本信息

4.2. SpringDataRedis快速入门

4.3. SpringbootDataRedis使用步骤

4.4. 基本示例
  1. 导入依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.4.5</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>
  <groupId>cn.varin</groupId>
  <artifactId>springbootDataRedis_demo</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>springbootDataRedis_demo</name>
  <description>springbootDataRedis_demo</description>
  <url/>
  <licenses>
    <license/>
  </licenses>
  <developers>
    <developer/>
  </developers>
  <scm>
    <connection/>
    <developerConnection/>
    <tag/>
    <url/>
  </scm>
  <properties>
    <java.version>17</java.version>
  </properties>
  <dependencies>
<!--    springbootDataRedis-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
<!--    pool2-->
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-pool2</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <annotationProcessorPaths>
            <path>
              <groupId>org.projectlombok</groupId>
              <artifactId>lombok</artifactId>
            </path>
          </annotationProcessorPaths>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
          <excludes>
            <exclude>
              <groupId>org.projectlombok</groupId>
              <artifactId>lombok</artifactId>
            </exclude>
          </excludes>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>
  1. 配置yml
spring:
  data:
    redis:
      port: 6379
      password: password
      database: 0
      lettuce:
        pool:
          max-active: 10
          max-idle: 10
          min-idle: 0
          max-wait: 100ms
      host: address
  1. 编写测试类
package cn.varin.springbootdataredis_demo;
import cn.varin.springbootdataredis_demo.pojo.User;
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.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
@SpringBootTest
class SpringbootDataRedisDemoApplicationTests {
  @Autowired
  RedisTemplate redisTemplate;
  @Test
  void setTest() {
    ValueOperations valueOperations = redisTemplate.opsForValue();
    valueOperations.set("user:1",new User("varin",1).toString());
    Object o = valueOperations.get("user:1");
    System.out.println(o);
  }
}
  1. 结果:

4.5. 重构redisTemplate序列化和反序列化工具
  1. 问题

  1. 在我们直接使用redisTemplate时,存入到redis的内容,是经过编译的字节,
  2. 影响阅读性
  3. 增加了存储空间
  1. 解决方案:
  1. 自定义序列化和反序列话的编码格式
  1. 步骤
  1. 建立template
  2. 设置连接工厂
  3. 设置序列化工具
  4. 分别对key和value设置不同的格式
package cn.varin.springbootdataredis_demo.config;
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.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
@Configuration
public class RedisTamplateConfig {
    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory){
        RedisTemplate<String,Object> template = new RedisTemplate<>();
        // 设置连接工厂
        template.setConnectionFactory(factory);
        // 创建序列化工具
        GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        // 对key
        template.setKeySerializer(RedisSerializer.string());
        template.setHashKeySerializer(RedisSerializer.string());
        // 对value
        template.setValueSerializer(genericJackson2JsonRedisSerializer);
        template.setHashValueSerializer(genericJackson2JsonRedisSerializer);
        return  template;
    }
}

测试类

package cn.varin.springbootdataredis_demo;
import cn.varin.springbootdataredis_demo.pojo.User;
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.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
@SpringBootTest
class SpringbootDataRedisDemoApplicationTests {
  @Autowired
  RedisTemplate redisTemplate;
  @Test
  void setTest() {
    ValueOperations valueOperations = redisTemplate.opsForValue();
        // value为user对象
    valueOperations.set("user:2",new User("varin",1));
    Object o = valueOperations.get("user:1");
    System.out.println(o);
  }
}
  1. 测试结果

4.6. StringRedisTamplate类使用
  1. 问题:
  1. 虽然自定义序列化工具可以解决上一问题,但是修改后在JSON字符串中会多存储一个类的包名
  1. 导致增大存储的空间
  1. 解决方法,
  1. 使用StringRedisTamplate类,在加上自己使用第三方的序列化工具进行存储。
  1. 优点:在存储时不会增加额外的数据
  2. 缺点:增加少许的代码量
  1. 示例代码
@Autowired
  StringRedisTemplate stringRedisTemplate;
  // 用于转Json格式
  private static  final ObjectMapper mapper = new ObjectMapper();
  @Test
  void StringRedisTamplateTest() throws JsonProcessingException {
    User user = new User("varya",1);
    // 转JSON格式
    String s = mapper.writeValueAsString(user);
    // 写入数据
    stringRedisTemplate.opsForValue().set("user:3",s);
    // 读取数据
    String s1 = stringRedisTemplate.opsForValue().get("user:3");
    // 反序列化
    User user1 = mapper.readValue(s1, User.class);
    System.out.println(user1);
  }

目录
相关文章
|
6月前
|
存储 Java 容器
Java基本语法详解
本文深入讲解了Java编程的基础语法,涵盖数据类型、运算符、控制结构及数组等核心内容,帮助初学者构建坚实的编程基础。
|
5月前
|
Java
Java基础语法与面向对象
重载(Overload)指同一类中方法名相同、参数列表不同,与返回值无关;重写(Override)指子类重新实现父类方法,方法名和参数列表必须相同,返回类型兼容。重载发生在同类,重写发生在继承关系中。
186 1
|
7月前
|
Java 数据库连接 数据库
Java 相关知识点总结含基础语法进阶技巧及面试重点知识
本文全面总结了Java核心知识点,涵盖基础语法、面向对象、集合框架、并发编程、网络编程及主流框架如Spring生态、MyBatis等,结合JVM原理与性能优化技巧,并通过一个学生信息管理系统的实战案例,帮助你快速掌握Java开发技能,适合Java学习与面试准备。
350 2
Java 相关知识点总结含基础语法进阶技巧及面试重点知识
|
10月前
|
NoSQL Java API
在Java环境下如何进行Redis数据库的操作
总的来说,使用Jedis在Java环境下进行Redis数据库的操作,是一种简单而高效的方法。只需要几行代码,就可以实现复杂的数据操作。同时,Jedis的API设计得非常直观,即使是初学者,也可以快速上手。
425 94
|
8月前
|
缓存 监控 NoSQL
Redis 实操要点:Java 最新技术栈的实战解析
本文介绍了基于Spring Boot 3、Redis 7和Lettuce客户端的Redis高级应用实践。内容包括:1)现代Java项目集成Redis的配置方法;2)使用Redisson实现分布式可重入锁与公平锁;3)缓存模式解决方案,包括布隆过滤器防穿透和随机过期时间防雪崩;4)Redis数据结构的高级应用,如HyperLogLog统计UV和GeoHash处理地理位置。文章提供了详细的代码示例,涵盖Redis在分布式系统中的核心应用场景,特别适合需要处理高并发、分布式锁等问题的开发场景。
535 41
|
6月前
|
算法 Java 测试技术
零基础学 Java: 从语法入门到企业级项目实战的详细学习路线解析
本文为零基础学习者提供完整的Java学习路线,涵盖语法基础、面向对象编程、数据结构与算法、多线程、JVM原理、Spring框架、Spring Boot及项目实战,助你从入门到进阶,系统掌握Java编程技能,提升实战开发能力。
404 0
|
8月前
|
缓存 NoSQL Java
Java Redis 面试题集锦 常见高频面试题目及解析
本文总结了Redis在Java中的核心面试题,包括数据类型操作、单线程高性能原理、键过期策略及分布式锁实现等关键内容。通过Jedis代码示例展示了String、List等数据类型的操作方法,讲解了惰性删除和定期删除相结合的过期策略,并提供了Spring Boot配置Redis过期时间的方案。文章还探讨了缓存穿透、雪崩等问题解决方案,以及基于Redis的分布式锁实现,帮助开发者全面掌握Redis在Java应用中的实践要点。
467 6
|
7月前
|
存储 安全 Java
从基础语法到实战应用的 Java 入门必备知识全解析
本文介绍了Java入门必备知识,涵盖开发环境搭建、基础语法、面向对象编程、集合框架、异常处理、多线程和IO流等内容,结合实例帮助新手快速掌握Java核心概念与应用技巧。
177 0
|
11月前
|
缓存 安全 Java
java面试-基础语法与面向对象
本文介绍了 Java 编程中的几个核心概念。首先,详细区分了方法重载与重写的定义、发生阶段及规则;其次,分析了 `==` 与 `equals` 的区别,强调了基本类型和引用类型的比较方式;接着,对比了 `String`、`StringBuilder` 和 `StringBuffer` 的特性,包括线程安全性和性能差异;最后,讲解了 Java 异常机制,包括自定义异常的实现以及常见非检查异常的类型。这些内容对理解 Java 面向对象编程和实际开发问题解决具有重要意义。
|
Linux 网络安全 Docker
尼恩一键开发环境: vagrant+java+springcloud+redis+zookeeper镜像下载(&制作详解)
尼恩提供了一系列文章,旨在帮助开发者轻松搭建一键开发环境,涵盖Java分布式、高并发场景下的多种技术组件安装与配置。内容包括但不限于Windows和CentOS虚拟机的安装与排坑指南、MySQL、Kafka、Redis、Zookeeper等关键组件在Linux环境下的部署教程,并附带详细的视频指导。此外,还特别介绍了Vagrant这一虚拟环境部署工具,
尼恩一键开发环境: vagrant+java+springcloud+redis+zookeeper镜像下载(&制作详解)

热门文章

最新文章