当前位置: 代码网 > it编程>数据库>Redis > RedisTemplate集成+封装RedisUtil过程

RedisTemplate集成+封装RedisUtil过程

2024年12月10日 Redis 我要评论
1.项目搭建创建一个redis模块调整pom.xml,使其成为单独的模块sun-common-redis的pom.xml 取消parentsun-common的pom.xml 取消对redis模块的管

1.项目搭建

创建一个redis模块

调整pom.xml,使其成为单独的模块

  • sun-common-redis的pom.xml 取消parent

  • sun-common的pom.xml 取消对redis模块的管理

  • sun-frame的pom.xml 增加对redis模块的管理

关于只在modules中配置子模块,但是子模块没有配置parent的用处

1. 多模块项目的构建管理

使用标签可以将多个子模块组织在一个顶层的父项目中,从而实现以下几个目标:

  • a. 单点构建
  • 你可以在父项目的根目录下运行一次mvn install命令,就可以构建和安装所有子模块到本地maven仓库,而不需要分别进入每个子模块目录单独运行构建命令。这大大简化了多模块项目的构建过程。
  • b. 构建顺序管理
  • maven会根据模块间的依赖关系,自动确定各个模块的构建顺序,确保在构建一个模块之前,先构建它所依赖的模块。这在多模块项目中是非常有用的,可以避免手动管理依赖顺序的麻烦。

2. 统一的版本管理

即使子模块没有指定父项目,使用标签仍然可以帮助你管理各个子模块的版本一致性。你可以在父项目的pom文件中统一指定各个子模块的版本号,然后在每个子模块的pom文件中引用这个版本号。

3. 项目结构的组织和清晰度

将多个子模块组织在一个父项目中,可以使项目结构更加清晰,便于管理。通过标签,你可以一目了然地看到项目中包含哪些子模块,以及它们之间的组织结构。

sun-common-redis引入redis依赖

    <dependencies>
        <!-- redis -->
        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-data-redis</artifactid>
            <version>2.4.2</version>
        </dependency>
        <!-- redis的pool -->
        <dependency>
            <groupid>org.apache.commons</groupid>
            <artifactid>commons-pool2</artifactid>
            <version>2.9.0</version>
        </dependency>
    </dependencies>

2.sun-user集成redistemplate

pom.xml引入sun-common-redis

        <!-- 引入sun-common-redis -->
        <dependency>
            <groupid>com.sunxiansheng</groupid>
            <artifactid>sun-common-redis</artifactid>
            <version>1.0-snapshot</version>
        </dependency>

application.yml配置redis(集群模式)

spring:
  #  配置redis(集群模式)
  redis:
    password: # redis服务器密码
    database: 0 # 默认数据库为0号
    timeout: 10000ms # 连接超时时间是10000毫秒
    lettuce:
      pool:
        max-active: 8 # 最大活跃连接数,使用负值表示没有限制,最佳配置为核数*2
        max-wait: 10000ms # 最大等待时间,单位为毫秒,使用负值表示没有限制,这里设置为10秒
        max-idle: 200 # 最大空闲连接数
        min-idle: 5 # 最小空闲连接数
    cluster:
      nodes:
  

testcontroller.java测试redistemplate

代码

package com.sunxiansheng.user.controller;

import org.springframework.data.redis.core.redistemplate;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.restcontroller;

import javax.annotation.resource;

/**
 * description:
 * @author sun
 * @create 2024/7/8 17:55
 * @version 1.0
 */
@restcontroller
public class testcontroller {

    @resource
    private redistemplate redistemplate;

    @requestmapping("/testredis")
    public string testredis() {
        redistemplate.opsforvalue().set("name", "sunxiansheng");
        return "hello world!";
    }
}

访问测试(发现有乱码)

重写redistemlate

引入jackson的依赖

        <!-- 重写redistemlate需要的jackson序列化工具 -->
        <dependency>
            <groupid>com.fasterxml.jackson.core</groupid>
            <artifactid>jackson-annotations</artifactid>
            <version>2.8.5</version>
        </dependency>
        <dependency>
            <groupid>com.fasterxml.jackson.core</groupid>
            <artifactid>jackson-databind</artifactid>
            <version>2.11.4</version>
        </dependency>

redisconfig.java

package com.sunxiansheng.redis.config;

import com.fasterxml.jackson.annotation.jsonautodetect;
import com.fasterxml.jackson.annotation.propertyaccessor;
import com.fasterxml.jackson.databind.deserializationfeature;
import com.fasterxml.jackson.databind.objectmapper;
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.jackson2jsonredisserializer;
import org.springframework.data.redis.serializer.redisserializer;
import org.springframework.data.redis.serializer.stringredisserializer;

/**
 * description: redisconfig配置类
 * @author sun
 * @create 2024/7/19 11:11
 * @version 1.0
 */
@configuration
public class redisconfig {

    /**
     * 重写redistemplate 解决乱码问题
     *
     * @param redisconnectionfactory
     * @return
     */
    @bean
    public redistemplate<string, object> redistemplate(redisconnectionfactory redisconnectionfactory) {
        redistemplate<string, object> redistemplate = new redistemplate<>();
        redistemplate.setconnectionfactory(redisconnectionfactory);
        // key就使用redis提供的序列化redisserializer即可
        redisserializer<string> redisserializer = new stringredisserializer();
        redistemplate.setkeyserializer(redisserializer);
        redistemplate.sethashkeyserializer(redisserializer);
        // value要使用jackson的序列化
        redistemplate.setvalueserializer(jackson2jsonredisserializer());
        redistemplate.setvalueserializer(jackson2jsonredisserializer());
        return redistemplate;
    }

    /**
     * 获取一个jackson的序列化对象逻辑
     *
     * @return
     */
    private jackson2jsonredisserializer<object> jackson2jsonredisserializer() {
        // 创建一个jackson2jsonredisserializer对象,用于序列化和反序列化java对象
        jackson2jsonredisserializer<object> jackson2jsonredisserializer = new jackson2jsonredisserializer<>(object.class);
        // 创建一个objectmapper对象,用于json序列化和反序列化的配置
        objectmapper objectmapper = new objectmapper();
        // 设置objectmapper的可见性,使其可以访问所有属性
        objectmapper.setvisibility(propertyaccessor.all, jsonautodetect.visibility.any);
        // 配置objectmapper,使其在遇到未知属性时不会抛出异常
        objectmapper.configure(deserializationfeature.fail_on_unknown_properties, false);
        // 将配置好的objectmapper设置到jackson2jsonredisserializer中
        jackson2jsonredisserializer.setobjectmapper(objectmapper);
        // 返回配置好的jackson2jsonredisserializer对象
        return jackson2jsonredisserializer;
    }

}

测试

3.封装redisutil

redisutil.java

package com.sunxiansheng.redis.util;

import org.springframework.data.redis.core.cursor;
import org.springframework.data.redis.core.redistemplate;
import org.springframework.data.redis.core.scanoptions;
import org.springframework.data.redis.core.zsetoperations;
import org.springframework.stereotype.component;

import javax.annotation.resource;
import java.util.hashmap;
import java.util.map;
import java.util.set;
import java.util.concurrent.timeunit;
import java.util.stream.collectors;
import java.util.stream.stream;

/**
 * description: redisutil工具类
 * @author sun
 * @create 2024/6/5 14:17
 * @version 1.0
 */
@component
public class redisutil {

    @resource
    private redistemplate redistemplate;

    private static final string cache_key_separator = ".";

    /**
     * 构建缓存key
     * @param strobjs 多个字符串拼接成缓存key
     * @return 拼接后的缓存key
     */
    public string buildkey(string... strobjs) {
        return stream.of(strobjs).collect(collectors.joining(cache_key_separator));
    }

    /**
     * 是否存在key
     * @param key redis中的key
     * @return true如果key存在,否则false
     */
    public boolean exist(string key) {
        return redistemplate.haskey(key);
    }

    /**
     * 删除key
     * @param key redis中的key
     * @return true如果删除成功,否则false
     */
    public boolean del(string key) {
        return redistemplate.delete(key);
    }

    /**
     * 设置key-value对
     * @param key redis中的key
     * @param value 要设置的值
     */
    public void set(string key, string value) {
        redistemplate.opsforvalue().set(key, value);
    }

    /**
     * 设置key-value对,如果key不存在,则设置成功,并指定过期时间
     * @param key redis中的key
     * @param value 要设置的值
     * @param time 过期时间
     * @param timeunit 时间单位
     * @return true如果设置成功,否则false
     */
    public boolean setnx(string key, string value, long time, timeunit timeunit) {
        return redistemplate.opsforvalue().setifabsent(key, value, time, timeunit);
    }

    /**
     * 获取指定key的值
     * @param key redis中的key
     * @return key对应的值
     */
    public string get(string key) {
        return (string) redistemplate.opsforvalue().get(key);
    }

    /**
     * 向有序集合中添加元素
     * @param key redis中的key
     * @param value 元素的值
     * @param score 元素的分数
     * @return true如果添加成功,否则false
     */
    public boolean zadd(string key, string value, long score) {
        return redistemplate.opsforzset().add(key, value, double.valueof(string.valueof(score)));
    }

    /**
     * 获取有序集合的元素数量
     * @param key redis中的key
     * @return 元素数量
     */
    public long countzset(string key) {
        return redistemplate.opsforzset().size(key);
    }

    /**
     * 获取有序集合指定范围内的元素
     * @param key redis中的key
     * @param start 起始位置
     * @param end 结束位置
     * @return 指定范围内的元素集合
     */
    public set<string> rangezset(string key, long start, long end) {
        return redistemplate.opsforzset().range(key, start, end);
    }

    /**
     * 删除有序集合中的指定元素
     * @param key redis中的key
     * @param value 要删除的元素
     * @return 被删除的元素数量
     */
    public long removezset(string key, object value) {
        return redistemplate.opsforzset().remove(key, value);
    }

    /**
     * 删除有序集合中的多个元素
     * @param key redis中的key
     * @param value 要删除的元素集合
     */
    public void removezsetlist(string key, set<string> value) {
        value.foreach(val -> redistemplate.opsforzset().remove(key, val));
    }

    /**
     * 获取有序集合中指定元素的分数
     * @param key redis中的key
     * @param value 元素的值
     * @return 元素的分数
     */
    public double score(string key, object value) {
        return redistemplate.opsforzset().score(key, value);
    }

    /**
     * 获取有序集合中指定分数范围内的元素
     * @param key redis中的key
     * @param start 起始分数
     * @param end 结束分数
     * @return 指定分数范围内的元素集合
     */
    public set<string> rangebyscore(string key, long start, long end) {
        return redistemplate.opsforzset().rangebyscore(key, double.valueof(string.valueof(start)), double.valueof(string.valueof(end)));
    }

    /**
     * 增加有序集合中指定元素的分数
     * @param key redis中的key
     * @param obj 元素的值
     * @param score 增加的分数
     * @return 增加后的分数
     */
    public object addscore(string key, object obj, double score) {
        return redistemplate.opsforzset().incrementscore(key, obj, score);
    }

    /**
     * 获取有序集合中指定元素的排名
     * @param key redis中的key
     * @param obj 元素的值
     * @return 元素的排名
     */
    public object rank(string key, object obj) {
        return redistemplate.opsforzset().rank(key, obj);
    }

    /**
     * 从 redis 有序集合(sorted set)中按分数范围获取成员及其分数
     * @param key 排行榜的key
     * @param start 起始位置(包含)
     * @param end 结束位置(包含)
     * @return set<zsetoperations.typedtuple<string>> : 每个 typedtuple 对象包含以下内容:value: 集合中的成员,score: 成员的分数。
     */
    public set<zsetoperations.typedtuple<string>> rankwithscore(string key, long start, long end) {
        return redistemplate.opsforzset().reverserangewithscores(key, start, end);
    }

    /**
     * 向redis中的hash结构存储数据
     * @param key 一个hash结构的key
     * @param hashkey hash中的小key
     * @param hashval hash中的小value
     */
    public void puthash(string key, string hashkey, object hashval) {
        redistemplate.opsforhash().put(key, hashkey, hashval);
    }

    /**
     * redis中的string类型,获取value时将其转换为int类型
     * @param key redis中的key
     * @return key对应的整数值
     */
    public integer getint(string key) {
        return (integer) redistemplate.opsforvalue().get(key);
    }

    /**
     * redis中的string类型,将value增加一
     * @param key redis中的key
     * @param count 增加的数量
     */
    public void increment(string key, integer count) {
        redistemplate.opsforvalue().increment(key, count);
    }

    /**
     * redis中的hash类型,根据key来将每一个hashkey和hashvalue转换为map类型
     * @param key redis中的hash结构的key
     * @return map<object, object> 包含hash结构中的所有键值对
     */
    public map<object, object> gethashanddelete(string key) {
        map<object, object> map = new hashmap<>();
        // 扫描hash,指定每一个entry的类型,这里返回的就是map的游标,可以进行遍历
        cursor<map.entry<object, object>> cursor = redistemplate.opsforhash().scan(key, scanoptions.none);
        // 遍历每一条数据,放到map中
        while (cursor.hasnext()) {
            map.entry<object, object> next = cursor.next();
            object hashkey = next.getkey();
            object hashvalue = next.getvalue();
            map.put(hashkey, hashvalue);
            // 每遍历一条就删除
            redistemplate.opsforhash().delete(key, hashkey);
        }
        return map;
    }
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com