Explorar el Código

缓存增加过期时间,优化日志

mxd hace 5 años
padre
commit
f757bf511f

+ 71 - 16
src/main/java/org/ssssssss/cache/DefaultSqlCache.java

@@ -4,37 +4,92 @@ import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.Map;
 
-public class DefaultSqlCache implements SqlCache {
+public class DefaultSqlCache extends LinkedHashMap<String, DefaultSqlCache.ExpireNode<Object>> implements SqlCache {
 
     private String separator = ":";
 
-    private LinkedHashMap<String, Object> cached;
+    private int capacity;
 
-    public DefaultSqlCache(int maxSize) {
-        this.cached = new LinkedHashMap<String, Object>(maxSize, 0.75f, true) {
-            @Override
-            protected boolean removeEldestEntry(Map.Entry<String, Object> eldest) {
-                return size() > maxSize;
-            }
-        };
+    private long expire;
+
+    public DefaultSqlCache(int capacity, long expire) {
+        super((int) Math.ceil(capacity / 0.75) + 1, 0.75f, true);
+        // 容量
+        this.capacity = capacity;
+        // 固定过期时间
+        this.expire = expire;
     }
+
     @Override
     public void put(String name, String key, Object value) {
-        this.cached.put(name + separator + key,value);
+        // 封装成过期时间节点
+        put(name + separator + key, new ExpireNode<>(System.currentTimeMillis() + this.expire, value));
     }
+
     @Override
     public Object get(String name, String key) {
-        return cached.get(name + separator + key);
+        key = name + separator + key;
+        ExpireNode<Object> expireNode = super.get(key);
+        if (expireNode == null) {
+            return null;
+        }
+        // 惰性删除过期的
+        if (this.expire > -1L && expireNode.expire < System.currentTimeMillis()) {
+            super.remove(key);
+            return null;
+        }
+        return expireNode.value;
     }
+
     @Override
-    public void remove(String name) {
-        Iterator<Map.Entry<String, Object>> iterator = cached.entrySet().iterator();
+    public void delete(String name) {
+        Iterator<Map.Entry<String, ExpireNode<Object>>> iterator = super.entrySet().iterator();
         String prefix = name + separator;
-        while(iterator.hasNext()){
-            Map.Entry<String, Object> entry = iterator.next();
-            if(entry.getKey().startsWith(prefix)){
+        // 清除所有key前缀为name + separator的缓存
+        while (iterator.hasNext()) {
+            Map.Entry<String, ExpireNode<Object>> entry = iterator.next();
+            if (entry.getKey().startsWith(prefix)) {
+                iterator.remove();
+            }
+        }
+    }
+
+
+    @Override
+    protected boolean removeEldestEntry(Map.Entry<String, ExpireNode<Object>> eldest) {
+        if (this.expire > -1L && size() > capacity) {
+            clean();
+        }
+        // lru淘汰
+        return size() > this.capacity;
+    }
+
+    /**
+     * 清理已过期的数据
+     */
+    private void clean() {
+        Iterator<Map.Entry<String, ExpireNode<Object>>> iterator = super.entrySet().iterator();
+        long now = System.currentTimeMillis();
+        while (iterator.hasNext()) {
+            Map.Entry<String, ExpireNode<Object>> next = iterator.next();
+            // 判断是否过期
+            if (next.getValue().expire < now) {
                 iterator.remove();
             }
         }
     }
+
+
+    /**
+     * 过期时间节点
+     */
+    static class ExpireNode<V> {
+        long expire;
+        Object value;
+
+        public ExpireNode(long expire, Object value) {
+            this.expire = expire;
+            this.value = value;
+        }
+    }
 }

+ 1 - 1
src/main/java/org/ssssssss/cache/SqlCache.java

@@ -38,6 +38,6 @@ public interface SqlCache {
      * 删除缓存
      * @param name  名字
      */
-    void remove(String name);
+    void delete(String name);
 
 }

+ 4 - 4
src/main/java/org/ssssssss/executor/SqlExecutor.java

@@ -132,7 +132,7 @@ public class SqlExecutor {
             int retVal = jdbcTemplate.update(sql, parameters);
             // 删除缓存
             if (retVal > 0 && this.sqlCache != null && StringUtils.isNotBlank(statement.getDeleteCache())) {
-                this.sqlCache.remove(statement.getDeleteCache());
+                this.sqlCache.delete(statement.getDeleteCache());
             }
             // 当设置返回值是boolean类型时,做>0比较
             if (returnType == Boolean.class) {
@@ -234,7 +234,7 @@ public class SqlExecutor {
             new ArgumentPreparedStatementSetter(parameters.toArray()).setValues(ps);
             int val = ps.executeUpdate();
             if (this.sqlCache != null && StringUtils.isNotBlank(deleteCache)) {
-                this.sqlCache.remove(deleteCache);
+                this.sqlCache.delete(deleteCache);
             }
             return val;
         } finally {
@@ -276,8 +276,8 @@ public class SqlExecutor {
      * 打印日志
      */
     private void printLog(String dataSourceName, String sql, Object... parameters) {
-        logger.debug("执行SQL({}):{}", dataSourceName == null ? "default" : dataSourceName, sql);
-        logger.debug("SQL参数{}", Arrays.toString(parameters));
+        logger.debug("执行SQL({}):{}", StringUtils.isBlank(dataSourceName) ? "default" : dataSourceName, sql);
+        logger.debug("SQL参数:{}", Arrays.toString(parameters));
     }
 
     /**

+ 8 - 2
src/main/java/org/ssssssss/session/DynamicDataSource.java

@@ -1,5 +1,8 @@
 package org.ssssssss.session;
 
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.ssssssss.utils.Assert;
 
 import javax.sql.DataSource;
@@ -8,17 +11,20 @@ import java.util.Map;
 
 public class DynamicDataSource {
 
+    private static Logger logger = LoggerFactory.getLogger(DynamicDataSource.class);
+
     private Map<String, DataSource> dataSourceMap = new HashMap<>();
 
     public void put(String dataSourceName, DataSource dataSource) {
-        if(dataSourceName == null){
+        if (dataSourceName == null) {
             dataSourceName = "";
         }
+        logger.info("注册数据源:{}", StringUtils.isNotBlank(dataSourceName) ? dataSourceName : "default");
         this.dataSourceMap.put(dataSourceName, dataSource);
     }
 
     public DataSource getDataSource(String dataSourceName) {
-        if(dataSourceName == null){
+        if (dataSourceName == null) {
             dataSourceName = "";
         }
         DataSource dataSource = dataSourceMap.get(dataSourceName);