如何在在Java中操作Redis

发布于:2024-09-19 ⋅ 阅读:(13) ⋅ 点赞:(0)

在Java中操作Redis

1 介绍

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

Redis 的 Java 客户端很多,官方推荐的有三种:

  • Jedis
  • Lettuce
  • Redisson

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

2 Jedis(理解)

1.Jedis使用介绍

Jedis 是 Redis 的 Java 版本的客户端实现。

maven坐标:

<dependency>
	<groupId>redis.clients</groupId>
	<artifactId>jedis</artifactId>
	<version>2.8.0</version>
</dependency>

使用 Jedis 操作 Redis 的步骤:

  1. 获取连接
  2. 执行操作
  3. 关闭连接
2. Jedis类常用方法

注:每个方法就是redis中的命令名,方法的参数就是命令的参数。

在每次访问Redis数据库的时候,都需要创建一个Jedis对象。每个Jedis对象似于JDBC中Connection对象,类似于mybatis中session对象。

连接和关闭 功能
new Jedis(host, port) 创建Jedis连接对象,参数:
host: 服务器地址
port:端口号6379
void close() 关闭连接
对string操作的方法 说明
set(String key,String value) 添加字符串类型的键和值
String get(String key) 通过键得到字符串的值
del(String … keys) 删除一个或多个键
对hash操作的方法 说明
hset(String key,String field,String value) 添加一个hash类型的键,字段和值
Map<String,String> hgetall(String key) 通过一个键得到所有的字段和值,返回Map
对list操作的方法 说明
lpush(String key,String…values) 从左边添加多个值到list中
List<String> lrange(String key,long start,long end) 通过键得到指定范围的元素
对set操作的方法 说明
sadd(String key,String…values) 添加一个或多个元素
Set<String> smembers(String key) 通过键得到集合所有的元素
对zset操作的方法 说明
zadd(String key, double score, String member) 添加一个键,分数和值
Set<String> zrange(String key, long start, long end) 查询一个指定范围的元素
3、案例:Jedis的基本操作
目标

使用Jedis上面的方法来访问Redis,向服务器中写入字符串、hash和list类型,并且取出打印到控制台上。

操作步骤:

1.导入依赖

<dependency>
	<groupId>redis.clients</groupId>
	<artifactId>jedis</artifactId>
	<version>2.8.0</version>
</dependency>

2.创建测试类,书写操作redis数据库的代码,代码一共分为三步:

​ 【1】创建jedis对象,连接redis数据库服务器 new Jedis(host,port)

​ 【2】 操作数据

​ 【3】 关闭连接

【1.下面是操作字符串数据的代码】:

package com.itheima.sh.jedis_test_01;

import org.junit.Test;
import redis.clients.jedis.Jedis;

import java.util.List;

public class JedisTest01 {
    /*
        jedis入门
     */
    @Test
    public void test01(){
        //1.创建jedis对象,连接redis数据库服务器 new Jedis(host,port)
        Jedis jedis = new Jedis("127.0.0.1",6379);
        //2.操作数据
        //【1】字符串
        jedis.set("username", "柳岩");
        //获取
        String username = jedis.get("username");
        System.out.println("username = " + username);
        //一次性添加多个数据 mset(key1,value1,key2,value2,...)
        jedis.mset("addr", "sh", "company", "黑马");
        //获取所有的数据
        List<String> values = jedis.mget("username", "addr", "company");
        System.out.println("values = " + values);
        //3.关闭连接
        jedis.close();
    }
}

控制台输出结果:

小结:

1.一次性添加多个字符串数据,使用的方法如下:

mset(key1,value1,key2,value2,...)

2.一次性获取所有的字符串:

List<String> mget(key1,key2,key3...);

【2.下面是操作hash数据的代码】:

package com.itheima.sh.jedis_test_01;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class JedisTest01 {
    /*
        jedis入门
     */
    @Test
    public void test01(){
        //1.创建jedis对象,连接redis数据库服务器 new Jedis(host,port)
        Jedis jedis = new Jedis("127.0.0.1",6379);
        //2.操作数据
       //【2】hash
        jedis.hset("person", "username", "锁哥");
        //存储多个数据 注意这里map集合的键和值都是String类型
        Map<String, String> map = new HashMap<>();
        map.put("age", "18");
        map.put("height", "180");
        jedis.hmset("person", map);
        //获取hash中的所有的数据
        Map<String, String> map1 = jedis.hgetAll("person");
        System.out.println(map1);
        //3.关闭连接
        jedis.close();
    }
}

控制台输出结果:

小结:

1.向hash中添加一个数据:

jedis.hset(key, field, value);

2.向hash中添加多个数据:

jedis.hset(key, map集合);

3.获取hash中所有的数据:

Map<String, String> map1 = jedis.hgetAll(key);

4.3 Spring Data Redis(掌握)

4.3.1 介绍

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

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

maven坐标:

<dependency>
	<groupId>org.springframework.data</groupId>
	<artifactId>spring-data-redis</artifactId>
	<version>2.4.8</version>
</dependency>

Spring Boot提供了对应的Starter,maven坐标:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

Spring Data Redis中提供了一个高度封装的类:RedisTemplate,针对类似 Jedis 客户端中大量api进行了归类封装,将同一类型操作封装为operation接口,具体分类如下:

  • ValueOperations:简单K-V操作(String类型)
  • SetOperations:set类型数据操作
  • ZSetOperations:zset类型数据操作
  • HashOperations:针对hash类型的数据操作
  • ListOperations:针对list类型的数据操作
4.3.2 使用方式
4.3.2.1 环境搭建

直接导入素材中的代码到idea中即可:

第一步:创建maven项目springdataredis_demo,配置pom.xml文件

<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.5</version>
        <relativePath/>
    </parent>
    <groupId>com.itheima</groupId>
    <artifactId>springdataredis_demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.4.5</version>
            </plugin>
        </plugins>
    </build>
</project>

第二步:编写启动类

package com.itheima;

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

@SpringBootApplication
public class App {

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

}

第三步:配置application.yml

spring:
  #Redis相关配置
  redis:
    host: 192.168.200.128 # 连接linux系统的redis
    port: 6379 # 端口号
    database: 0 #操作的是0号数据库

解释说明:

spring.redis.database:指定使用Redis的哪个数据库,Redis服务启动后默认有16个数据库,编号分别是从0到15。

可以通过修改Redis配置文件来指定数据库的数量。

第四步:提供测试类

package com.itheima.test;

import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@SpringBootTest
public class SpringDataRedisTest {

    @Autowired
    private RedisTemplate redisTemplate;
    
}
4.3.2.2 操作字符串类型数据

需求:

1.存入数据和取出数据

2.存值并设置过期时间

3.如果存在值则不执行任何操作

  /**
     * 操作String类型的数据
     */
    @Test
    public void test01String(){
        //获取操作String类型的接口对象
        ValueOperations valueOperations = redisTemplate.opsForValue();
        //存值
        valueOperations.set("city123","beijing");

        //取值
        String value = (String) valueOperations.get("city123");
        System.out.println(value);

        //存值,同时设置过期时间   TimeUnit:超时时间单位
        /*
            void set(K key, V value, long timeout, TimeUnit unit);
                key :字段key
                value:key对应的值
                timeout:超时时间
                TimeUnit:超时时间单位
         */
        valueOperations.set("username","suoge",10, TimeUnit.SECONDS);

        //存值,如果存在则不执行任何操作
        Boolean aBoolean = valueOperations.setIfAbsent("city1234", "nanjing");
        System.out.println(aBoolean);
    }

上述操作完毕之后,在客户端查看键,如下所示:

因为默认的key序列化器为JdkSerializationRedisSerializer,导致我们存到Redis中后的数据和原始数据有差别。如果我们想要存储的key是正常的key,我们可以使用如下配置类,当前配置类不是必须的,因为 Spring Boot 框架会自动装配 RedisTemplate 对象。

配置类:

package com.itheima.config;

import org.springframework.cache.annotation.CachingConfigurerSupport;
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;

/**
 * Redis配置类
 */
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
    /*
        1.RedisConnectionFactory 是获取RedisConnection对象的,RedisConnection相当于jdbc中的连接对象Connection表示和
            Redis进行连接
     */
    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        //创建Redis模板对象
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        //默认的Key序列化器为:JdkSerializationRedisSerializer
        //StringRedisSerializer支持字符串类型的转化,而且默认使用UTF-8编码
        //下面代码的意思是使用StringRedisSerializer序列化器替换默认的Key序列化器JdkSerializationRedisSerializer
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());

        redisTemplate.setConnectionFactory(connectionFactory);
        return redisTemplate;
    }

}
4.3.2.3 操作哈希类型数据

需求:

1.存储几个哈希类型的数据

2.获取哈希类型的数据

3.根据键获取哈希类型中的所有字段

4.获得hash结构中的所有值

/**
 * 操作Hash类型数据
*/
@Test
public void testHash(){
       //获取操作Hash类型的接口对象
        HashOperations hashOperations = redisTemplate.opsForHash();
        //存值 下面的代码相当于命令:hset person name xiaoming
        //pseron表示键,name表示字段名  xiaoming表示字段值
        hashOperations.put("person","name","xiaoming");
        hashOperations.put("person","age","20");
        hashOperations.put("person","address","bj");

        //取值
        //下面的代码相当于执行命令:hget 键 字段===》hget person age===>表示根据键和字段名获取字段值
        String age = (String) hashOperations.get("person", "age");
        System.out.println(age);
        //获得hash结构中的所有字段
        //下面的代码相当于执行命令:HKEYS 键===》HKEYS person
        Set keys = hashOperations.keys("person");
        for (Object key : keys) {
            System.out.println(key);
        }

        //获得hash结构中的所有值
        //HVALS 键
        List values = hashOperations.values("person");
        for (Object value : values) {
            System.out.println(value);
        }
}
4.3.2.4 操作列表类型数据

需求:

1.向列表中添加数据

2.查询列表中所有数据

/**
 * 操作List类型的数据
*/
@Test
public void testList(){
       //获取操作列表类型的接口对象
        ListOperations listOperations = redisTemplate.opsForList();

        //存值
        //命令lpush 键 元素 元素...
        listOperations.leftPush("mylist","a");
        listOperations.leftPushAll("mylist","b","c","d");

        //取值
        //命令:lrange 键 开始 结束
        //下面的代码是查询所有
        List<String> mylist = listOperations.range("mylist", 0, -1);
        for (String value : mylist) {
            System.out.println(value);
        }

        //获得列表长度 命令:llen 键
        Long size = listOperations.size("mylist");
        for (int i = 0; i < size; i++) {
            //出队列
            //命令:rpop 键
            //从右边删除一个元素,返回被删除的元素
            String element = (String) listOperations.rightPop("mylist");
            System.out.println(element);
        }
}
4.3.2.5 操作set集合类型数据

需求:

1.向set集合中添加数据

2.获取指定set集合的所有的元素

3.删除指定set集合的数据

/**
 * 操作Set类型的数据
*/
@Test
public void testSet(){
        //获取操作set类型的接口对象
        SetOperations setOperations = redisTemplate.opsForSet();

        //存值
        //sadd 键 元素 元素...
        setOperations.add("myset","a","b","c","a");

        //取值
        //smembers 键 : 得到这个集合中所有的元素
        Set<String> myset = setOperations.members("myset");
        for (String o : myset) {
            System.out.println(o);
        }

        //删除成员
        //srem 键 元素 元素...
        setOperations.remove("myset","a","b");

        //取值
        myset = setOperations.members("myset");
        for (String o : myset) {
            System.out.println(o);
        }

}
4.3.2.6 操作有序集合类型数据

需求:

1.向zset中添加数据

2.从zset中取出数据

3.对某个值的分数进行加20

4.删除数据

/**
 * 操作ZSet类型的数据
*/
@Test
public void testZset(){
        //获取操作zSet类型的接口对象
        ZSetOperations zSetOperations = redisTemplate.opsForZSet();

        //存值
        //Boolean add(K var1, V var2, double var3)  var1 表示键  var2 表示值   var3表示分数
        zSetOperations.add("myZset","a",10.0);//myZset 表示键  a 表示值   10.0 表示分数
        zSetOperations.add("myZset","b",11.0);
        zSetOperations.add("myZset","c",12.0);
        zSetOperations.add("myZset","a",13.0);

        //取值
        //命令:zrange 键 开始索引 结束索引
        //获取指定范围的元素,得到所有的元素,索引是0到-1
        Set<String> myZset = zSetOperations.range("myZset", 0, -1);
        for (String s : myZset) {
            System.out.println(s);
        }
        //修改分数
        //下面的方法表示在原来分数上进行加20
        zSetOperations.incrementScore("myZset","c",20.0);

        //删除成员
        zSetOperations.remove("myZset","a","b");

        //取值
         Set<ZSetOperations.TypedTuple> myZset = zSetOperations.rangeWithScores("myZset", 0, -1);
        for (ZSetOperations.TypedTuple typedTuple : myZset) {
            Double score = typedTuple.getScore();
            Object value = typedTuple.getValue();
            System.out.println(score+"---"+value);
        }
}
4.3.2.7 通用操作

需求:

1.获取Redis中所有的key

2.判断某个key是否存在

3.删除指定key

4.获取指定key对应的value的数据类型

/**
 * 通用操作,针对不同的数据类型都可以操作
*/
@Test
public void testCommon(){
       //获取Redis中所有的key
        Set<String> keys = redisTemplate.keys("*");
        for (String key : keys) {
            System.out.println(key);
        }

        //判断某个key是否存在
        Boolean itcast = redisTemplate.hasKey("itcast");
        System.out.println(itcast);

        //删除指定key
        redisTemplate.delete("myZset");

        //获取指定key对应的value的数据类型
        DataType dataType = redisTemplate.type("myset");
        System.out.println(dataType.name());

}
4.3.2.8 整合连接池(能够理解连接池参数即可)

关于redis连接池并没有什么效果,配置好之后会优化获取连接性能。

pom引入依赖:

<!-- redis创建连接池,默认不会创建连接池 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

配置连接池:

# 配置redis环境
spring:
  redis:
    # 默认连接本地localhost,如果仅仅连接本地redis服务,则可不写
    host: 192.168.200.128
    # 默认端口是6379,则省略不写
    port: 6379
    # redis实例中分为16分片库,索引位从0~15,默认操纵的是0
    database: 0
    lettuce:
      pool:
        max-active: 8 # 连接池最大连接数(使用负值表示没有限制)
        max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
        max-idle: 8 # 连接池中的最大空闲连接
        min-idle: 1  # 连接池中的最小空闲连接

网站公告

今日签到

点亮在社区的每一天
去签到