diff --git a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/pom.xml b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/pom.xml
index 44f75363..1cf9d41b 100755
--- a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/pom.xml
+++ b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/pom.xml
@@ -15,6 +15,7 @@
UTF-8
UTF-8
1.8
+ 2.5.13
@@ -142,6 +143,24 @@
1.2.9
+
+ redis.clients
+ jedis
+ 3.9.0
+
+
+
+ org.springframework.data
+ spring-data-redis
+ 2.4.0
+
+
+ redis.clients
+ jedis
+
+
+
+
diff --git a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/demo/DemoSQLExecutor.java b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/demo/DemoSQLExecutor.java
index 9ada8f81..baab9cea 100644
--- a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/demo/DemoSQLExecutor.java
+++ b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/java/apijson/demo/DemoSQLExecutor.java
@@ -14,14 +14,20 @@
package apijson.demo;
+import apijson.JSON;
+import apijson.RequestMethod;
import com.alibaba.druid.pool.DruidDataSource;
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer;
import com.vesoft.nebula.jdbc.impl.NebulaDriver;
import com.zaxxer.hikari.HikariDataSource;
+import java.io.Serializable;
import java.sql.Connection;
-import java.sql.DriverManager;
+import java.util.List;
import java.util.Map;
import java.util.Properties;
+import java.util.concurrent.TimeUnit;
import javax.sql.DataSource;
@@ -29,6 +35,14 @@
import apijson.boot.DemoApplication;
import apijson.framework.APIJSONSQLExecutor;
import apijson.orm.SQLConfig;
+import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
+import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.GenericToStringSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+import static apijson.framework.APIJSONConstant.PRIVACY_;
+import static apijson.framework.APIJSONConstant.USER_;
/**SQL 执行器,支持连接池及多数据源
@@ -38,19 +52,71 @@
public class DemoSQLExecutor extends APIJSONSQLExecutor {
public static final String TAG = "DemoSQLExecutor";
+ // Redis 缓存 <<<<<<<<<<<<<<<<<<<<<<<
+ public static final RedisTemplate REDIS_TEMPLATE;
+ static {
+ REDIS_TEMPLATE = new RedisTemplate<>();
+ REDIS_TEMPLATE.setConnectionFactory(new JedisConnectionFactory(new RedisStandaloneConfiguration("127.0.0.1", 6379)));
+ REDIS_TEMPLATE.setKeySerializer(new StringRedisSerializer());
+ REDIS_TEMPLATE.setHashValueSerializer(new GenericToStringSerializer<>(Serializable.class));
+ REDIS_TEMPLATE.setValueSerializer(new GenericToStringSerializer<>(Serializable.class));
+// REDIS_TEMPLATE.setValueSerializer(new FastJsonRedisSerializer>(List.class));
+ REDIS_TEMPLATE.afterPropertiesSet();
+ }
+
// 可重写以下方法,支持 Redis 等单机全局缓存或分布式缓存
- // @Override
- // public List getCache(String sql, int type) {
- // return super.getCache(sql, type);
- // }
- // @Override
- // public synchronized void putCache(String sql, List list, int type) {
- // super.putCache(sql, list, type);
- // }
- // @Override
- // public synchronized void removeCache(String sql, int type) {
- // super.removeCache(sql, type);
- // }
+ @Override
+ public List getCache(String sql, SQLConfig config) {
+ List list = super.getCache(sql, config);
+ if (list == null) {
+ list = JSON.parseArray(REDIS_TEMPLATE.opsForValue().get(sql), JSONObject.class);
+ }
+ return list;
+ }
+ @Override
+ public synchronized void putCache(String sql, List list, SQLConfig config) {
+ super.putCache(sql, list, config);
+ if (config != null && config.isMain()) {
+ if (config.isExplain() || RequestMethod.isHeadMethod(config.getMethod(), true)) {
+ REDIS_TEMPLATE.opsForValue().set(sql, JSON.toJSONString(list), 10*60, TimeUnit.SECONDS);
+ } else {
+ String table = config.getTable();
+ REDIS_TEMPLATE.opsForValue().set(sql, JSON.toJSONString(list), USER_.equals(table) || PRIVACY_.equals(table) ? 10*60 : 60, TimeUnit.SECONDS);
+ }
+ }
+ }
+ @Override
+ public synchronized void removeCache(String sql, SQLConfig config) {
+ super.removeCache(sql, config);
+ if (config.getMethod() == RequestMethod.DELETE) { // 避免缓存击穿
+ REDIS_TEMPLATE.expire(sql, 60, TimeUnit.SECONDS);
+ } else {
+ REDIS_TEMPLATE.delete(sql);
+ }
+ }
+
+ @Override
+ public JSONObject execute(SQLConfig config, boolean unknownType) throws Exception {
+ JSONObject result = super.execute(config, unknownType);
+ RequestMethod method = config.getMethod();
+ if (method == RequestMethod.POST) { // 没必要,直接查就行了
+// Object id = result.get(config.getIdKey());
+// Object idIn = result.get(config.getIdKey() + "[]");
+// SQLConfig cacheConfig = APIJSONRouterApplication.DEFAULT_APIJSON_CREATOR.createSQLConfig();
+// cacheConfig.setMethod(RequestMethod.GET);
+//
+ }
+ else if (method == RequestMethod.PUT || method == RequestMethod.DELETE) { // RequestMethod.isQueryMethod(method) == false) {
+ config.setMethod(RequestMethod.GET);
+ boolean isPrepared = config.isPrepared();
+ removeCache(config.getSQL(false), config);
+ config.setPrepared(isPrepared);
+ config.setMethod(method);
+ }
+ return result;
+ }
+
+ // Redis 缓存 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// 适配连接池,如果这里能拿到连接池的有效 Connection,则 SQLConfig 不需要配置 dbVersion, dbUri, dbAccount, dbPassword
@Override
diff --git a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/js/main.js b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/js/main.js
index c5889ebf..ddbb9ce7 100755
--- a/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/js/main.js
+++ b/APIJSON-Java-Server/APIJSONBoot-MultiDataSource/src/main/resources/static/js/main.js
@@ -3592,6 +3592,7 @@
'[]': {
'count': this.testCaseCount || 100, //200 条测试直接卡死 0,
'page': this.testCasePage || 0,
+ 'join': '@/TestRecord,@/Script:pre,@/Script:post',
'Document': {
'@order': 'version-,date-',
'userId': this.User.id,