REDIS学习总结(二)Java操作redis集群

REDIS学习总结(二)Java操作redis集群
REDIS学习总结(一)单机集群搭建

一、操作方式概述
  方法一、Jedis操作
  方式二、RedisTemplate操作
  Jedis是Redis官方推荐的面向Java的操作Redis的客户端,而RedisTemplate是SpringDataRedis中对JedisApi的高度封装。SpringDataRedis相对于Jedis来说可以方便地更换Redis的Java客户端,比Jedis多了自动管理连接池的特性,方便与其他Spring框架进行搭配使用如:SpringCache
二、代码实例
  1.IDEA下创建工程的目录结构
  
  2.各配置文件及类文件
     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.1.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.jupiter.redis.test</groupId>
    <artifactId>redis-learn</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>redis-learn</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.54</version>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>3.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </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.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

     RedisConfig.java

package com.jupiter.redis.commons;

import com.alibaba.fastjson.parser.ParserConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;

import java.time.Duration;
import java.util.HashSet;
import java.util.Set;

/*
 * @author Jupiter
 * @date 2019/1/20-23:41
 * @description redis配置
 */
@Component
@PropertySource("classpath:redis.properties")
public class RedisConfig {

    @Value("${spring.redis.cluster.nodes}")
    private String clusterNodes;
    @Value("${redis.cache.timeout}")
    private int timeout;
    @Value("${redis.pool.max-idle}")
    private int maxIdle;
    @Value("${redis.pool.max-wait}")
    private long maxWaitMillis;
    @Value("${redis.cache.commandTimeout}")
    private int commandTimeout;

    @Bean
    public RedisSerializer fastJson2JsonRedisSerializer(){
        ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
        return new FastJson2RedisJsonSerializer<Object>(Object.class);
    }

    @Bean
    public JedisCluster getJedisCluster() {
        String[] cNodes = clusterNodes.split(",");
        Set<HostAndPort> nodes =new HashSet<>();
        //分割出集群节点
        for(String node : cNodes) {
            String[] hp = node.split(":");
            nodes.add(new HostAndPort(hp[0], Integer.parseInt(hp[1])));
        }
        JedisPoolConfig jedisPoolConfig =new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(maxIdle);
        jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
        //创建集群对象
        return new JedisCluster(nodes,timeout,jedisPoolConfig);
    }

    @Bean
    public RedisTemplate<Object,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
        RedisTemplate<Object,Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        //使用fastjson做序列化
        FastJson2RedisJsonSerializer fastJson2RedisJsonSerializer = new FastJson2RedisJsonSerializer(Object.class);
        redisTemplate.setValueSerializer(fastJson2RedisJsonSerializer);
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    public RedisConnectionFactory connectionFactory() {
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxIdle(maxIdle);
        poolConfig.setTestOnBorrow(true);
        poolConfig.setTestOnReturn(false);
        poolConfig.setTestWhileIdle(true);
        JedisClientConfiguration clientConfig = JedisClientConfiguration.builder()
                .usePooling().poolConfig(poolConfig).and().readTimeout(Duration.ofMillis(timeout)).build();

        // 集群redis
        RedisClusterConfiguration redisConfig = new RedisClusterConfiguration();
        String[] cNodes = clusterNodes.split(",");
        Set<RedisNode> nodes =new HashSet<>();
        //分割出集群节点
        for(String node : cNodes) {
            String[] hp = node.split(":");
            nodes.add(new RedisNode(hp[0], Integer.parseInt(hp[1])));
        }
        redisConfig.setClusterNodes(nodes);
        //redisConfig.setPassword(RedisPassword.of(redisAuth));

        return new JedisConnectionFactory(redisConfig, clientConfig);
    }
}

     FastJson2RedisJsonSerializer.java

package com.jupiter.redis.commons;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;

import java.nio.charset.Charset;

/*
 * @author Jupiter
 * @date 2019/1/20-22:57
 * @description 使用FastJson序列化(redisTemplate序列化默认使用的jdkSerializeable,存储二进制字节码,导致key会出现乱码,所以自定义)
 */
public class FastJson2RedisJsonSerializer<T> implements RedisSerializer<T> {

    private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");

    private Class<T> clazz;

    public FastJson2RedisJsonSerializer(Class<T> clazz) {
        this.clazz = clazz;
    }

    @Override
    public byte[] serialize(T t) throws SerializationException {
        if (t == null)
            return new byte[0];
        return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
    }

    @Override
    public T deserialize(byte[] bytes) throws SerializationException {
        if (bytes == null || bytes.length <= 0) {
            return  null;
        }
        String str = new String(bytes, DEFAULT_CHARSET);
        return (T) JSON.parseObject(str, clazz);
    }
}

     RedisLearnApplication.java

package com.jupiter.redis;

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

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

     redis.properties

# Redis服务器连接密码(默认为空)
redis.password=
# 连接池最大连接数(使用负值表示没有限制)
redis.pool.max-active=8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
redis.pool.max-wait=-1
# 连接池中的最大空闲连接
redis.pool.max-idle=8
# 连接池中的最小空闲连接
redis.pool.min-idle=0
# 连接超时时间(毫秒)
redis.cache.timeout=0
redis.cache.commandTimeout=5000

# redis.cluster
spring.redis.cluster.nodes=192.168.31.132:27001,192.168.31.132:27002,192.168.31.132:27003,192.168.31.132:27004,192.168.31.132:27005,192.168.31.132:27006,192.168.31.132:27007,192.168.31.132:27008

  RedisLearnApplicationTests.java测试类

package com.jupiter.redis;

import com.jupiter.redis.commons.RedisConfig;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
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.StringRedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.SortingParams;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisLearnApplicationTests {

    @Resource
    private RedisConfig redis;

    private JedisCluster jedis;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    public StringRedisTemplate stringRedisTemplate;

    //private JedisClusterConnection jedisClusterConnection;

    @Before
    public void getJedis() {
        this.jedis =  redis.getJedisCluster();

        //拿到RedisConnectionFactory
//        RedisConnectionFactory factory = redis.connectionFactory();
//        this.redisTemplate = redis.redisTemplate();
    }


    @Test
    public void testRedisConfig(){
        jedis.setex("sex", 13, "man");
        System.out.println(jedis.get("sex"));
    }

    @Test
    public void testRedisBasicOperation(){
        JedisCluster jedis = redis.getJedisCluster();

    }

    @Test
    public void testKey() throws InterruptedException {

        jedis.del("age");
        jedis.del("username");
        jedis.del("sortedList");
        jedis.del("password");
        jedis.del("collections");
        jedis.del("name");
        System.out.println("判断某个键是否存在:"+jedis.exists("username"));
        System.out.println("新增<'username','wukong'>的键值对:"+jedis.set("username", "wukong"));
        System.out.println("是否存在:"+jedis.exists("name"));
        System.out.println("新增<'password','password'>的键值对:"+jedis.set("password", "password"));
        Set<String> keys = redisTemplate.keys("*");//jedis单节点可以
        System.out.println("系统中所有的键如下:"+keys);
        System.out.println("删除键password:"+jedis.del("password"));
        System.out.println("判断键password是否存在:"+jedis.exists("password"));
        System.out.println("设置键username的过期时间为5s:"+jedis.expire("username", 5));
        TimeUnit.SECONDS.sleep(2);
        System.out.println("查看键username的剩余生存时间:"+jedis.ttl("username"));
        System.out.println("移除键username的生存时间:"+jedis.persist("username"));
        System.out.println("查看键username的剩余生存时间:"+jedis.ttl("username"));
        System.out.println("查看键username所存储的值的类型:"+jedis.type("username"));
    }

    /***
     * 字符串操作
     * memcached和redis同样有append的操作,但是memcached有prepend的操作,redis中并没有。
     */
    @Test
    public void testString() throws InterruptedException {
        System.out.println("===========增加数据===========");
        System.out.println(jedis.set("key1","value1"));
        System.out.println(jedis.set("key2","value2"));
        System.out.println(jedis.set("key3", "value3"));
        System.out.println("删除键key2:"+jedis.del("key2"));
        System.out.println("获取键key2:"+jedis.get("key2"));
        System.out.println("修改key1:"+jedis.set("key1", "value1Changed"));
        System.out.println("获取key1的值:"+jedis.get("key1"));
        System.out.println("在key3后面加入值:"+jedis.append("key3", "End"));
        System.out.println("key3的值:"+jedis.get("key3"));
        Map<String, String> maps = new HashMap<>();
        maps.put("key01", "value01");
        maps.put("key02", "value02");
        maps.put("key03", "value03");
        redisTemplate.opsForValue().multiSet(maps);
        System.out.println("获取键值对:"+jedis.get("key01"));
        System.out.println("增加多个键值对成功");
//        System.out.println("增加多个键值对:"+jedis.mset("key01","value01","key02","value02","key03","value03"));
//        System.out.println("获取多个键值对:"+jedis.mget("key01","key02","key03"));
//        System.out.println("获取多个键值对:"+jedis.mget("key01","key02","key03","key04"));
//        System.out.println("删除多个键值对:"+jedis.del(new String[]{"key01","key02"}));
//        System.out.println("获取多个键值对:"+jedis.mget("key01","key02","key03"));

        System.out.println("===========新增键值对防止覆盖原先值==============");
        System.out.println(jedis.setnx("key1", "value1"));
        System.out.println(jedis.setnx("key2", "value2"));
        System.out.println(jedis.setnx("key2", "value2-new"));
        System.out.println(jedis.get("key1"));
        System.out.println(jedis.get("key2"));

        System.out.println("===========新增键值对并设置有效时间=============");
        System.out.println(jedis.setex("key3", 2, "value3"));
        System.out.println(jedis.get("key3"));
        TimeUnit.SECONDS.sleep(3);
        System.out.println(jedis.get("key3"));

        System.out.println("===========获取原值,更新为新值==========");//GETSET is an atomic set this value and return the old value command.
        System.out.println(jedis.getSet("key2", "key2GetSet"));
        System.out.println(jedis.get("key2"));

        System.out.println("获得key2的值的字串:"+jedis.getrange("key2", 2, 4));
    }

    /***
     * 整数和浮点数
     */
    @Test
    public void testNumber() {
        jedis.set("key1", "1");
        jedis.set("key2", "2");
        jedis.set("key3", "2.3");
        System.out.println("key1的值:"+jedis.get("key1"));
        System.out.println("key2的值:"+jedis.get("key2"));
        System.out.println("key1的值加1:"+jedis.incr("key1"));
        System.out.println("获取key1的值:"+jedis.get("key1"));
        System.out.println("key2的值减1:"+jedis.decr("key2"));
        System.out.println("获取key2的值:"+jedis.get("key2"));
        System.out.println("将key1的值加上整数5:"+jedis.incrBy("key1", 5));
        System.out.println("获取key1的值:"+jedis.get("key1"));
        System.out.println("将key2的值减去整数5:"+jedis.decrBy("key2", 5));
        System.out.println("获取key2的值:"+jedis.get("key2"));
    }

    /***
     * 列表
     */
    @Test
    public void testList() {
        System.out.println("===========添加一个list===========");
        //从左到右依次先放
        jedis.lpush("collections", "ArrayList", "Vector", "Stack", "HashMap", "WeakHashMap", "LinkedHashMap");
        jedis.lpush("collections", "HashSet");
        jedis.lpush("collections", "TreeSet");
        jedis.lpush("collections", "TreeMap");
        System.out.println("collections的内容:"+jedis.lrange("collections", 0, -1));//-1代表倒数第一个元素,-2代表倒数第二个元素
        System.out.println("collections区间0-3的元素:"+jedis.lrange("collections",0,3));
        System.out.println("===============================");
        // 删除列表指定的值 ,第二个参数为删除的个数(有重复时),后add进去的值先被删,类似于出栈
        System.out.println("删除指定元素个数:"+jedis.lrem("collections", 2, "HashMap"));
        System.out.println("collections的内容:"+jedis.lrange("collections", 0, -1));
        System.out.println("删除下表0-3区间之外的元素:"+jedis.ltrim("collections", 0, 3));
        System.out.println("collections的内容:"+jedis.lrange("collections", 0, -1));
        System.out.println("collections列表出栈(左端):"+jedis.lpop("collections"));
        System.out.println("collections的内容:"+jedis.lrange("collections", 0, -1));
        System.out.println("collections添加元素,从列表右端,与lpush相对应:"+jedis.rpush("collections", "EnumMap"));
        System.out.println("collections的内容:"+jedis.lrange("collections", 0, -1));
        System.out.println("collections列表出栈(右端):"+jedis.rpop("collections"));
        System.out.println("collections的内容:"+jedis.lrange("collections", 0, -1));
        System.out.println("修改collections指定下标1的内容:"+jedis.lset("collections", 1, "LinkedArrayList"));
        System.out.println("collections的内容:"+jedis.lrange("collections", 0, -1));
        System.out.println("===============================");
        System.out.println("collections的长度:"+jedis.llen("collections"));
        System.out.println("获取collections下标为2的元素:"+jedis.lindex("collections", 2));
        System.out.println("===============================");
        jedis.lpush("sortedList", "3","6","2","0","7","4");
        System.out.println("sortedList排序前:"+jedis.lrange("sortedList", 0, -1));
        System.out.println(jedis.sort("sortedList"));
        //排序前排序后一样,要想输出排好序的List,用jedis.sort("sortedList")即可
        System.out.println("sortedList排序后:"+jedis.lrange("sortedList", 0, -1));
    }



    /***
     * set集合
     */
    @Test
    public void testSet() {
        System.out.println("============向集合中添加元素============");
        System.out.println(jedis.sadd("eleSet", "e1","e2","e4","e3","e0","e8","e7","e5"));
        System.out.println(jedis.sadd("eleSet", "e6"));
        System.out.println(jedis.sadd("eleSet", "e6"));//集合元素唯一性
        System.out.println("eleSet的所有元素为:"+jedis.smembers("eleSet"));
        System.out.println("删除一个元素e0:"+jedis.srem("eleSet", "e0"));
        System.out.println("eleSet的所有元素为:"+jedis.smembers("eleSet"));
        System.out.println("删除两个元素e7和e6:"+jedis.srem("eleSet", "e7","e6"));
        System.out.println("eleSet的所有元素为:"+jedis.smembers("eleSet"));
        System.out.println("随机的移除集合中的一个元素:"+jedis.spop("eleSet"));
        System.out.println("随机的移除集合中的一个元素:"+jedis.spop("eleSet"));
        System.out.println("eleSet的所有元素为:"+jedis.smembers("eleSet"));
        System.out.println("eleSet中包含元素的个数:"+jedis.scard("eleSet"));
        System.out.println("e3是否在eleSet中:"+jedis.sismember("eleSet", "e3"));
        System.out.println("e1是否在eleSet中:"+jedis.sismember("eleSet", "e1"));
        System.out.println("e1是否在eleSet中:"+jedis.sismember("eleSet", "e5"));
        System.out.println("=================================");
        System.out.println(jedis.sadd("eleSet1", "e1","e2","e4","e3","e0","e8","e7","e5"));
        System.out.println(jedis.sadd("eleSet2", "e1","e2","e4","e3","e0","e8"));
        //redisTemplate不会创建新的SET集合,而jedis操作集群有报错No way to dispatch this command to Redis Cluster because keys have different slots.
        //解决方法, redis集群下的multiCommands:https://www.cnblogs.com/Finley/p/8595506.html
//        System.out.println("将eleSet1中删除e1并存入eleSet3中:"+redisTemplate.opsForSet().move("eleSet1", "e1", "eleSet3"));
//        System.out.println("将eleSet1中删除e1并存入eleSet3中:"+jedis.smove("eleSet1", "eleSet3", "e1"));
//        System.out.println("将eleSet1中删除e7并存入eleSet2中:"+redisTemplate.opsForSet().move("eleSet1", "e7", "eleSet2"));
//        System.out.println("将eleSet1中删除e2并存入eleSet3中:"+jedis.smove("eleSet1", "eleSet3", "e2"));
//        System.out.println("eleSet1中的元素:"+jedis.smembers("eleSet1"));
//        System.out.println("eleSet3中的元素:"+jedis.smembers("eleSet3"));
//        System.out.println("============集合运算=================");
//        System.out.println("eleSet1中的元素:"+jedis.smembers("eleSet1"));
//        System.out.println("eleSet2中的元素:"+jedis.smembers("eleSet2"));
//        System.out.println("eleSet1和eleSet2的交集:"+jedis.sinter("eleSet1","eleSet2"));
//        System.out.println("eleSet1和eleSet2的并集:"+jedis.sunion("eleSet1","eleSet2"));
//        System.out.println("eleSet1和eleSet2的差集:"+jedis.sdiff("eleSet1","eleSet2"));//eleSet1中有,eleSet2中没有
    }

    @Test
    public void setMove(){
        System.out.println("eleSet1中是否含有e7元素:"+stringRedisTemplate.opsForSet().members("{eleSet}1"));
        System.out.println("eleSet1中是否含有e7元素:"+redisTemplate.opsForSet().members("{eleSet}1"));
        System.out.println("将eleSet1中删除e7并存入eleSet2中:"+redisTemplate.opsForSet().move("{eleSet}1", "e7", "{eleSet}2"));
    }

    /***
     * 加入HashTag后的set集合(redis 集群下的相关操作)
     */
    @Test
    public void testHashTagSet() {
        System.out.println("============向集合中添加元素============");
        System.out.println(jedis.sadd("{eleSet}", "e1","e2","e4","e3","e0","e8","e7","e5"));
        System.out.println(jedis.sadd("{eleSet}", "e6"));
        System.out.println(jedis.sadd("{eleSet}", "e6"));//集合元素唯一性
        System.out.println("eleSet的所有元素为:"+jedis.smembers("{eleSet}"));
        System.out.println("删除一个元素e0:"+jedis.srem("{eleSet}", "e0"));
        System.out.println("eleSet的所有元素为:"+jedis.smembers("{eleSet}"));
        System.out.println("删除两个元素e7和e6:"+jedis.srem("{eleSet}", "e7","e6"));
        System.out.println("eleSet的所有元素为:"+jedis.smembers("{eleSet}"));
        System.out.println("随机的移除集合中的一个元素:"+jedis.spop("{eleSet}"));
        System.out.println("随机的移除集合中的一个元素:"+jedis.spop("{eleSet}"));
        System.out.println("eleSet的所有元素为:"+jedis.smembers("{eleSet}"));
        System.out.println("eleSet中包含元素的个数:"+jedis.scard("{eleSet}"));
        System.out.println("e3是否在eleSet中:"+jedis.sismember("{eleSet}", "e3"));
        System.out.println("e1是否在eleSet中:"+jedis.sismember("{eleSet}", "e1"));
        System.out.println("e1是否在eleSet中:"+jedis.sismember("{eleSet}", "e5"));
        System.out.println("=================================");
        System.out.println(jedis.sadd("{eleSet}1", "e1","e2","e4","e3","e0","e8","e7","e5"));
        System.out.println(jedis.sadd("{eleSet}2", "e1","e2","e4","e3","e0","e8"));
        //jedis操作集群有报错No way to dispatch this command to Redis Cluster because keys have different slots.
        //解决方法, redis集群下的multiCommands:https://www.cnblogs.com/Finley/p/8595506.html
        System.out.println("将eleSet1中删除e1并存入eleSet3中:"+redisTemplate.opsForSet().move("{eleSet}1", "e1", "{eleSet}3"));
        System.out.println("将eleSet1中删除e1并存入eleSet3中:"+jedis.smove("{eleSet}1", "{eleSet}3", "e1"));
        System.out.println("将eleSet1中删除e7并存入eleSet2中:"+redisTemplate.opsForSet().move("{eleSet}1", "e7", "{eleSet}2"));
        System.out.println("将eleSet1中删除e2并存入eleSet3中:"+jedis.smove("{eleSet}1", "{eleSet}3", "e2"));
        System.out.println("eleSet1中的元素:"+jedis.smembers("{eleSet}1"));
        System.out.println("eleSet3中的元素:"+jedis.smembers("{eleSet}3"));
        System.out.println("============集合运算=================");
        System.out.println("eleSet1中的元素:"+jedis.smembers("{eleSet}1"));
        System.out.println("eleSet2中的元素:"+jedis.smembers("{eleSet}2"));
        System.out.println("eleSet1和eleSet2的交集:"+jedis.sinter("{eleSet}1","{eleSet}2"));
        System.out.println("eleSet1和eleSet2的并集:"+jedis.sunion("{eleSet}1","{eleSet}2"));
        System.out.println("eleSet1和eleSet2的差集:"+jedis.sdiff("{eleSet}1","{eleSet}2"));//eleSet1中有,eleSet2中没有
    }

    /***
     * 散列
     */
    @Test
    public void testHash() {
        Map<String,String> map = new HashMap<String,String>();
        map.put("key1","value1");
        map.put("key2","value2");
        map.put("key3","value3");
        map.put("key4","value4");
        jedis.hmset("hash",map);
        jedis.hset("hash", "key5", "value5");
        System.out.println("散列hash的所有键值对为:"+jedis.hgetAll("hash"));//return Map<String,String>
        System.out.println("散列hash的所有键为:"+jedis.hkeys("hash"));//return Set<String>
        System.out.println("散列hash的所有值为:"+jedis.hvals("hash"));//return List<String>
        System.out.println("将key6保存的值加上一个整数,如果key6不存在则添加key6:"+jedis.hincrBy("hash", "key6", 6));
        System.out.println("散列hash的所有键值对为:"+jedis.hgetAll("hash"));
        System.out.println("将key6保存的值加上一个整数,如果key6不存在则添加key6:"+jedis.hincrBy("hash", "key6", 3));
        System.out.println("散列hash的所有键值对为:"+jedis.hgetAll("hash"));
        System.out.println("删除一个或者多个键值对:"+jedis.hdel("hash", "key2"));
        System.out.println("散列hash的所有键值对为:"+jedis.hgetAll("hash"));
        System.out.println("散列hash中键值对的个数:"+jedis.hlen("hash"));
        System.out.println("判断hash中是否存在key2:"+jedis.hexists("hash","key2"));
        System.out.println("判断hash中是否存在key3:"+jedis.hexists("hash","key3"));
        System.out.println("获取hash中的值:"+jedis.hmget("hash","key3"));
        System.out.println("获取hash中的值:"+jedis.hmget("hash","key3","key4"));
    }

    /**
     * 有序集合
     */
    @Test
    public void testSortedSet() {
        Map<String,Double> map = new HashMap<String,Double>();
        map.put("key2",1.2);
        map.put("key3",4.0);
        map.put("key4",5.0);
        map.put("key5",0.2);
        System.out.println(jedis.zadd("zset", 3,"key1"));
        System.out.println(jedis.zadd("zset",map));
        System.out.println("zset中的所有元素:"+jedis.zrange("zset", 0, -1));
        System.out.println("zset中的所有元素:"+jedis.zrangeWithScores("zset", 0, -1));
        System.out.println("zset中的所有元素:"+jedis.zrangeByScore("zset", 0,100));
        System.out.println("zset中的所有元素:"+jedis.zrangeByScoreWithScores("zset", 0,100));
        System.out.println("zset中key2的分值:"+jedis.zscore("zset", "key2"));
        System.out.println("zset中key2的排名:"+jedis.zrank("zset", "key2"));
        System.out.println("删除zset中的元素key3:"+jedis.zrem("zset", "key3"));
        System.out.println("zset中的所有元素:"+jedis.zrange("zset", 0, -1));
        System.out.println("zset中元素的个数:"+jedis.zcard("zset"));
        System.out.println("zset中分值在1-4之间的元素的个数:"+jedis.zcount("zset", 1, 4));
        System.out.println("key2的分值加上5:"+jedis.zincrby("zset", 5, "key2"));
        System.out.println("key3的分值加上4:"+jedis.zincrby("zset", 4, "key3"));
        System.out.println("zset中的所有元素:"+jedis.zrange("zset", 0, -1));
    }

    /**
     * 排序
     */
    @Test
    public void testSort()
    {
        jedis.lpush("collections", "ArrayList", "Vector", "Stack", "HashMap", "WeakHashMap", "LinkedHashMap");
        System.out.println("collections的内容:"+jedis.lrange("collections", 0, -1));
        SortingParams sortedParameters = new SortingParams();
        System.out.println(jedis.sort("collections",sortedParameters.alpha()));
        System.out.println("===============================");
        jedis.lpush("sortedList", "3","6","2","0","7","4");
        System.out.println("sortedList排序前:"+jedis.lrange("sortedList", 0, -1));
        System.out.println("升序:"+jedis.sort("sortedList", sortedParameters.asc()));
        System.out.println("降序:"+jedis.sort("sortedList", sortedParameters.desc()));
    }
}

  3.更多SpringBoot操作REDIS的文章推荐:
    链接:springboot之使用redistemplate优雅地操作redis
    链接:使用RedisTemplate访问Redis数据结构API大全
三、实践遇到的问题
  问题一:错误TypeMismatchException: Failed to convert property value of type [java.lang原因与解决
    原因:配置文件并没有被spring容器加载到,所以导致这样的错误
    解决:
      链接:TypeMismatchException: Failed to convert property value of type [java.lang解决与原因
      链接:Springboot导入自定义properties配置文件 和 SpringBoot自定义配置文件(xxx.properties)
      链接:SpringBoot四种读取properties文件的方式
  问题二:redis.clients.jedis.exceptions.JedisClusterOperationException: No way to dispatch this command to Redis Cluster because keys have different slots.
    原因:哈希槽(hash slot)是Redis Cluster的概念,哈希槽是一个key的集合,Redis集群共有16384个哈希槽,每个key通过CRC16散列然后对16384进行取模来决定该key应当被放到哪个槽中,集群中的每个节点负责一部分哈希槽。这里需要注意的是需要组成并集的各个集合的key必须是对应到redis集群中的同一个slot上,否则将会出现异常:No way to dispatch this command to Redis Cluster because keys have different slots或者CROSSSLOT Keys in request don’t hash to the same slot。所以redis提供了一种特定的标签{},这个{}内的字符串才参与计算hash slot.例如:{user}:aaa与{user}:bbb 这两个集合可以确保在同一个slot上,可以使用zunionstore求它们的并集。如果是在redis集群环境下,需要特别注意。
    解决:
      在操作redis集群之前先想好后期是否会涉及对集群中存的数据进行批操作,如果只是做缓存,单个K-V存取可以不考虑key在一个hash slot中,这样也有利于数据均匀散列到不通的槽中。
      链接:Redis集群
      链接:zunionstore异常:CROSSSLOT Keys in request don't hash to the same slot
  问题三:redisTemplate.opsForSet().members 反序列化失败
    原因:StringRedisTemplate与RedisTemplate区别点:两者的关系是StringRedisTemplate继承RedisTemplate。两者的数据是不共通的;也就是说StringRedisTemplate只能管理StringRedisTemplate里面的数据,RedisTemplate只能管理RedisTemplate中的数据。两者之间的区别主要在于他们使用的序列化类:RedisTemplate使用的是JdkSerializationRedisSerializer:存入数据会将数据先序列化成字节数组然后在存入Redis数据库。 StringRedisTemplate使用的是StringRedisSerializer
    解决:
       当你的redis数据库里面本来存的是字符串数据或者你要存取的数据就是字符串类型数据的时候,那么你就使用StringRedisTemplate即可。
       但是如果你的数据是复杂的对象类型,而取出的时候又不想做任何的数据转换,直接从Redis里面取出一个对象,那么使用RedisTemplate是更好的选择。

      链接:StringRedisTemplate操作redis数据
  问题四:Redis报错:WRONGTYPE Operation against a key holding the wrong kind of value
    原因:jedis方法与redis服务器中存储数据的类型存在冲突。例如:数据库中有一个key的数据存储的是Hash类型的,但是你使用jedis执行数据操作的时候却使用了非Hash的操作方法。
    解决:
     链接: Redis报错:WRONGTYPE Operation against a key holding the wrong kind of value 解决处理
    
四、参考文献
  1.redis学习系列(二)--spring boot整合Redis集群
  2.Spring Boot学习之旅:(六)springboot 整合 redis 以及 redis 通用工具类
  3.IntelliJ IDEA lombok插件的安装和使用
  4.Caused by: java.lang.NoClassDefFoundError: redis/clients/util/Pool
  5.JedisCluster模式尝试进行批量操作
  6.springboot配置文件代码提示
  7.Redis: Jedis和RedisTemplate有何区别?
  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值