Redis Java 开发简单示例

文章目录

    • 一、概述
    • [二、Jedis 开发示例](#二、Jedis 开发示例)
      • [2.1 导入 maven 依赖](#2.1 导入 maven 依赖)
      • [2.2 使用连接池读写](#2.2 使用连接池读写)
      • [2.3 使用集群读写](#2.3 使用集群读写)
      • [2.4 完整示例代码](#2.4 完整示例代码)
      • [2.5 测试集群的搭建](#2.5 测试集群的搭建)
    • [三、Lettuce 开发示例](#三、Lettuce 开发示例)
      • [3.1 导入 maven 依赖](#3.1 导入 maven 依赖)
      • [3.2 读写数据](#3.2 读写数据)
    • [四、Spring Boot Redis 开发示例](#四、Spring Boot Redis 开发示例)
      • [4.1 导入 maven 依赖](#4.1 导入 maven 依赖)
      • [4.2 配置Redis服务地址](#4.2 配置Redis服务地址)
      • [4.3 基于 RedisTemplate 的读写全类型数据](#4.3 基于 RedisTemplate 的读写全类型数据)
      • [4.4 基于 StringRedisTemplate 的读写字符串类型数据](#4.4 基于 StringRedisTemplate 的读写字符串类型数据)
      • [4.5 基于 RedisConnection 的读写字节数据](#4.5 基于 RedisConnection 的读写字节数据)
      • [4.6 读写 Hash 数据类型](#4.6 读写 Hash 数据类型)
      • [4.7 订阅发布](#4.7 订阅发布)
      • [4.8 基于SpringBoot的完整测试代码](#4.8 基于SpringBoot的完整测试代码)
      • [4.9 注意问题](#4.9 注意问题)

如果您对Redis的了解不够深入请关注本栏目,本栏目包括Redis安装Redis配置文件说明Redis命令和数据类型说明Redis持久化配置Redis主从复制和哨兵机制Redis Cluster(集群)配置Redis Predixy 集群Redis Twemproxy 集群Redis Codis 集群Redis 集群对比RedisBloom 布隆过滤器

一、概述

  • Redis(Remote Dictionary Server)是一种高性能的开源内存数据库,它具有多种用途和功能,可以充当缓存、消息队列、数据库、实时分析和数据处理平台等多种角色。具体功能如下:

    1. 数据缓存: Redis 可以用作应用程序的缓存层,帮助减少对后端数据库的频繁访问。通过将经常使用的数据存储在内存中,可以显著提高读取速度,降低数据库负担,从而提高应用程序性能。
    2. 会话存储: Redis 可以用于存储用户会话数据,特别是在分布式环境中。这使得用户会话可以跨多个服务器实例进行共享,提高了应用程序的伸缩性和可用性。
    3. 消息队列: Redis 支持发布/订阅(Pub/Sub)模式,使其成为一个优秀的消息队列平台。应用程序可以使用 Redis 来发送和接收消息,实现异步通信、事件驱动和消息分发。
    4. 计数器和统计信息: Redis 提供了递增和递减操作,因此它非常适合存储计数器数据。这对于跟踪应用程序中的用户行为、实时统计信息和监视任务非常有用。
    5. 地理空间数据: Redis 支持地理空间数据(Geospatial Data),因此它可以用于存储位置信息、地图数据和地理位置查询。
    6. 分布式锁: Redis 可以用于实现分布式锁,确保在分布式系统中的互斥操作。这对于避免竞态条件和数据一致性非常重要。
    7. 缓存击穿保护: Redis 可以用于缓存击穿保护,通过设置适当的过期时间或使用布隆过滤器来避免某个数据的同时大量请求导致的数据库请求。
    8. 实时数据传输: Redis 可以用于构建实时数据传输和协作应用程序,如聊天应用、协同编辑和游戏。
    9. 数据持久性: Redis 提供不同级别的数据持久性选项,以确保数据在服务器重启后不会丢失。
  • 下面分别使用 Jedis 、Lettuce 访问Redis 和 在 Spring Boot 使用访问 Redis 的简单示例。

二、Jedis 开发示例

2.1 导入 maven 依赖

  • 在 pom.xml 添加 jedis

    xml 复制代码
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>3.9.0</version>
        </dependency>

2.2 使用连接池读写

  • 使用连接池对单个Redis实例进行读写

    java 复制代码
            JedisPool pool = new JedisPool("192.168.8.60", 6379);
            Jedis resource = pool.getResource();
            resource.set("aaa", "111");
            System.out.println("read redis 1="+resource.get("aaa"));

2.3 使用集群读写

  • 使用集群对Redis集群进行读写

    java 复制代码
            Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();
            jedisClusterNodes.add(new HostAndPort("192.168.8.60", 30001));
            jedisClusterNodes.add(new HostAndPort("192.168.8.60", 30002));
            jedisClusterNodes.add(new HostAndPort("192.168.8.60", 30003));
    //        jedisClusterNodes.add(new HostAndPort("192.168.8.60", 30004));
    //        jedisClusterNodes.add(new HostAndPort("192.168.8.60", 30005));
    //        jedisClusterNodes.add(new HostAndPort("192.168.8.60", 30006));
            JedisCluster jedis = new JedisCluster(jedisClusterNodes);
    
            jedis.set("ddd", "1111");
            System.out.println("read redis 2="+ jedis.get("aaa"));

2.4 完整示例代码

  • 以下是完整的测试代码

    java 复制代码
    package top.yiqifu.study.p121;
    
    
    import redis.clients.jedis.HostAndPort;
    import redis.clients.jedis.Jedis;
    import redis.clients.jedis.JedisCluster;
    import redis.clients.jedis.JedisPool;
    
    import java.util.HashSet;
    import java.util.Set;
    
    public class Test01_Redis {
    
        public static void main(String[] args) {
            // 通过连接池直接读写数据
            testResource();
    
            //通过Redis集群(Cluster)读写数据
            testCluster();
        }
    
        private static void testResource(){
            JedisPool pool = new JedisPool("192.168.8.60", 6379);
            Jedis resource = pool.getResource();
            resource.set("aaa", "111");
            System.out.println("read redis 1="+resource.get("aaa"));
        }
    
        private static void testCluster(){
            Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();
            jedisClusterNodes.add(new HostAndPort("192.168.8.60", 30001));
            jedisClusterNodes.add(new HostAndPort("192.168.8.60", 30002));
            jedisClusterNodes.add(new HostAndPort("192.168.8.60", 30003));
    //        jedisClusterNodes.add(new HostAndPort("192.168.8.60", 30004));
    //        jedisClusterNodes.add(new HostAndPort("192.168.8.60", 30005));
    //        jedisClusterNodes.add(new HostAndPort("192.168.8.60", 30006));
            JedisCluster jedis = new JedisCluster(jedisClusterNodes);
    
            jedis.set("ddd", "1111");
            System.out.println("read redis 2="+ jedis.get("aaa"));
        }
    }

2.5 测试集群的搭建

  • 以下给出测试集群搭建的核心命令,具体请参考Redis Cluster(集群)配置

    bash 复制代码
    cd /redis-6.0.6/utils/create-cluster
    vi create-cluster
        CLUSTER_HOST=192.168.8.60
        PROTECTED_MODE=no
    ./create-cluster start
    ./create-cluster create
    
    
    firewall-cmd  --permanent  --add-port=30001/tcp
    firewall-cmd  --permanent  --add-port=30002/tcp
    firewall-cmd  --permanent  --add-port=30003/tcp
    firewall-cmd  --permanent  --add-port=30004/tcp
    firewall-cmd  --permanent  --add-port=30005/tcp
    firewall-cmd  --permanent  --add-port=30006/tcp
    firewall-cmd  --reload

三、Lettuce 开发示例

3.1 导入 maven 依赖

  • 开源地址:lettuce-core

  • 在 pom.xml 添加 lettuce-core

    xml 复制代码
            <dependency>
                <groupId>io.lettuce</groupId>
                <artifactId>lettuce-core</artifactId>
                <version>6.1.10.RELEASE</version>
            </dependency>

3.2 读写数据

  • 以下使用 lettuce 来读写Redis,lettuce 最大的特点是支持响应式编程(Reactive API)。

    java 复制代码
    package top.yiqifu.study.p121;
    
    
    import io.lettuce.core.RedisClient;
    import io.lettuce.core.api.StatefulRedisConnection;
    import io.lettuce.core.api.async.RedisAsyncCommands;
    import io.lettuce.core.api.sync.RedisStringCommands;
    
    public class Test02_LettuceRedis {
    
        public static void main(String[] args) {
            // 同步/异步方式读写数据
            testSync();
        }
    
        private static void testSync(){
            RedisClient client = RedisClient.create("redis://192.168.8.60:6379");
            StatefulRedisConnection<String, String> connection = client.connect();
            RedisStringCommands sync = connection.sync();
            sync.set("aaa", "111");
            System.out.println("read redis 1="+sync.get("aaa"));
    
            RedisAsyncCommands<String, String> async = connection.async();
            async.set("bbb", "222");
            System.out.println("read redis 2="+async.get("bbb"));
        }
    }

四、Spring Boot Redis 开发示例

4.1 导入 maven 依赖

  • 这里 spring-boot-starter-data-redis 是 Redis 的依赖,而 spring-boot-starter-json 是用于数据序列化的 json 依赖。
xml 复制代码
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <version>2.7.15</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-json</artifactId>
            <version>2.7.15</version>
        </dependency>

4.2 配置Redis服务地址

  • 在 application.yaml 文件中添加配置
yaml 复制代码
spring:
  redis:
    host: 192.168.8.60
    port: 6379

4.3 基于 RedisTemplate 的读写全类型数据

java 复制代码
    @Autowired
    RedisTemplate redisTemplate;
    
    private void  testObject(){
        redisTemplate.opsForValue().set("aaa", "111");
        System.out.println("reda redis 1 = "+redisTemplate.opsForValue().get("aaa"));
    }

4.4 基于 StringRedisTemplate 的读写字符串类型数据

java 复制代码
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    
    private void testString(){
        stringRedisTemplate.opsForValue().set("bbb", "222");
        System.out.println("read redis 2 = "+stringRedisTemplate.opsForValue().get("bbb"));
    }

4.5 基于 RedisConnection 的读写字节数据

java 复制代码
    @Autowired
    RedisTemplate redisTemplate;
    
    private void  testObject(){
        redisTemplate.opsForValue().set("aaa", "111");
        System.out.println("reda redis 1 = "+redisTemplate.opsForValue().get("aaa"));
    }

4.6 读写 Hash 数据类型

java 复制代码
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @Autowired
    @Qualifier("serializerRedisTemplate")
    StringRedisTemplate serializerRedisTemplate;

    private void testHash(){
        // 方法一:使用 StringRedisTemplate 直接读写hash
        HashOperations<String, Object, Object> hash = stringRedisTemplate.opsForHash();
        hash.put("someInfo", "name" , "qifu");
        hash.put("someInfo", "age" , "30");
        System.out.println("read redis 4 = "+hash.entries("someInfo"));//hincrby someInfo age 1

        // 创建对象
        Person person = new Person();
        person.setName("zhang san");
        person.setAge(20);
        Jackson2HashMapper hashMapper = new Jackson2HashMapper(objectMapper, false);

        // 方法二:使用 RedisTemplate 读写 hash 对象
        redisTemplate.opsForHash().putAll("person1", hashMapper.toHash(person));
        Map personMap1 = redisTemplate.opsForHash().entries("person1");
        Person value6 = objectMapper.convertValue(personMap1, Person.class);
        System.out.println("read redis 6 = "+value6.getName());

        // 方法三:使用 StringRedisTemplate 读写 hash 对象
        // stringRedisTemplate 需设置 ValueSerializer ,因为age是Integer类型
        stringRedisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));
        stringRedisTemplate.opsForHash().putAll("person2", hashMapper.toHash(person));
        Map personMap2 = stringRedisTemplate.opsForHash().entries("person2");
        Person value7 = objectMapper.convertValue(personMap2, Person.class);
        System.out.println("read redis 7 = "+value7.getName());

        // 方法四:使用自定义 serializerRedisTemplate  读写 hash 对象
        serializerRedisTemplate.opsForHash().putAll("person3", hashMapper.toHash(person));
        Map personMap3 = serializerRedisTemplate.opsForHash().entries("person3");
        Person value8 = objectMapper.convertValue(personMap3, Person.class);
        System.out.println("read redis 8 = "+value8.getName());
    }

4.7 订阅发布

java 复制代码
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    
    private void  testPubsub(){
        //pub/sub
        stringRedisTemplate.getConnectionFactory().getConnection().subscribe(new MessageListener() {
            @Override
            public void onMessage(Message message, byte[] pattern) {
                System.out.println("sub redis = "+new String(message.getBody()));
            }
        }, "xxx".getBytes());
        stringRedisTemplate.convertAndSend("xxx","yyy");
    }

4.8 基于SpringBoot的完整测试代码

  • TestRedis.java

    java 复制代码
    package top.yiqifu.study.p211_redis;
    
    import com.fasterxml.jackson.databind.ObjectMapper;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.data.redis.connection.Message;
    import org.springframework.data.redis.connection.MessageListener;
    import org.springframework.data.redis.connection.RedisConnection;
    import org.springframework.data.redis.core.HashOperations;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.core.StringRedisTemplate;
    import org.springframework.data.redis.hash.Jackson2HashMapper;
    import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
    import org.springframework.stereotype.Component;
    
    import java.util.Map;
    
    @Component
    public class TestRedis {
        @Autowired
        RedisTemplate redisTemplate;
        @Autowired
        StringRedisTemplate stringRedisTemplate;
        @Autowired
        @Qualifier("serializerRedisTemplate")
        StringRedisTemplate serializerRedisTemplate;
    
        @Autowired
        ObjectMapper objectMapper;
    
        public void  test(){
            // 基于 RedisTemplate 测试Redis全类型的读写,如 object
            this.testObject();
    
            // 基于 StringRedisTemplate 测试Redis字符串类型的读写,如 string
            this.testString();
    
            // 基于 RedisConnection 测试Redis更底层的字节类型的读写,如 byte[]
            this.testBytes();
    
            // 基于 StringRedisTemplate 测试Redis的Hash类型的读写,如 hash
            this.testHash();
    
            // 基于 StringRedisTemplate 测试Redis的发布、订阅
            this.testPubsub();
        }
    
    
        private void  testObject(){
            redisTemplate.opsForValue().set("aaa", "111");
            System.out.println("reda redis 1 = "+redisTemplate.opsForValue().get("aaa"));
        }
        private void testString(){
            stringRedisTemplate.opsForValue().set("bbb", "222");
            System.out.println("read redis 2 = "+stringRedisTemplate.opsForValue().get("bbb"));
        }
        private void testBytes(){
            RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
            connection.set("ccc".getBytes(), "333".getBytes());
            System.out.println("read redis 3 = "+new String(connection.get("ccc".getBytes())));
        }
    
        private void testHash(){
            // 方法一:使用 StringRedisTemplate 直接读写hash
            HashOperations<String, Object, Object> hash = stringRedisTemplate.opsForHash();
            hash.put("someInfo", "name" , "qifu");
            hash.put("someInfo", "age" , "30");
            System.out.println("read redis 4 = "+hash.entries("someInfo"));//hincrby someInfo age 1
    
            // 创建对象
            Person person = new Person();
            person.setName("zhang san");
            person.setAge(20);
            Jackson2HashMapper hashMapper = new Jackson2HashMapper(objectMapper, false);
    
            // 方法二:使用 RedisTemplate 读写 hash 对象
            redisTemplate.opsForHash().putAll("person1", hashMapper.toHash(person));
            Map personMap1 = redisTemplate.opsForHash().entries("person1");
            Person value6 = objectMapper.convertValue(personMap1, Person.class);
            System.out.println("read redis 6 = "+value6.getName());
    
            // 方法三:使用 StringRedisTemplate 读写 hash 对象
            // stringRedisTemplate 需设置 ValueSerializer ,因为age是Integer类型
            stringRedisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));
            stringRedisTemplate.opsForHash().putAll("person2", hashMapper.toHash(person));
            Map personMap2 = stringRedisTemplate.opsForHash().entries("person2");
            Person value7 = objectMapper.convertValue(personMap2, Person.class);
            System.out.println("read redis 7 = "+value7.getName());
    
            // 方法四:使用自定义 serializerRedisTemplate  读写 hash 对象
            serializerRedisTemplate.opsForHash().putAll("person3", hashMapper.toHash(person));
            Map personMap3 = serializerRedisTemplate.opsForHash().entries("person3");
            Person value8 = objectMapper.convertValue(personMap3, Person.class);
            System.out.println("read redis 8 = "+value8.getName());
        }
    
        private void  testPubsub(){
            //pub/sub
            stringRedisTemplate.getConnectionFactory().getConnection().subscribe(new MessageListener() {
                @Override
                public void onMessage(Message message, byte[] pattern) {
                    System.out.println("sub redis = "+new String(message.getBody()));
                }
            }, "xxx".getBytes());
            stringRedisTemplate.convertAndSend("xxx","yyy");
        }
    }
  • Config.java

    java 复制代码
    package top.yiqifu.study.p211_redis;
    
    import org.springframework.beans.factory.annotation.Autowired;
    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.StringRedisTemplate;
    import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
    
    import javax.annotation.Resource;
    
    @Configuration
    public class Config {
    
        @Resource
        RedisConnectionFactory factory;
    
        @Bean("serializerRedisTemplate")
        public StringRedisTemplate getRedisTemplate(){
            StringRedisTemplate template = new StringRedisTemplate(factory);
            template.setHashValueSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));
            return template;
        }
    }
  • RedisSpringBootApplication.java

    java 复制代码
    package top.yiqifu.study.p211_redis;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.ConfigurableApplicationContext;
    
    @SpringBootApplication
    public class RedisSpringBootApplication {
        public static void main(String[] args){
    
            ConfigurableApplicationContext context = SpringApplication.run(RedisSpringBootApplication.class, args);
            TestRedis bean = context.getBean(TestRedis.class);
            bean.test();
        }
    }

4.9 注意问题

  • 在新版本(版本大于2.7)的SpringBoot中,以下写法会报错"Could not autowire. No beans of 'RedisConnectionFactory' type found",如下写法:

    java 复制代码
    @Configuration
    public class Config {
        @Bean("serializerRedisTemplate")
        public StringRedisTemplate getRedisTemplate(RedisConnectionFactory factory){
            StringRedisTemplate template = new StringRedisTemplate(factory);
            template.setHashValueSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));
            return template;
        }
    }
  • 要使用@Resource注解的属性注入,修改后的代码为

    java 复制代码
    @Configuration
    public class Config {
    
        @Resource
        RedisConnectionFactory factory;
    
        @Bean("serializerRedisTemplate")
        public StringRedisTemplate getRedisTemplate(){
            StringRedisTemplate template = new StringRedisTemplate(factory);
            template.setHashValueSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));
            return template;
        }
    }
相关推荐
louisgeek9 分钟前
Java 位运算
java
Code季风1 小时前
将 gRPC 服务注册到 Consul:从配置到服务发现的完整实践(上)
数据库·微服务·go·json·服务发现·consul
hweiyu001 小时前
Maven 私库
java·maven
Boilermaker19921 小时前
【Java EE】SpringIoC
前端·数据库·spring
Super Rookie1 小时前
Spring Boot 企业项目技术选型
java·spring boot·后端
来自宇宙的曹先生1 小时前
用 Spring Boot + Redis 实现哔哩哔哩弹幕系统(上篇博客改进版)
spring boot·redis·后端
写不出来就跑路1 小时前
Spring Security架构与实战全解析
java·spring·架构
霸王龙的小胳膊1 小时前
泛微虚拟视图-数据虚拟化集成
数据库
灵犀学长2 小时前
解锁Spring Boot多项目共享Redis:优雅Key命名结构指南
数据库·redis
轩情吖2 小时前
Qt的信号与槽(二)
数据库·c++·qt·信号·connect·信号槽·