spring boot(三)整合 redis

_否極泰來發表於2021-11-23

Spring boot 整合redis

為什麼要用redis,它解決了什麼問題?

Redis 是一個高效能的key-value記憶體資料庫。它支援常用的5種資料結構:String字串、Hash雜湊表、List列表、Set集合、Zset有序集合 等資料型別。
Redis它解決了2個問題:
第一個是:效能
通常資料庫的讀操作,一般都要幾十毫秒,而redisd的讀操作一般僅需不到1毫秒。通常只要把資料庫的資料快取進redis,就能得到幾十倍甚至上百倍的效能提升。
第二個是:併發
在大併發的情況下,所有的請求直接訪問資料庫,資料庫會出現連線異常,甚至卡死在資料庫中。為了解決大併發卡死的問題,一般的做法是採用redis做一個緩衝操作,讓請求先訪問到redis,而不是直接訪問資料庫。

一、新增maven依賴

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

二、配置檔案

#埠
server.port=9998


## Redis 配置
## Redis資料庫索引(預設為0)
spring.redis.database=0
## Redis伺服器地址
spring.redis.host=127.0.0.1
## Redis伺服器連線埠
spring.redis.port=6379
## Redis伺服器連線密碼(預設為空)
spring.redis.password=



### Redis叢集版配置
### 連線池最大連線數(使用負值表示沒有限制)
#spring.redis.lettuce.pool.max-active=8
### 連線池中的最大空閒連線
#spring.redis.lettuce.pool.max-idle=8
### 連線池最大阻塞等待時間(使用負值表示沒有限制)
#spring.redis.lettuce.pool.max-wait=-1ms
### 連線池中的最小空閒連線
#spring.redis.lettuce.pool.min-idle=0
##spring.redis.sentinel.master= # Name of Redis server.
##spring.redis.sentinel.nodes= # Comma-separated list of host:port pairs.
#spring.redis.timeout=1m
#spring.redis.cluster.nodes=81.70.199.73:6381,81.70.199.73:6382

三、設定redis配置,key和value序列化的

@Slf4j
@Configuration
public class RedisConfiguration {
    /**
     * 重寫Redis序列化方式,使用Json方式:
     * 當我們的資料儲存到Redis的時候,我們的鍵(key)和值(value)都是通過Spring提供的Serializer序列化到資料庫的。RedisTemplate預設使用的是JdkSerializationRedisSerializer,StringRedisTemplate預設使用的是StringRedisSerializer。
     * Spring Data JPA為我們提供了下面的Serializer:
     * GenericToStringSerializer、Jackson2JsonRedisSerializer、JacksonJsonRedisSerializer、
     * JdkSerializationRedisSerializer、OxmSerializer、StringRedisSerializer。
     *
     * 在此我們將自己配置RedisTemplate並定義Serializer。
     * @param redisConnectionFactory
     * @return
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        GenericJackson2JsonRedisSerializer jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
//
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.afterPropertiesSet();
        log.info("設定redisTemplate序列化 getKeySerializer:{} getValueSerializer:{}",redisTemplate.getKeySerializer().getClass(),redisTemplate.getValueSerializer().getClass());
        log.info("設定redisTemplate序列化 getHashKeySerializer:{} getHashValueSerializer:{}",redisTemplate.getHashKeySerializer().getClass(),redisTemplate.getHashValueSerializer().getClass());
        return redisTemplate;
    }
}

四、使用RedisTemplate

string

@Slf4j
@Api("redis【string】")
@RestController
@RequestMapping("/redis/string")
public class RedisStringController {

    @Autowired
    RedisTemplate redisTemplate;
    //-----------------redis string start-------------
    @ApiOperation("初始化資料")
    @RequestMapping(value = "/initData",method = RequestMethod.GET)
    public BaseResp string_initData(){
        log.info("string_initData start");
        for (User user : TestDataUtil.getUsers()) {
            log.info("string_initData user:{}",user);
            redisTemplate.opsForValue().set(user.getId().toString(),user);
        }
        log.info("string_initData end");
        return BaseResp.buildSuccess();
    }

    @ApiOperation("get方法")
    @RequestMapping(value = "/get",method = RequestMethod.GET)
    public BaseResp string_get(@RequestParam("strKey")String strKey){
        Object val = redisTemplate.opsForValue().get(strKey);
        return BaseResp.buildDataSuccess(val);
    }

    @ApiOperation("set方法")
    @RequestMapping(value = "/string/set",method = RequestMethod.GET)
    public BaseResp string_set(@RequestParam("strKey")String strKey,@RequestParam("strVal")String strVal){
        redisTemplate.opsForValue().set(strKey,strVal);
        return BaseResp.buildSuccess();
    }
    //-----------------redis string end-------------

}

set

@Slf4j
@Api("redis【set】")
@RestController
@RequestMapping("/redis/set")
public class RedisSetController {

    @Autowired
    RedisTemplate redisTemplate;



    //-----------------redis set start-------------
    String testSetKey = "test_set";
    String testSetKey_1 = "test_set_1";
    String testSetKey_2 = "test_set_2";
    String testSetKey_3 = "test_set_3";

    @ApiOperation("初始化資料")
    @RequestMapping(value = "/initData",method = RequestMethod.GET)
    public BaseResp set_initData(){
        log.info("list_initData start");
        Long resp = redisTemplate.opsForSet().add(testSetKey,TestDataUtil.getUsers().toArray());

        redisTemplate.opsForSet().add(testSetKey_1,"A","B","C");
        redisTemplate.opsForSet().add(testSetKey_2,"A","a","B");
        redisTemplate.opsForSet().add(testSetKey_3,"A");
        log.info("list_initData end resp:{}",resp);
        return BaseResp.buildSuccess();
    }

    @ApiOperation("set-拉取")
    @RequestMapping(value = "/pop",method = RequestMethod.GET)
    public BaseResp<User> set_pop(){
        SetOperations<String, User> setOperations  = redisTemplate.opsForSet();
        User user= setOperations.pop(testSetKey);
        return BaseResp.buildDataSuccess(user);
    }

    @ApiOperation("randomMember 隨機返回一個元素")
    @RequestMapping(value = "/randomMember",method = RequestMethod.GET)
    public BaseResp<User> set_randomMember(){
        SetOperations<String, User> setOperations  = redisTemplate.opsForSet();
        User user= setOperations.randomMember(testSetKey);
        return BaseResp.buildDataSuccess(user);
    }

    @ApiOperation("新增一個元素")
    @RequestMapping(value = "/add",method = RequestMethod.GET)
    public BaseResp<Long> set_add(@RequestParam("setKey")String setKey,@RequestParam("setVal")String setVal){
        SetOperations<String, String> setOperations  = redisTemplate.opsForSet();
        Long resp = setOperations.add(setKey,setVal);
        return BaseResp.buildDataSuccess(resp);
    }

    @ApiOperation("判斷一個元素是否存在")
    @RequestMapping(value = "/isMember",method = RequestMethod.GET)
    public BaseResp<Boolean> set_isMember(@RequestParam("setKey")String setKey,@RequestParam("setVal")String setVal){
        SetOperations<String, User> setOperations  = redisTemplate.opsForSet();
        boolean resp = setOperations.isMember(setKey,setVal);
        return BaseResp.buildDataSuccess(resp);
    }

    @ApiOperation("獲取set的元素數量")
    @RequestMapping(value = "/size",method = RequestMethod.GET)
    public BaseResp list_pop1(@RequestParam("setKey")String setKey){
        SetOperations<String, User> setOperations  = redisTemplate.opsForSet();
        return BaseResp.buildDataSuccess(setOperations.size(setKey));
    }



    @ApiOperation("多個set-差集(取第一個set集合中 在其他set集合沒有出現的元素)")
    @RequestMapping(value = "/difference",method = RequestMethod.GET)
    public BaseResp list_difference(){
        SetOperations<String, String> setOperations  = redisTemplate.opsForSet();
        Set<String> differenceSet = setOperations.difference(Arrays.asList(testSetKey_1,testSetKey_3,testSetKey_2));
        return BaseResp.buildDataSuccess(differenceSet);
    }

    @ApiOperation("多個set-並集")
    @RequestMapping(value = "/union",method = RequestMethod.GET)
    public BaseResp list_union(){
        SetOperations<String, String> setOperations  = redisTemplate.opsForSet();

        Set<String> differenceSet = setOperations.union(Arrays.asList(testSetKey_1,testSetKey_2,testSetKey_3));
        return BaseResp.buildDataSuccess(differenceSet);
    }
    @ApiOperation("多個set-交集")
    @RequestMapping(value = "/intersect",method = RequestMethod.GET)
    public BaseResp list_intersect(){
        SetOperations<String, String> setOperations  = redisTemplate.opsForSet();
        Set<String> differenceSet = setOperations.intersect(Arrays.asList(testSetKey_1,testSetKey_2,testSetKey_3));
        return BaseResp.buildDataSuccess(differenceSet);
    }

    //-----------------redis set end-------------

}

hash

@Slf4j
@Api("redis【hash】")
@RestController
@RequestMapping("/redis/hash")
public class RedisHashController {

    @Autowired
    RedisTemplate redisTemplate;

    String testHashKey = "hash_{}";

    @ApiOperation("初始化資料")
    @RequestMapping(value = "/initData",method = RequestMethod.GET)
    public BaseResp hash_initData(){
        log.info("hash_initData start");
        for (User user : TestDataUtil.getUsers()) {
            log.info("hash_initData user:{}",user);
            redisTemplate.opsForHash().putAll(StrUtil.format(testHashKey,user.getId()),JSONUtil.parseObj(user));
        }
        log.info("hash_initData end");
        return BaseResp.buildSuccess();
    }
    @ApiOperation("put方法")
    @RequestMapping(value = "/put",method = RequestMethod.GET)
    public BaseResp hash_put(@RequestParam("h")String h,@RequestParam("hk")String hk,@RequestParam("hv")String hv){
        redisTemplate.opsForHash().put(h,hk,hv);
        return BaseResp.buildSuccess();
    }
    @ApiOperation("get方法")
    @RequestMapping(value = "/get",method = RequestMethod.GET)
    public BaseResp hash_get(@RequestParam("h")String h,@RequestParam("hk")String hk){
        redisTemplate.opsForHash().get(h,hk);
        return BaseResp.buildSuccess();
    }
    @ApiOperation("increment方法")
    @RequestMapping(value = "/increment",method = RequestMethod.GET)
    public BaseResp hash_increment(@RequestParam("h")String h,@RequestParam("hk")String hk){
        redisTemplate.opsForHash().increment(h,hk,1);
        return BaseResp.buildSuccess();
    }
    @ApiOperation("keys方法")
    @RequestMapping(value = "/keys",method = RequestMethod.GET)
    public BaseResp<Set> hash_keys(@RequestParam("h")String h){
        return BaseResp.buildDataSuccess(redisTemplate.opsForHash().keys(h));
    }

    @ApiOperation("keys方法")
    @RequestMapping(value = "/delete",method = RequestMethod.GET)
    public BaseResp<Long> delete(@RequestParam("h")String h){
        HashOperations hashOperations = redisTemplate.opsForHash();
        Long resp = hashOperations.delete(h);
        return BaseResp.buildDataSuccess(resp);
    }
}

list


@Slf4j
@Api("redis【list】")
@RestController
@RequestMapping("/redis/list")
public class RedisListController {

    @Autowired
    RedisTemplate redisTemplate;

    //-----------------redis list start-------------
    String testListKey = "test_list";

    @ApiOperation("初始化資料")
    @RequestMapping(value = "/initData",method = RequestMethod.GET)
    public BaseResp list_initData(){
        log.info("list_initData start");
        redisTemplate.opsForList().rightPushAll(testListKey,TestDataUtil.getUsers().toArray());
        log.info("list_initData end");
        return BaseResp.buildSuccess();
    }

    @ApiOperation("根據下標 取資料")
    @RequestMapping(value = "/index",method = RequestMethod.GET)
    public BaseResp list_index(@RequestParam("index")Integer index){
        Object user = redisTemplate.opsForList().index(testListKey,index);
        return BaseResp.buildDataSuccess(user);
    }

    @ApiOperation("根據下標 取資料")
    @RequestMapping(value = "/list/range",method = RequestMethod.GET)
    public BaseResp range(@RequestParam("start")Integer start,@RequestParam("end")Integer end){
        Object user = redisTemplate.opsForList().range(testListKey,start,end);
        return BaseResp.buildDataSuccess(user);
    }
    String testListPopKey = "test_list_pop";

    @ApiOperation("list-拉取")
    @RequestMapping(value = "/pop",method = RequestMethod.GET)
    public BaseResp list_pop(){
        Object popResp = redisTemplate.opsForList().leftPop(testListPopKey, Duration.ofMinutes(1));
        log.info("popResp:{}",popResp);
        return BaseResp.buildDataSuccess(popResp);
    }
    @ApiOperation("list-推送")
    @RequestMapping(value = "/pop/leftPush",method = RequestMethod.GET)
    public BaseResp list_pop(@RequestParam("pushVal")String pushVal){
        Long resp = redisTemplate.opsForList().leftPush(testListPopKey,pushVal);
        return BaseResp.buildDataSuccess(resp);
    }
    //-----------------redis list end-------------
}

zset


@Slf4j
@Api("redis【zSet】")
@RestController
@RequestMapping("/redis/zSet")
public class RedisZSetController {

    @Autowired
    RedisTemplate redisTemplate;

    //-----------------redis zset start-------------
    String zSet_test_key = "zSet_test";

    String zSet_test_key_1 = "zSet_test_1";


    @ApiOperation("初始化資料")
    @RequestMapping(value = "/initData",method = RequestMethod.GET)
    public BaseResp zSet_initData(){
        log.info("zSet_initData start");
        ZSetOperations setOperations  = redisTemplate.opsForZSet();
        List<User> users = TestDataUtil.getUsers();
        for (User user : users) {
            setOperations.add(zSet_test_key,user,user.getAge());
        }
        log.info("zSet_initData end");
        return BaseResp.buildSuccess();
    }

    @ApiOperation("【zSet】初始化資料(新增 型別是TypedTuple的set集合)")
    @RequestMapping(value = "/initData_tuples",method = RequestMethod.GET)
    public BaseResp zSet_initData1(){
        log.info("zSet_initData1 start");
        ZSetOperations setOperations  = redisTemplate.opsForZSet();
        List<User> users = TestDataUtil.getUsers();

        Set<ZSetOperations.TypedTuple<User>> tuples = new HashSet<>();
        for (User user : users) {
            tuples.add(ZSetOperations.TypedTuple.of(user,user.getAge().doubleValue()));
        }
        Long resp = setOperations.add(zSet_test_key, tuples);
        log.info("zSet_initData1 end resp:{}",resp);
        return BaseResp.buildSuccess();
    }

    @ApiOperation("【zSet】初始化資料 (value值只存id)")
    @RequestMapping(value = "/initData_value",method = RequestMethod.GET)
    public BaseResp initData_value(){
        log.info("initData_value start");
        ZSetOperations setOperations  = redisTemplate.opsForZSet();
        List<User> users = TestDataUtil.getUsers();
        for (User user : users) {
            setOperations.add(zSet_test_key_1,user.getId(),user.getAge());
        }
        log.info("initData_value end");
        return BaseResp.buildSuccess();
    }

    @ApiOperation("計算有序集合中指定字典區間(minScore -> maxScore)內成員數量。")
    @RequestMapping(value = "/count",method = RequestMethod.GET)
    public BaseResp zSet_count(@RequestParam("minScore")Double minScore,@RequestParam("maxScore")Double maxScore){
        ZSetOperations setOperations  = redisTemplate.opsForZSet();
        Long count =setOperations.count(zSet_test_key_1,minScore,maxScore);
        return BaseResp.buildDataSuccess(count);
    }

    @ApiOperation("有序集合中,元素score原子自增")
    @RequestMapping(value = "/incrementScore",method = RequestMethod.GET)
    public BaseResp incrementScore(@RequestParam("uid")Integer uid,@RequestParam(value = "score",defaultValue = "1")Integer score){
        ZSetOperations setOperations  = redisTemplate.opsForZSet();
        Double count = setOperations.incrementScore(zSet_test_key_1,uid,score);
        return BaseResp.buildDataSuccess(count);
    }
    @ApiOperation("取有序集合中 成員數量")
    @RequestMapping(value = "/count/zCard",method = RequestMethod.GET)
    public BaseResp zCard(){
        ZSetOperations setOperations  = redisTemplate.opsForZSet();
        Long count = setOperations.zCard(zSet_test_key_1);
        return BaseResp.buildDataSuccess(count);
    }

    @ApiOperation("取當前成員所在 集合的排名【升序的排名(按照score從低到高的 排名)】【排名是所在下標 從0開始】")
    @RequestMapping(value = "/get/rank",method = RequestMethod.GET)
    public BaseResp rank(@RequestParam("uid")Integer uid){
        ZSetOperations setOperations  = redisTemplate.opsForZSet();
        Long rank = setOperations.rank(zSet_test_key_1,uid);
        log.info("rank uid:{} rank:{}",uid,rank);
        return BaseResp.buildDataSuccess("所在排名"+(rank+1));
    }


    @ApiOperation("取當前成員所在 集合的排名【降序的排名(按照score從高到低的 排名)】【排名是所在下標 從0開始】")
    @RequestMapping(value = "/get/rank/reverse",method = RequestMethod.GET)
    public BaseResp reverseRank(@RequestParam("uid")Integer uid){
        ZSetOperations setOperations  = redisTemplate.opsForZSet();
        Long reverseRank = setOperations.reverseRank(zSet_test_key_1,uid);
        log.info("rank uid:{} reverseRank:{}",uid,reverseRank);
        return BaseResp.buildDataSuccess("所在排名"+(reverseRank+1));
    }



    @ApiOperation("根據設定的最大和最小的範圍,返回字典排序集合中的元素")
    @RequestMapping(value = "/get/rangeByLex",method = RequestMethod.GET)
    public BaseResp rangeByLex(@RequestParam(value = "minScore",required = true,defaultValue = "0")Double minScore,
                               @RequestParam(value = "maxScore",required = true,defaultValue = "999")Double maxScore){
        ZSetOperations setOperations  = redisTemplate.opsForZSet();
        RedisZSetCommands.Range range = new RedisZSetCommands.Range().gte(minScore).lte(maxScore);
        Set resp = setOperations.rangeByLex(zSet_test_key_1, range);
        log.info("rangeByLex resp:{}",resp);
        return BaseResp.buildDataSuccess(resp);
    }


    @ApiOperation("列表查詢【根據(score)排序,正序返回「value」】- 查詢條件【起始位置 start - 結束位置 end】")
    @RequestMapping(value = "/query/range",method = RequestMethod.GET)
    public BaseResp range(@RequestParam(value = "start",required = false,defaultValue = "0")Long start,@RequestParam(value = "end",required = false,defaultValue = "-1")Long end){
        ZSetOperations setOperations  = redisTemplate.opsForZSet();
        Set resp = setOperations.range(zSet_test_key_1,start,end);
        log.info("reverseRange resp:{}",resp);
        return BaseResp.buildDataSuccess(resp);
    }

    @ApiOperation("列表查詢(根據(score)排序,倒序返回「value」)- 查詢條件【起始位置 start - 結束位置 end】")
    @RequestMapping(value = "/query/range/reverse",method = RequestMethod.GET)
    public BaseResp reverseRange(@RequestParam(value = "start",required = false,defaultValue = "0")Long start,@RequestParam(value = "end",required = false,defaultValue = "-1")Long end){
        ZSetOperations setOperations  = redisTemplate.opsForZSet();
        Set resp = setOperations.reverseRange(zSet_test_key_1,start,end);
        log.info("reverseRange resp:{}",resp);
        return BaseResp.buildDataSuccess(resp);
    }


    @ApiOperation(value = "列表查詢【根據(score)排序,正序返回「value」】- 查詢條件【最小&最高】score")
    @RequestMapping(value = "/query/rangeByScore",method = RequestMethod.GET)
    public BaseResp rangeByScore(@RequestParam(value = "minScore",required = false)Double minScore,@RequestParam(value = "maxScore",required = false)Double maxScore){
        ZSetOperations setOperations  = redisTemplate.opsForZSet();
        minScore = ObjectUtil.defaultIfNull(minScore,Double.MIN_VALUE);
        maxScore = ObjectUtil.defaultIfNull(maxScore,Double.MAX_VALUE);
        Set resp = setOperations.rangeByScore(zSet_test_key_1, minScore,maxScore);
        log.info("rangeByScore resp:{}",resp);
        return BaseResp.buildDataSuccess(resp);
    }

    @ApiOperation(value = "列表查詢(根據(score)排序,倒序返回「value」)-查詢條件【最小&最高】score")
    @RequestMapping(value = "/query/rangeByScore/reverse",method = RequestMethod.GET)
    public BaseResp reverseRangeByScore(@RequestParam(value = "minScore",required = false)Double minScore,@RequestParam(value = "maxScore",required = false)Double maxScore){
        ZSetOperations setOperations  = redisTemplate.opsForZSet();
        minScore = ObjectUtil.defaultIfNull(minScore,Double.MIN_VALUE);
        maxScore = ObjectUtil.defaultIfNull(maxScore,Double.MAX_VALUE);
        Set resp = setOperations.reverseRangeByScore(zSet_test_key_1, minScore,maxScore);
        log.info("reverseRangeByScore resp:{}",resp);
        return BaseResp.buildDataSuccess(resp);
    }


    @ApiOperation("列表查詢(根據(score)排序,正序返回「score & value」 )- 查詢條件【最小&最高】score")
    @RequestMapping(value = "/query/rangeByScoreWithScores",method = RequestMethod.GET)
    public BaseResp rangeByScoreWithScores(@RequestParam(value = "minScore",required = false)Double minScore,@RequestParam(value = "maxScore",required = false)Double maxScore){
        ZSetOperations setOperations  = redisTemplate.opsForZSet();
        minScore = ObjectUtil.defaultIfNull(minScore,Double.MIN_VALUE);
        maxScore = ObjectUtil.defaultIfNull(maxScore,Double.MAX_VALUE);

        Set resp = setOperations.rangeByScoreWithScores(zSet_test_key_1, minScore,maxScore);
        log.info("rangeByScore resp:{}",resp);
        return BaseResp.buildDataSuccess(resp);
    }

    @ApiOperation("列表查詢(根據(score)排序 倒序返回「score & value」)- 查詢條件【最小&最高】score")
    @RequestMapping(value = "/query/rangeByScoreWithScores/reverse",method = RequestMethod.GET)
    public BaseResp reverseRangeByScoreWithScores(@RequestParam(value = "minScore",required = false)Double minScore,@RequestParam(value = "maxScore",required = false)Double maxScore){
        ZSetOperations setOperations  = redisTemplate.opsForZSet();
        minScore = ObjectUtil.defaultIfNull(minScore,Double.MIN_VALUE);
        maxScore = ObjectUtil.defaultIfNull(maxScore,Double.MAX_VALUE);

        Set resp = setOperations.reverseRangeByScoreWithScores(zSet_test_key_1, minScore,maxScore);
        log.info("reverseRangeByScoreWithScores resp:{}",resp);
        return BaseResp.buildDataSuccess(resp);
    }


    String zSet_test_key_union_1 = "zSet_test_key_union_1";
    String zSet_test_key_union_2 = "zSet_test_key_union_2";
    String zSet_test_key_union_desc = "zSet_test_key_union_desc";

    @ApiOperation("多個有序集合,合併成一個新的有序集合(並集) 元素相同的score想加")
    @RequestMapping(value = "/store/unionAndStore",method = RequestMethod.GET)
    public BaseResp unionAndStore(){
        ZSetOperations setOperations  = redisTemplate.opsForZSet();
        List<User> users = TestDataUtil.getUsers();
        for (User user : users) {
            setOperations.add(zSet_test_key_union_1,user.getId(),user.getAge());
        }

        setOperations.add(zSet_test_key_union_2,1,10000);

        setOperations.add(zSet_test_key_union_2,-1,-1);

        Long resp = setOperations.unionAndStore(zSet_test_key_union_1,zSet_test_key_union_2,zSet_test_key_union_desc);
        log.info("unionAndStore resp:{}",resp);
        return BaseResp.buildDataSuccess(resp);
    }


    String zSet_test_key_intersect_1 = "zSet_test_intersect_1";
    String zSet_test_key_intersect_2 = "zSet_test_intersect_2";
    String zSet_test_key_intersect_desc = "zSet_test_intersect_dest";

    @ApiOperation("兩個有序集合-交集, 兩個有序集合 都有相同的元素,並且score相加")
    @RequestMapping(value = "/store/intersectAndStore",method = RequestMethod.GET)
    public BaseResp intersectAndStore(){
        ZSetOperations setOperations  = redisTemplate.opsForZSet();
        List<User> users = TestDataUtil.getUsers();
        for (User user : users) {
            setOperations.add(zSet_test_key_intersect_1,user.getId(),user.getAge());
        }

        setOperations.add(zSet_test_key_intersect_2,1,100);
        setOperations.add(zSet_test_key_intersect_2,10003,100);

        Long resp = setOperations.intersectAndStore(zSet_test_key_intersect_1,zSet_test_key_intersect_2,zSet_test_key_intersect_desc);
        log.info("intersectAndStore resp:{}",resp);
        return BaseResp.buildDataSuccess(resp);
    }
    //-----------------redis zset end-------------
}

5、RedisTemplate支援常用的5種資料結構:String字串、Hash雜湊表、List列表、Set集合、Zset有序集合,方法對應的介面文件

在部落格園看到大佬(暱稱: 一天學點)把這5種資料結構 呼叫方法整理成了表格,我copy了一份備註了出處 方便後期查閱
1、使用ValueOperations操作redis(String字串)
2、使用HashOperations操作redis(Hash雜湊表)
3、使用ListOperations操作redis(List列表)
4、使用SetOperations(無序)操作redis(Set集合)
5、使用ZSetOperations(有序)操作redis(Zset有序集合)


6、隨機建立使用者資訊的工具類(方便測試)

/****
 *
 * <p>隨機數生成工具類,主要包括<br>
 *  中文姓名,性別,Email,手機號,住址
 *
 * @author youqiang.xiong
 * @date 2018年5月23日  下午2:15:31
 * @version v1.0
 * @ClassName: RandomValueUtil
 */
@Slf4j
public class RandomValueUtil {

    public static String base = "abcdefghijklmnopqrstuvwxyz0123456789";
    private static String firstName="趙錢孫李周吳鄭王馮陳褚衛蔣沈韓楊朱秦尤許何呂施張孔曹嚴華金魏陶姜戚謝鄒喻柏水竇章雲蘇潘葛奚範彭郎魯韋昌馬苗鳳花方俞任袁柳酆鮑史唐費廉岑薛雷賀倪湯滕殷羅畢郝鄔安常樂於時傅皮卞齊康伍餘元卜顧孟平黃和穆蕭尹姚邵湛汪祁毛禹狄米貝明臧計伏成戴談宋茅龐熊紀舒屈項祝董樑杜阮藍閔席季麻強賈路婁危江童顏郭梅盛林刁鍾徐邱駱高夏蔡田樊胡凌霍虞萬支柯咎管盧莫經房裘繆幹解應宗宣丁賁鄧鬱單杭洪包諸左石崔吉鈕龔程嵇邢滑裴陸榮翁荀羊於惠甄魏加封芮羿儲靳汲邴糜鬆井段富巫烏焦巴弓牧隗山谷車侯宓蓬全郗班仰秋仲伊宮寧仇欒暴甘鈄厲戎祖武符劉姜詹束龍葉幸司韶郜黎薊薄印宿白懷蒲臺從鄂索鹹籍賴卓藺屠蒙池喬陰鬱胥能蒼雙聞莘黨翟譚貢勞逄姬申扶堵冉宰酈雍卻璩桑桂濮牛壽通邊扈燕冀郟浦尚農溫別莊晏柴瞿閻充慕連茹習宦艾魚容向古易慎戈廖庚終暨居衡步都耿滿弘匡國文寇廣祿闕東毆殳沃利蔚越夔隆師鞏厙聶晁勾敖融冷訾辛闞那簡饒空曾毋沙乜養鞠須豐巢關蒯相查後江紅遊竺權逯蓋益桓公万俟司馬上官歐陽夏侯諸葛聞人東方赫連皇甫尉遲公羊澹臺公冶宗政濮陽淳于仲孫太叔申屠公孫樂正軒轅令狐鍾離閭丘長孫慕容鮮于宇文司徒司空亓官司寇仉督子車顓孫端木巫馬公西漆雕樂正壤駟公良拓拔夾谷宰父谷粱晉楚閻法汝鄢塗欽段幹百里東郭南門呼延歸海羊舌微生嶽帥緱亢況後有琴樑丘左丘東門西門商牟佘佴伯賞南宮墨哈譙笪年愛陽佟第五言福百家姓續";
    private static String girl="秀娟英華慧巧美娜靜淑惠珠翠雅芝玉萍紅娥玲芬芳燕彩春菊蘭鳳潔梅琳素雲蓮真環雪榮愛妹霞香月鶯媛豔瑞凡佳嘉瓊勤珍貞莉桂娣葉璧璐婭琦晶妍茜秋珊莎錦黛青倩婷姣婉嫻瑾穎露瑤怡嬋雁蓓紈儀荷丹蓉眉君琴蕊薇菁夢嵐苑婕馨瑗琰韻融園藝詠卿聰瀾純毓悅昭冰爽琬茗羽希寧欣飄育瀅馥筠柔竹靄凝曉歡霄楓芸菲寒伊亞宜可姬舒影荔枝思麗 ";
    public static String boy="偉剛勇毅俊峰強軍平保東文輝力明永健世廣志義興良海山仁波寧貴福生龍元全國勝學祥才發武新利清飛彬富順信子傑濤昌成康星光天達安巖中茂進林有堅和彪博誠先敬震振壯會思群豪心邦承樂紹功鬆善厚慶磊民友裕河哲江超浩亮政謙亨奇固之輪翰朗伯巨集言若鳴朋斌樑棟維啟克倫翔旭鵬澤晨辰士以建家致樹炎德行時泰盛雄琛鈞冠策騰楠榕風航弘";
    public static final String[] email_suffix="@gmail.com,@yahoo.com,@msn.com,@hotmail.com,@aol.com,@ask.com,@live.com,@qq.com,@0355.net,@163.com,@163.net,@263.net,@3721.net,@yeah.net,@googlemail.com,@126.com,@sina.com,@sohu.com,@yahoo.com.cn".split(",");

    public static int getNum(int start,int end) {
        return (int)(Math.random()*(end-start+1)+start);
    }

    public static int getAge() {
        return getNum(1,100);
    }
    /***
     *
     * <p>隨機生成Email
     *
     * @param lMin
     *         最小長度
     * @param lMax
     *         最大長度
     * @return
     */
    public static String getEmail(int lMin,int lMax) {
        int length=getNum(lMin,lMax);
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = (int)(Math.random()*base.length());
            sb.append(base.charAt(number));
        }
        sb.append(email_suffix[(int)(Math.random()*email_suffix.length)]);
        return sb.toString();
    }
    public static String getEmail(){
        return getEmail(5,15);
    }

    private static String[] telFirst="134,135,136,137,138,139,150,151,152,157,158,159,130,131,132,155,156,133,153".split(",");

    /***
     *
     * <p>隨機生成手機號碼
     *
     * @return
     */
    public static String getTelephone() {
        int index=getNum(0,telFirst.length-1);
        String first=telFirst[index];
        String second=String.valueOf(getNum(1,888)+10000).substring(1);
        String thrid=String.valueOf(getNum(1,9100)+10000).substring(1);
        return first+second+thrid;
    }

    /***
     *
     * Project Name: recruit-helper-util
     * <p>隨機生成8位電話號碼
     *

     * @since
     * @return
     */
    public static String getLandline() {
        int index=getNum(0,telFirst.length-1);
        String first=telFirst[index];
        String second=String.valueOf(getNum(1,888)+10000).substring(1);
        String thrid=String.valueOf(getNum(1,9100)+10000).substring(1);
        return first+second+thrid;
    }



    /**
     * 返回中文姓名
     */
    public static String name_sex = "";

    /***
     *
     * <p>返回中文姓名
     * 
     * @return
     */
    public static String getChineseName() {
        int index = getNum(0, firstName.length() - 1);
        String first = firstName.substring(index, index + 1);
        int sex = getNum(0, 1);
        String str = boy;
        int length = boy.length();
        if (sex == 0) {
            str = girl;
            length = girl.length();
            name_sex = "女";
        } else {
            name_sex = "男";
        }
        index = getNum(0, length - 1);
        String second = str.substring(index, index + 1);
        int hasThird = getNum(0, 1);
        String third = "";
        if (hasThird == 1) {
            index = getNum(0, length - 1);
            third = str.substring(index, index + 1);
        }
        return first + second + third;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 200; i++) {
            String name =RandomValueUtil.getChineseName();
            String phone = RandomValueUtil.getTelephone();
            String email = RandomValueUtil.getEmail(5,15);
            Integer age = RandomValueUtil.getAge();
			
            log.info("i:{}  name:{} phone:{} email:{} age:{}",i,name,phone,email,age);
        }
    }
	
}


程式碼我已經傳到gitee了 傳送門

相關文章