|
@@ -3,6 +3,7 @@ package org.ssssssss.script.functions;
|
|
|
import org.springframework.jdbc.core.JdbcTemplate;
|
|
|
import org.springframework.jdbc.core.RowMapper;
|
|
|
import org.springframework.jdbc.datasource.DataSourceUtils;
|
|
|
+import org.ssssssss.magicapi.cache.SqlCache;
|
|
|
import org.ssssssss.magicapi.config.DynamicDataSource;
|
|
|
import org.ssssssss.magicapi.dialect.Dialect;
|
|
|
import org.ssssssss.magicapi.dialect.DialectUtils;
|
|
@@ -11,6 +12,7 @@ import org.ssssssss.magicapi.model.Page;
|
|
|
import org.ssssssss.magicapi.model.PageResult;
|
|
|
import org.ssssssss.magicapi.provider.PageProvider;
|
|
|
import org.ssssssss.script.MagicScriptContext;
|
|
|
+import org.ssssssss.script.annotation.UnableCall;
|
|
|
import org.ssssssss.script.parsing.GenericTokenParser;
|
|
|
import org.ssssssss.script.parsing.Parser;
|
|
|
import org.ssssssss.script.parsing.TokenStream;
|
|
@@ -23,41 +25,131 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|
|
|
|
|
public class DatabaseQuery extends HashMap<String, DatabaseQuery> {
|
|
|
|
|
|
+ @UnableCall
|
|
|
private DynamicDataSource dataSource;
|
|
|
|
|
|
+ @UnableCall
|
|
|
private JdbcTemplate template;
|
|
|
|
|
|
+ @UnableCall
|
|
|
private PageProvider pageProvider;
|
|
|
|
|
|
+ @UnableCall
|
|
|
private RowMapper<Map<String, Object>> rowMapper;
|
|
|
|
|
|
- public DatabaseQuery(JdbcTemplate template, DynamicDataSource dataSource, PageProvider pageProvider, RowMapper<Map<String, Object>> rowMapper) {
|
|
|
- this.template = template;
|
|
|
+ @UnableCall
|
|
|
+ private SqlCache sqlCache;
|
|
|
+
|
|
|
+ @UnableCall
|
|
|
+ private String cacheName;
|
|
|
+
|
|
|
+ @UnableCall
|
|
|
+ private long ttl;
|
|
|
+
|
|
|
+ public DatabaseQuery() {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public DatabaseQuery(DynamicDataSource dataSource) {
|
|
|
this.dataSource = dataSource;
|
|
|
+ this.template = dataSource.getJdbcTemplate();
|
|
|
+ }
|
|
|
+
|
|
|
+ @UnableCall
|
|
|
+ public void setPageProvider(PageProvider pageProvider) {
|
|
|
this.pageProvider = pageProvider;
|
|
|
+ }
|
|
|
+
|
|
|
+ @UnableCall
|
|
|
+ public void setRowMapper(RowMapper<Map<String, Object>> rowMapper) {
|
|
|
this.rowMapper = rowMapper;
|
|
|
}
|
|
|
|
|
|
- public DatabaseQuery(DynamicDataSource dataSource, PageProvider pageProvider, RowMapper<Map<String, Object>> rowMapper) {
|
|
|
+ @UnableCall
|
|
|
+ public void setDataSource(DynamicDataSource dataSource) {
|
|
|
this.dataSource = dataSource;
|
|
|
- this.pageProvider = pageProvider;
|
|
|
- this.rowMapper = rowMapper;
|
|
|
- this.template = dataSource.getJdbcTemplate(null);
|
|
|
+ }
|
|
|
+
|
|
|
+ @UnableCall
|
|
|
+ public void setSqlCache(SqlCache sqlCache) {
|
|
|
+ this.sqlCache = sqlCache;
|
|
|
+ }
|
|
|
+
|
|
|
+ @UnableCall
|
|
|
+ public void setTemplate(JdbcTemplate template) {
|
|
|
+ this.template = template;
|
|
|
+ }
|
|
|
+
|
|
|
+ @UnableCall
|
|
|
+ public void setCacheName(String cacheName) {
|
|
|
+ this.cacheName = cacheName;
|
|
|
+ }
|
|
|
+
|
|
|
+ @UnableCall
|
|
|
+ public void setTtl(long ttl) {
|
|
|
+ this.ttl = ttl;
|
|
|
+ }
|
|
|
+
|
|
|
+ @UnableCall
|
|
|
+ public DatabaseQuery cloneQuery() {
|
|
|
+ DatabaseQuery query = new DatabaseQuery();
|
|
|
+ query.setDataSource(this.dataSource);
|
|
|
+ query.setTemplate(this.template);
|
|
|
+ query.setPageProvider(this.pageProvider);
|
|
|
+ query.setRowMapper(this.rowMapper);
|
|
|
+ query.setSqlCache(this.sqlCache);
|
|
|
+ query.setTtl(this.ttl);
|
|
|
+ return query;
|
|
|
+ }
|
|
|
|
|
|
+ @UnableCall
|
|
|
+ private <T> T putCacheValue(T value, BoundSql boundSql) {
|
|
|
+ if (this.cacheName != null) {
|
|
|
+ this.sqlCache.put(this.cacheName, boundSql.getCacheKey(this.sqlCache), value, this.ttl);
|
|
|
+ }
|
|
|
+ return value;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public DatabaseQuery cache(String cacheName, long ttl) {
|
|
|
+ if (cacheName == null) {
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+ DatabaseQuery query = cloneQuery();
|
|
|
+ query.setCacheName(cacheName);
|
|
|
+ query.setTtl(ttl);
|
|
|
+ return query;
|
|
|
+ }
|
|
|
+
|
|
|
+ public DatabaseQuery cache(String cacheName) {
|
|
|
+ return cache(cacheName, 0);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public DatabaseQuery get(Object key) {
|
|
|
+ DatabaseQuery query = cloneQuery();
|
|
|
if (key == null) {
|
|
|
- return new DatabaseQuery(dataSource.getJdbcTemplate(null), this.dataSource, this.pageProvider, this.rowMapper);
|
|
|
+ query.setTemplate(dataSource.getJdbcTemplate());
|
|
|
+ } else {
|
|
|
+ query.setTemplate(dataSource.getJdbcTemplate(key.toString()));
|
|
|
}
|
|
|
- return new DatabaseQuery(dataSource.getJdbcTemplate(key.toString()), this.dataSource, this.pageProvider, this.rowMapper);
|
|
|
+ return query;
|
|
|
}
|
|
|
|
|
|
|
|
|
public Object select(String sql) {
|
|
|
BoundSql boundSql = new BoundSql(sql);
|
|
|
- return template.query(boundSql.getSql(), this.rowMapper, boundSql.getParameters());
|
|
|
+ return boundSql.getCacheValue(this.sqlCache, this.cacheName)
|
|
|
+ .orElseGet(() -> putCacheValue(template.query(boundSql.getSql(), this.rowMapper, boundSql.getParameters()), boundSql));
|
|
|
+ }
|
|
|
+
|
|
|
+ public int update(String sql) {
|
|
|
+ BoundSql boundSql = new BoundSql(sql);
|
|
|
+ int value = template.update(boundSql.getSql(), boundSql.getParameters());
|
|
|
+ if (this.cacheName != null) {
|
|
|
+ this.sqlCache.delete(this.cacheName);
|
|
|
+ }
|
|
|
+ return value;
|
|
|
}
|
|
|
|
|
|
public Object page(String sql) {
|
|
@@ -74,7 +166,8 @@ public class DatabaseQuery extends HashMap<String, DatabaseQuery> {
|
|
|
try {
|
|
|
connection = template.getDataSource().getConnection();
|
|
|
dialect = DialectUtils.getDialectFromUrl(connection.getMetaData().getURL());
|
|
|
- count = template.queryForObject(dialect.getCountSql(boundSql.getSql()), Integer.class, boundSql.getParameters());
|
|
|
+ count = (int) boundSql.getCacheValue(this.sqlCache, this.cacheName)
|
|
|
+ .orElseGet(() -> putCacheValue(template.queryForObject(dialect.getCountSql(boundSql.getSql()), Integer.class, boundSql.getParameters()), boundSql));
|
|
|
result.setTotal(count);
|
|
|
} catch (SQLException e) {
|
|
|
throw new MagicAPIException("自动获取数据库方言失败", e);
|
|
@@ -83,25 +176,31 @@ public class DatabaseQuery extends HashMap<String, DatabaseQuery> {
|
|
|
}
|
|
|
if (count > 0) {
|
|
|
String pageSql = dialect.getPageSql(boundSql.getSql(), boundSql, offset, limit);
|
|
|
- result.setList(template.query(pageSql, this.rowMapper, boundSql.getParameters()));
|
|
|
+ result.setList((List<Map<String, Object>>) boundSql.removeCacheKey().getCacheValue(this.sqlCache, this.cacheName)
|
|
|
+ .orElseGet(() -> putCacheValue(template.query(pageSql, this.rowMapper, boundSql.getParameters()), boundSql)));
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
public Integer selectInt(String sql) {
|
|
|
BoundSql boundSql = new BoundSql(sql);
|
|
|
- return template.queryForObject(boundSql.getSql(), boundSql.getParameters(), Integer.class);
|
|
|
+ return (Integer) boundSql.getCacheValue(this.sqlCache, this.cacheName)
|
|
|
+ .orElseGet(() -> putCacheValue(template.queryForObject(boundSql.getSql(), boundSql.getParameters(), Integer.class), boundSql));
|
|
|
}
|
|
|
|
|
|
- public Map<String, Object> selectOne(String sql) {
|
|
|
+ public Object selectOne(String sql) {
|
|
|
BoundSql boundSql = new BoundSql(sql);
|
|
|
- List<Map<String, Object>> list = template.query(boundSql.getSql(), this.rowMapper, boundSql.getParameters());
|
|
|
- return list != null && list.size() > 0 ? list.get(0) : null;
|
|
|
+ return boundSql.getCacheValue(this.sqlCache, this.cacheName)
|
|
|
+ .orElseGet(() -> {
|
|
|
+ List<Map<String, Object>> list = template.query(boundSql.getSql(), this.rowMapper, boundSql.getParameters());
|
|
|
+ return list != null && list.size() > 0 ? list.get(0) : null;
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
public Object selectValue(String sql) {
|
|
|
BoundSql boundSql = new BoundSql(sql);
|
|
|
- return template.queryForObject(boundSql.getSql(), boundSql.getParameters(), Object.class);
|
|
|
+ return boundSql.getCacheValue(this.sqlCache, this.cacheName)
|
|
|
+ .orElseGet(() -> putCacheValue(template.queryForObject(boundSql.getSql(), boundSql.getParameters(), Object.class), boundSql));
|
|
|
}
|
|
|
|
|
|
private static Tokenizer tokenizer = new Tokenizer();
|
|
@@ -117,6 +216,8 @@ public class DatabaseQuery extends HashMap<String, DatabaseQuery> {
|
|
|
public static class BoundSql {
|
|
|
private String sql;
|
|
|
private List<Object> parameters = new ArrayList<>();
|
|
|
+ private String cacheKey;
|
|
|
+
|
|
|
|
|
|
BoundSql(String sql) {
|
|
|
MagicScriptContext context = MagicScriptContext.get();
|
|
@@ -150,6 +251,22 @@ public class DatabaseQuery extends HashMap<String, DatabaseQuery> {
|
|
|
public Object[] getParameters() {
|
|
|
return parameters.toArray();
|
|
|
}
|
|
|
+
|
|
|
+ public BoundSql removeCacheKey() {
|
|
|
+ this.cacheKey = null;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ public String getCacheKey(SqlCache sqlCache) {
|
|
|
+ if (cacheKey == null) {
|
|
|
+ cacheKey = sqlCache.buildSqlCacheKey(this);
|
|
|
+ }
|
|
|
+ return cacheKey;
|
|
|
+ }
|
|
|
+
|
|
|
+ public <T> Optional<T> getCacheValue(SqlCache sqlCache, String cacheName) {
|
|
|
+ return Optional.ofNullable(cacheName == null ? null : sqlCache.get(cacheName, getCacheKey(sqlCache)));
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
}
|