Browse Source

缓存数据库处理

zhanghao 1 month ago
parent
commit
76eecd3215

+ 2 - 1
project-admin/src/main/java/com/project/web/controller/monitor/SysUserOnlineController.java

@@ -1,5 +1,6 @@
 package com.project.web.controller.monitor;
 
+import com.alibaba.fastjson2.JSON;
 import com.project.common.annotation.Log;
 import com.project.common.constant.CacheConstants;
 import com.project.common.core.controller.BaseController;
@@ -40,7 +41,7 @@ public class SysUserOnlineController extends BaseController {
         Collection<String> keys = redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*");
         List<SysUserOnline> userOnlineList = new ArrayList<SysUserOnline>();
         for (String key : keys) {
-            LoginUser user = redisCache.getCacheObject(key);
+            LoginUser user = JSON.parseObject(redisCache.getCacheObject(key).toString(), LoginUser.class);
             if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) {
                 if (StringUtils.equals(ipaddr, user.getIpaddr()) && StringUtils.equals(userName, user.getUsername())) {
                     userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user));

+ 44 - 0
project-common/src/main/java/com/project/common/core/domain/entity/LargeCache.java

@@ -0,0 +1,44 @@
+package com.project.common.core.domain.entity;
+
+import com.alibaba.fastjson2.annotation.JSONField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import lombok.experimental.Accessors;
+
+import java.util.Date;
+
+@Data
+@Accessors(chain = true)
+@ToString(callSuper = true)
+@EqualsAndHashCode(callSuper = false)
+@TableName("large_plat_cache")
+public class LargeCache {
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 名称
+     */
+    private String key;
+
+    /**
+     * 类别
+     */
+    private String data;
+
+    /**
+     * 创建时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    /**
+     * 有效期
+     */
+    private Long expirationDate;
+
+}

+ 80 - 13
project-common/src/main/java/com/project/common/core/redis/MyCache.java

@@ -1,18 +1,30 @@
 package com.project.common.core.redis;
 
 
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
 import com.github.benmanes.caffeine.cache.Cache;
 import com.github.benmanes.caffeine.cache.Caffeine;
+import com.project.common.core.domain.entity.LargeCache;
+import com.project.common.mapper.cache.PlatCacheMapper;
+import com.project.common.utils.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.PostConstruct;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.List;
 import java.util.Objects;
 import java.util.concurrent.TimeUnit;
 
 @Component
 public class MyCache {
 
+    @Autowired
+    private PlatCacheMapper platCacheMapper;
+
     // 使用ConcurrentHashMap作为数据的存储
 //    private ConcurrentHashMap<String, Object> storage = new ConcurrentHashMap<>();
 
@@ -54,10 +66,27 @@ public class MyCache {
      * @return
      */
     public boolean hasKey(String key){
-        if (caffeineCache.getIfPresent(key) != null){
-            return true;
+        if (StringUtils.isBlank(key)){
+            return false;
+        }
+        LargeCache cache = platCacheMapper.selectCache(key);
+        if (cache == null || StringUtils.isBlank(cache.getKey())){
+            return false;
         }
-        return false;
+        LocalDateTime createTimePlus30 = cache.getCreateTime().toInstant()
+                .atZone(java.time.ZoneId.systemDefault())
+                .toLocalDateTime()
+                .plusMinutes(cache.getExpirationDate());
+        LocalDateTime now = LocalDateTime.now();
+        if (createTimePlus30.isBefore(now)){
+            platCacheMapper.deleteCache(key);
+            return false;
+        }
+        return true;
+//        if (caffeineCache.getIfPresent(key) != null){
+//            return true;
+//        }
+//        return false;
     }
 
 //    @Override
@@ -70,13 +99,30 @@ public class MyCache {
 //    }
 
     /**
-     * get方法, 获取缓存数据,无需反序列化
+     * get方法, 获取缓存数据
      * @param key
      * @return
      */
     public Object get(Object key) {
-        String k = key.toString();
-        return caffeineCache.getIfPresent(k);
+//        String k = key.toString();
+//        return caffeineCache.getIfPresent(k);
+        if (Objects.isNull(key)){
+            return null;
+        }
+        LargeCache cache = platCacheMapper.selectCache(key.toString());
+        if (cache == null || StringUtils.isBlank(cache.getKey())){
+            return null;
+        }
+        LocalDateTime createTimePlus30 = cache.getCreateTime().toInstant()
+                .atZone(java.time.ZoneId.systemDefault())
+                .toLocalDateTime()
+                .plusMinutes(cache.getExpirationDate());
+        LocalDateTime now = LocalDateTime.now();
+        if (createTimePlus30.isBefore(now)){
+            platCacheMapper.deleteCache(key.toString());
+            return null;
+        }
+        return cache.getData();
     }
 
 //    @Override
@@ -105,8 +151,17 @@ public class MyCache {
      * @param value
      */
     public void put(Object key, Object value) {
-        if (Objects.nonNull(value)) {
-            caffeineCache.put(key.toString(), value);
+//        if (Objects.nonNull(value)) {
+//            caffeineCache.put(key.toString(), value);
+//        }
+        if (Objects.isNull(key) || Objects.isNull(value)){
+            return;
+        }
+        if (value instanceof String){
+            platCacheMapper.insertCache(key.toString(), value.toString());
+        }
+        else {
+            platCacheMapper.insertCache(key.toString(), JSON.toJSONString(value));
         }
     }
 
@@ -121,7 +176,11 @@ public class MyCache {
      * @param key
      */
     public void evict(Object key) {
-        caffeineCache.invalidate(key.toString());
+//        caffeineCache.invalidate(key.toString());
+        if (Objects.isNull(key)){
+            return;
+        }
+        platCacheMapper.deleteCache(key.toString());
     }
 
     // 删除集合
@@ -138,9 +197,15 @@ public class MyCache {
      * @return
      */
     public boolean deleteObject(final Collection collection){
+//        collection.forEach(o -> {
+//            caffeineCache.invalidate(o.toString());
+//        } );
+//        return true;
+        List<String> list = new ArrayList<>();
         collection.forEach(o -> {
-            caffeineCache.invalidate(o.toString());
-        } );
+            list.add(o.toString());
+        });
+        platCacheMapper.deleteCaches(list);
         return true;
     }
 
@@ -155,7 +220,8 @@ public class MyCache {
      * @return
      */
     public Collection<String> keys(final String pattern){
-        return caffeineCache.asMap().keySet();
+//        return caffeineCache.asMap().keySet();
+        return platCacheMapper.selectKeys();
     }
 
 //    @Override
@@ -167,6 +233,7 @@ public class MyCache {
      * 清除所有缓存
      */
     public void clear() {
-        caffeineCache.invalidateAll();
+//        caffeineCache.invalidateAll();
+        platCacheMapper.clearAll();
     }
 }

+ 21 - 0
project-common/src/main/java/com/project/common/mapper/cache/PlatCacheMapper.java

@@ -0,0 +1,21 @@
+package com.project.common.mapper.cache;
+
+import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
+import com.project.common.core.domain.entity.LargeCache;
+
+import java.util.List;
+
+@InterceptorIgnore(blockAttack = "true")
+public interface PlatCacheMapper {
+    LargeCache selectCache(String key);
+
+    void insertCache(String key, String data);
+
+    void deleteCache(String key);
+
+    void deleteCaches(List<String> list);
+
+    List<String> selectKeys();
+
+    void clearAll();
+}

+ 52 - 0
project-common/src/main/resources/mapper/common.cache/PlatCacheMapper.xml

@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.project.common.mapper.cache.PlatCacheMapper">
+    <resultMap type="com.project.common.core.domain.entity.LargeCache" id="LargeCacheResult">
+        <result property="id"    column="id"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="expirationDate"    column="expiration_date"    />
+        <result property="key"    column="key"    />
+        <result property="data"    column="data"    />
+    </resultMap>
+
+    <select id="selectCache" resultMap="LargeCacheResult">
+        SELECT
+            *
+        FROM
+            large_plat_cache
+        WHERE
+            `key` = #{key}
+            LIMIT 1
+    </select>
+
+    <insert id="insertCache">
+        insert into large_plat_cache(`key`,`data`,expiration_date,create_time)
+        values (#{arg0},#{arg1},30,sysdate())
+    </insert>
+
+    <delete id="deleteCache" parameterType="String">
+        delete from large_plat_cache where `key` = #{key}
+    </delete>
+
+    <delete id="deleteCaches" parameterType="String">
+        delete from large_plat_cache where `key` in
+        <foreach collection="list" item="item" open="(" separator="," close=")">
+            #{item}
+        </foreach>
+    </delete>
+
+    <select id="selectKeys" resultType="String">
+        SELECT
+            `key`
+        FROM
+            large_plat_cache
+        WHERE
+            DATE_ADD( create_time, INTERVAL 30 MINUTE ) > SYSDATE()
+    </select>
+
+    <delete id="clearAll">
+        delete from large_plat_cache
+    </delete>
+</mapper>

+ 2 - 2
project-framework/src/main/java/com/project/framework/interceptor/impl/SameUrlDataInterceptor.java

@@ -62,9 +62,9 @@ public class SameUrlDataInterceptor extends RepeatSubmitInterceptor {
         // 唯一标识(指定key + url + 消息头)
         String cacheRepeatKey = CacheConstants.REPEAT_SUBMIT_KEY + url + submitKey;
 
-        Object sessionObj = redisCache.getCacheObject(cacheRepeatKey);
+        Map<String, Object> sessionObj = JSON.parseObject(redisCache.getCacheObject(cacheRepeatKey).toString(), Map.class);
         if (sessionObj != null) {
-            Map<String, Object> sessionMap = (Map<String, Object>) sessionObj;
+            Map<String, Object> sessionMap = sessionObj;
             if (sessionMap.containsKey(url)) {
                 Map<String, Object> preDataMap = (Map<String, Object>) sessionMap.get(url);
                 if (compareParams(nowDataMap, preDataMap) && compareTime(nowDataMap, preDataMap, annotation.interval())) {

+ 1 - 1
project-framework/src/main/java/com/project/framework/web/service/SysLoginService.java

@@ -146,7 +146,7 @@ public class SysLoginService {
      */
     public void validateCaptcha(String username, String code, String uuid) {
         String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
-        String captcha = redisCache.getCacheObject(verifyKey);
+        String captcha = redisCache.getCacheObject(verifyKey).toString();
         redisCache.deleteObject(verifyKey);
         if (captcha == null) {
             AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));

+ 7 - 1
project-framework/src/main/java/com/project/framework/web/service/SysPasswordService.java

@@ -48,7 +48,13 @@ public class SysPasswordService {
         Authentication usernamePasswordAuthenticationToken = AuthenticationContextHolder.getContext();
         String username = usernamePasswordAuthenticationToken.getName();
         String password = usernamePasswordAuthenticationToken.getCredentials().toString();
-        Integer retryCount = redisCache.getCacheObject(getCacheKey(username));
+        Object res = redisCache.getCacheObject(getCacheKey(username));
+        Integer retryCount;
+        if (res == null){
+            retryCount = 0;
+        }else {
+            retryCount = Integer.valueOf(res.toString());
+        }
 
         if (retryCount == null) {
             retryCount = 0;

+ 1 - 1
project-framework/src/main/java/com/project/framework/web/service/SysRegisterService.java

@@ -84,7 +84,7 @@ public class SysRegisterService {
      */
     public void validateCaptcha(String username, String code, String uuid) {
         String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
-        String captcha = redisCache.getCacheObject(verifyKey);
+        String captcha = redisCache.getCacheObject(verifyKey).toString();
         redisCache.deleteObject(verifyKey);
         if (captcha == null) {
             throw new CaptchaExpireException();

+ 2 - 1
project-framework/src/main/java/com/project/framework/web/service/TokenService.java

@@ -1,5 +1,6 @@
 package com.project.framework.web.service;
 
+import com.alibaba.fastjson2.JSON;
 import com.project.common.constant.CacheConstants;
 import com.project.common.constant.Constants;
 import com.project.common.core.domain.model.LoginUser;
@@ -61,7 +62,7 @@ public class TokenService {
                 // 解析对应的权限以及用户信息
                 String uuid = (String) claims.get(Constants.LOGIN_USER_KEY);
                 String userKey = getTokenKey(uuid);
-                LoginUser user = redisCache.getCacheObject(userKey);
+                LoginUser user = JSON.parseObject(redisCache.getCacheObject(userKey).toString(), LoginUser.class);
                 return user;
             } catch (Exception e) {
                 e.printStackTrace();

+ 1 - 1
project-system/src/main/java/com/project/system/service/impl/SysConfigServiceImpl.java

@@ -61,7 +61,7 @@ public class SysConfigServiceImpl implements ISysConfigService {
      */
     @Override
     public String selectConfigByKey(String configKey) {
-        String configValue = Convert.toStr(redisCache.getCacheObject(getCacheKey(configKey)));
+        String configValue = Convert.toStr(redisCache.getCacheObject(getCacheKey(configKey)).toString());
         if (StringUtils.isNotEmpty(configValue)) {
             return configValue;
         }