diff --git a/README.md b/README.md
index f4ec9e9..0ed84f9 100644
--- a/README.md
+++ b/README.md
@@ -40,4 +40,7 @@
utils.response.VoResult
### 根据实体类属性获取getAndSet方法
- utils.MethodGetAndSet 可能有bug,待测试
\ No newline at end of file
+ utils.MethodGetAndSet 可能有bug,待测试
+
+### redis工具
+ utils.redis.RedisCacheUtils
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index e5b589c..8653097 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,19 +21,21 @@
org.springframework.boot
spring-boot-starter-web
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
com.alibaba
fastjson
2.0.26
-
cn.hutool
hutool-all
5.8.16
-
org.projectlombok
lombok
diff --git a/src/main/java/utils/Base64Utils.java b/src/main/java/utils/Base64Utils.java
new file mode 100644
index 0000000..d63b101
--- /dev/null
+++ b/src/main/java/utils/Base64Utils.java
@@ -0,0 +1,112 @@
+package utils;
+
+import org.apache.commons.codec.binary.Base64;
+
+import java.io.*;
+
+public class Base64Utils {
+
+ /**
+ * BASE64编码解码工具包
+ * 依赖javabase64-1.3.1.jar
+ *
+ * @date 2012-5-19
+ * @version 1.0
+ */
+
+ /**
+ * 文件读取缓冲区大小
+ */
+ private static final int CACHE_SIZE = 1024;
+
+ /**
+ * BASE64字符串解码为二进制数据
+ * @param base64
+ * @throws Exception
+ */
+ public static byte[] decode(String base64) throws Exception {
+ return Base64.decodeBase64(base64.getBytes());
+ // return Base64.decode(base64.getBytes());
+ }
+
+ /**
+ * 二进制数据编码为BASE64字符串
+ * @param bytes
+ * @throws Exception
+ */
+ public static String encode(byte[] bytes) throws Exception {
+ return new String(Base64.encodeBase64(bytes));
+ // return new String(Base64.encode(bytes));
+ }
+
+ /**
+ * 将文件编码为BASE64字符串
+ * 大文件慎用,可能会导致内存溢出
+ *
+ * @param filePath 文件绝对路径
+ * @throws Exception
+ */
+ public static String encodeFile(String filePath) throws Exception {
+ byte[] bytes = fileToByte(filePath);
+ return encode(bytes);
+ }
+
+ /**
+ * BASE64字符串转回文件
+ * @param filePath 文件绝对路径
+ * @param base64 编码字符串
+ * @throws Exception
+ */
+ public static void decodeToFile(String filePath, String base64) throws Exception {
+ byte[] bytes = decode(base64);
+ byteArrayToFile(bytes, filePath);
+ }
+
+ /**
+ * 文件转换为二进制数组
+ * @param filePath 文件路径
+ * @return
+ * @throws Exception
+ */
+ public static byte[] fileToByte(String filePath) throws Exception {
+ byte[] data = new byte[0];
+ File file = new File(filePath);
+ if (file.exists()) {
+ FileInputStream in = new FileInputStream(file);
+ ByteArrayOutputStream out = new ByteArrayOutputStream(2048);
+ byte[] cache = new byte[CACHE_SIZE];
+ int nRead = 0;
+ while ((nRead = in.read(cache)) != -1) {
+ out.write(cache, 0, nRead);
+ out.flush();
+ }
+ out.close();
+ in.close();
+ data = out.toByteArray();
+ }
+ return data;
+ }
+
+ /**
+ * 二进制数据写文件
+ * @param bytes 二进制数据
+ * @param filePath 文件生成目录
+ */
+ public static void byteArrayToFile(byte[] bytes, String filePath) throws Exception {
+ InputStream in = new ByteArrayInputStream(bytes);
+ File destFile = new File(filePath);
+ if (!destFile.getParentFile().exists()) {
+ destFile.getParentFile().mkdirs();
+ }
+ destFile.createNewFile();
+ OutputStream out = new FileOutputStream(destFile);
+ byte[] cache = new byte[CACHE_SIZE];
+ int nRead = 0;
+ while ((nRead = in.read(cache)) != -1) {
+ out.write(cache, 0, nRead);
+ out.flush();
+ }
+ out.close();
+ in.close();
+ }
+}
diff --git a/src/main/java/utils/redis/RedisCacheUtils.java b/src/main/java/utils/redis/RedisCacheUtils.java
new file mode 100644
index 0000000..b0f335c
--- /dev/null
+++ b/src/main/java/utils/redis/RedisCacheUtils.java
@@ -0,0 +1,129 @@
+package utils.redis;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author fuhouyin
+ * @time 2023/4/11 9:30
+ */
+@Component
+public class RedisCacheUtils {
+
+ @Autowired
+ private RedisTemplateProvider redisTemplateProvider;
+ private final StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
+
+ public void setValue(String key, Object value){
+ RedisTemplate redisTemplate = getRedisTemplate();
+ redisTemplate.opsForValue().set(key,value);
+ }
+
+ public void setValue(String key, Object value,Long timeout, TimeUnit timeUnit){
+ RedisTemplate redisTemplate = getRedisTemplate();
+ redisTemplate.opsForValue().set(key,value,timeout, timeUnit);
+ }
+
+ public Object getValue(String key){
+ RedisTemplate redisTemplate = getRedisTemplate();
+ return redisTemplate.opsForValue().get(key);
+ }
+
+ public String getCacheKey(Object... keys) {
+ return StringUtils.join(Arrays.asList(keys), ":");
+ }
+
+ public Long hashIncrement(String key, String hashKey){
+ RedisTemplate redisTemplate = getRedisTemplate();
+ Long increment = redisTemplate.opsForHash().increment(key, hashKey, 1);
+ return increment;
+ }
+
+ public boolean hasKey(String key){
+ return getRedisTemplate().hasKey(key);
+ }
+
+ public boolean delKey(String key){
+ if (StringUtils.isEmpty(key)) {
+ return Boolean.FALSE;
+ }
+ RedisTemplate redisTemplate = getRedisTemplate();
+ if (redisTemplate.hasKey(key)) {
+ return redisTemplate.delete(key);
+ }
+ return Boolean.TRUE;
+ }
+
+ public boolean hashHasKey(String key, String hashKey){
+ return getRedisTemplate().opsForHash().hasKey(key, hashKey);
+ }
+
+ public Object hashGet(String key, String hashKey){
+ return getRedisTemplate().opsForHash().get(key, hashKey);
+ }
+
+ private RedisTemplate getRedisTemplate(){
+ RedisTemplate template = redisTemplateProvider.getTemplate(stringRedisSerializer);
+ return template;
+ }
+
+ public void hashPut(String key,String hashKey, String value){
+ getRedisTemplate().opsForHash().put(key,hashKey,value);
+ }
+
+ public void hashPutIfAbsent(String key, String hashKey, String value) {
+ getRedisTemplate().opsForHash().putIfAbsent(key,hashKey,value);
+ }
+
+ public Boolean expire(String key, long time, TimeUnit timeUnit){
+ Boolean result = getRedisTemplate().expire(key, time, timeUnit);
+ return result;
+ }
+
+ public Boolean lock(String key){
+ return getRedisTemplate().opsForValue().setIfAbsent(key, BigDecimal.ZERO.intValue());
+ }
+
+ public Boolean tryLock(String key){
+ try {
+ for (int i = 0; i < 3; i++) {
+ if (lock(key)) {
+ return Boolean.TRUE;
+ }
+ Thread.sleep(100L);
+ }
+ } catch (InterruptedException e) {
+ return Boolean.FALSE;
+ }
+ return Boolean.FALSE;
+ }
+
+ public void unlock(String key){
+ getRedisTemplate().delete(key);
+ }
+
+
+ public Long increment(String key, Long delta){
+ return getRedisTemplate().opsForValue().increment(key,delta);
+ }
+
+ public Boolean setIfAbsent(String key, Object value){
+ return getRedisTemplate().opsForValue().setIfAbsent(key,value);
+ }
+
+ public Set keys(String keyPattern) {
+ return getRedisTemplate().keys(keyPattern);
+ }
+
+ public Object getAndSet(String key, Object value){
+ return getRedisTemplate().opsForValue().getAndSet(key,value);
+ }
+}
diff --git a/src/main/java/utils/redis/RedisTemplateProvider.java b/src/main/java/utils/redis/RedisTemplateProvider.java
new file mode 100644
index 0000000..0811b35
--- /dev/null
+++ b/src/main/java/utils/redis/RedisTemplateProvider.java
@@ -0,0 +1,14 @@
+package utils.redis;
+
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.RedisSerializer;
+
+/**
+ * @author fuhouyin
+ * @time 2023/4/11 9:30
+ */
+public interface RedisTemplateProvider {
+ RedisTemplate getTemplate();
+
+ RedisTemplate getTemplate(RedisSerializer valueSerializer);
+}
diff --git a/src/main/java/utils/redis/RedisTemplateProviderImpl.java b/src/main/java/utils/redis/RedisTemplateProviderImpl.java
new file mode 100644
index 0000000..e2e554c
--- /dev/null
+++ b/src/main/java/utils/redis/RedisTemplateProviderImpl.java
@@ -0,0 +1,95 @@
+package utils.redis;
+
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
+import org.springframework.data.redis.serializer.RedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+import org.springframework.stereotype.Component;
+import org.springframework.util.Assert;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+/**
+ * @author fuhouyin
+ * @time 2023/4/11 9:30
+ */
+@Component
+public class RedisTemplateProviderImpl implements RedisTemplateProvider {
+ public static final RedisSerializer