From 07d2ca87b9f3af1c100eb5e16487c9d80ff7aed6 Mon Sep 17 00:00:00 2001 From: redkale Date: Thu, 6 Jun 2024 08:32:52 +0800 Subject: [PATCH] nativePageSql --- .../redkale/source/AbstractDataSource.java | 17 +---- .../redkale/source/AbstractDataSqlSource.java | 73 +++++++++++++++---- .../org/redkale/source/DataJdbcSource.java | 6 +- .../source/DataNativeSqlStatement.java | 11 +++ .../java/org/redkale/source/EntityInfo.java | 48 ------------ 5 files changed, 75 insertions(+), 80 deletions(-) diff --git a/src/main/java/org/redkale/source/AbstractDataSource.java b/src/main/java/org/redkale/source/AbstractDataSource.java index 5aecb05e9..cc4884769 100644 --- a/src/main/java/org/redkale/source/AbstractDataSource.java +++ b/src/main/java/org/redkale/source/AbstractDataSource.java @@ -5,9 +5,6 @@ */ package org.redkale.source; -import static org.redkale.boot.Application.RESNAME_APP_EXECUTOR; -import static org.redkale.source.DataSources.*; - import java.io.Serializable; import java.net.InetSocketAddress; import java.util.*; @@ -19,12 +16,14 @@ import org.redkale.annotation.*; import org.redkale.annotation.AutoLoad; import org.redkale.annotation.Comment; import org.redkale.annotation.ResourceType; +import static org.redkale.boot.Application.RESNAME_APP_EXECUTOR; import org.redkale.convert.json.JsonConvert; import org.redkale.inject.Resourcable; import org.redkale.inject.ResourceEvent; import org.redkale.net.WorkThread; import org.redkale.persistence.Entity; import org.redkale.service.*; +import static org.redkale.source.DataSources.*; import org.redkale.util.*; /** @@ -223,18 +222,6 @@ public abstract class AbstractDataSource extends AbstractService implements Data return info.getBuilder().getEntityValue(sels, row); } - /** - * 根据翻页参数构建排序SQL - * - * @param 泛型 - * @param info EntityInfo - * @param flipper 翻页参数 - * @return SQL - */ - protected String createOrderbySql(EntityInfo info, Flipper flipper) { - return info.createOrderbySql(flipper); - } - /** * 根据过滤条件生成关联表与别名的映射关系 * diff --git a/src/main/java/org/redkale/source/AbstractDataSqlSource.java b/src/main/java/org/redkale/source/AbstractDataSqlSource.java index 790fc2189..c2efa1f12 100644 --- a/src/main/java/org/redkale/source/AbstractDataSqlSource.java +++ b/src/main/java/org/redkale/source/AbstractDataSqlSource.java @@ -82,6 +82,9 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource protected final IntFunction signFunc = index -> prepareParamSign(index); + // Flipper.sort转换成以ORDER BY开头SQL的缓存 + protected final Map sortOrderbySqls = new ConcurrentHashMap<>(); + // 超过多少毫秒视为较慢, 会打印警告级别的日志, 默认值: 2000 protected long slowmsWarn; @@ -156,7 +159,7 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource readConfProps.getProperty(DATA_SOURCE_SLOWMS_ERROR, "3000").trim()); } - protected String createLimitSQL(String listSql, Flipper flipper) { + protected String createLimitSql(String listSql, Flipper flipper) { if (flipper == null || flipper.getLimit() < 1) { return listSql; } @@ -167,6 +170,47 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource throw new SourceException("Not support page sql: " + listSql); } + /** + * 根据Flipper获取ORDER BY的SQL语句,不存在Flipper或sort字段返回空字符串 + * + * @param flipper 翻页对象 + * @return String + */ + protected String createOrderbySql(EntityInfo info, Flipper flipper) { + if (flipper == null || Utility.isEmpty(flipper.getSort())) { + return ""; + } + final String sort = flipper.getSort(); + if (sort.indexOf(';') >= 0 || sort.indexOf('\n') >= 0) { + return ""; + } + return sortOrderbySqls.computeIfAbsent(sort, s -> { + final StringBuilder sb = new StringBuilder(); + sb.append(" ORDER BY "); + if (info.getBuilder().isNoAlias()) { + sb.append(s); + } else { + boolean flag = false; + for (String item : s.split(",")) { + if (item.isEmpty()) { + continue; + } + String[] sub = item.split("\\s+"); + if (flag) { + sb.append(','); + } + if (sub.length < 2 || sub[1].equalsIgnoreCase("ASC")) { + sb.append(info.getSQLColumn("a", sub[0])).append(" ASC"); + } else { + sb.append(info.getSQLColumn("a", sub[0])).append(" DESC"); + } + flag = true; + } + } + return sb.toString(); + }); + } + @Override @ResourceChanged public void onResourceChange(ResourceEvent[] events) { @@ -336,7 +380,8 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource // #{oldtable} LIMIT 0)"); props.setProperty( DATA_SOURCE_TABLECOPY_SQLTEMPLATE, - "CREATE TABLE IF NOT EXISTS #{newtable} (LIKE #{oldtable} INCLUDING DEFAULTS INCLUDING CONSTRAINTS INCLUDING COMMENTS INCLUDING INDEXES)"); + "CREATE TABLE IF NOT EXISTS #{newtable} (LIKE #{oldtable} " + + "INCLUDING DEFAULTS INCLUDING CONSTRAINTS INCLUDING COMMENTS INCLUDING INDEXES)"); } if (!props.containsKey(DATA_SOURCE_TABLENOTEXIST_SQLSTATES)) { props.setProperty(DATA_SOURCE_TABLENOTEXIST_SQLSTATES, "42P01;3F000"); @@ -719,11 +764,11 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource return sqlCode != null && !sqlCode.isEmpty() && tableNotExistSqlstates.contains(';' + sqlCode + ';'); } - protected String getTableCopySQL(EntityInfo info, String newTable) { + protected String getTableCopySql(EntityInfo info, String newTable) { return tablecopySQL.replace("#{newtable}", newTable).replace("#{oldtable}", info.table); } - protected Serializable getSQLAttrValue(EntityInfo info, Attribute attr, Serializable val) { + protected Serializable getSQLAttrValue(EntityInfo info, Attribute attr, Serializable val) { if (val != null && !(val instanceof Number) && !(val instanceof CharSequence) @@ -1468,7 +1513,7 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource String sql = "DELETE FROM " + table + " a" + (join1 == null ? "" : (", " + join1)) + " WHERE " + info.getPrimarySQLColumn() + " IN (SELECT " + info.getPrimaryField() + " FROM " + table - + join2AndWhere + info.createOrderbySql(flipper) + " OFFSET 0 LIMIT " + flipper.getLimit() + + join2AndWhere + createOrderbySql(info, flipper) + " OFFSET 0 LIMIT " + flipper.getLimit() + ")"; sqls.add(sql); } @@ -1478,7 +1523,7 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource List sqls = new ArrayList<>(); for (String table : tables) { String sql = "DELETE " + (mysql ? "a" : "") + " FROM " + table + " a" - + (join1 == null ? "" : (", " + join1)) + join2AndWhere + info.createOrderbySql(flipper) + + (join1 == null ? "" : (", " + join1)) + join2AndWhere + createOrderbySql(info, flipper) + ((mysql && flipper != null && flipper.getLimit() > 0) ? (" LIMIT " + flipper.getLimit()) : ""); @@ -1562,7 +1607,7 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource if (sqls == null) { return -1; } - String copyTableSql = info.getTableStrategy() == null ? null : getTableCopySQL(info, info.getTable(pk)); + String copyTableSql = info.getTableStrategy() == null ? null : getTableCopySql(info, info.getTable(pk)); if (info.isLoggable(logger, Level.FINEST, sqls[0])) { logger.finest(info.getType().getSimpleName() + " createTable sql=" + Arrays.toString(sqls)); } @@ -1582,7 +1627,7 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource if (sqls == null) { return CompletableFuture.completedFuture(-1); } - String copyTableSql = info.getTableStrategy() == null ? null : getTableCopySQL(info, info.getTable(pk)); + String copyTableSql = info.getTableStrategy() == null ? null : getTableCopySql(info, info.getTable(pk)); if (copyTableSql == null) { if (info.isLoggable(logger, Level.FINEST, sqls[0])) { logger.finest(info.getType().getSimpleName() + " createTable sql=" + Arrays.toString(sqls)); @@ -2154,14 +2199,14 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource sql = "UPDATE " + tables[0] + " a " + (join1 == null ? "" : (", " + join1)) + " SET " + setsql + " WHERE " + info.getPrimarySQLColumn() + " IN (SELECT " + info.getPrimaryField() + " FROM " + tables[0] - + wherestr + info.createOrderbySql(flipper) + " OFFSET 0 LIMIT " + flipper.getLimit() + ")"; + + wherestr + createOrderbySql(info, flipper) + " OFFSET 0 LIMIT " + flipper.getLimit() + ")"; } else { sql = "UPDATE " + tables[0] + " a " + (join1 == null ? "" : (", " + join1)) + " SET " + setsql + ((where == null || where.length() == 0) ? (join2 == null ? "" : (" WHERE " + join2)) : (" WHERE " + where + (join2 == null ? "" : (" AND " + join2)))) - + info.createOrderbySql(flipper) + + createOrderbySql(info, flipper) + (("mysql".equals(dbtype()) && flipper != null && flipper.getLimit() > 0) ? (" LIMIT " + flipper.getLimit()) : ""); @@ -2703,7 +2748,7 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource } final String[] tables = info.getTables(node); - String sql = queryColumnMapSql(info, tables, keyColumn, func, funcColumn, node); + String sql = AbstractDataSqlSource.this.queryColumnMapSql(info, tables, keyColumn, func, funcColumn, node); if (info.isLoggable(logger, Level.FINEST, sql)) { logger.finest(info.getType().getSimpleName() + " queryColumnMap sql=" + sql); } @@ -2730,7 +2775,7 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource } } final String[] tables = info.getTables(node); - String sql = queryColumnMapSql(info, tables, keyColumn, func, funcColumn, node); + String sql = AbstractDataSqlSource.this.queryColumnMapSql(info, tables, keyColumn, func, funcColumn, node); if (info.isLoggable(logger, Level.FINEST, sql)) { logger.finest(info.getType().getSimpleName() + " queryColumnMap sql=" + sql); } @@ -3060,7 +3105,7 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource protected T findUnCache(final EntityInfo info, final SelectColumn selects, final Serializable pk) { String[] tables = info.getTableOneArray(pk); - String sql = findSql(info, selects, pk); + String sql = AbstractDataSqlSource.this.findSql(info, selects, pk); if (info.isLoggable(logger, Level.FINEST, sql)) { logger.finest(info.getType().getSimpleName() + " find sql=" + sql); } @@ -3074,7 +3119,7 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource protected CompletableFuture findUnCacheAsync( final EntityInfo info, final SelectColumn selects, final Serializable pk) { String[] tables = info.getTableOneArray(pk); - String sql = findSql(info, selects, pk); + String sql = AbstractDataSqlSource.this.findSql(info, selects, pk); if (info.isLoggable(logger, Level.FINEST, sql)) { logger.finest(info.getType().getSimpleName() + " find sql=" + sql); } diff --git a/src/main/java/org/redkale/source/DataJdbcSource.java b/src/main/java/org/redkale/source/DataJdbcSource.java index e6285988a..38a271064 100644 --- a/src/main/java/org/redkale/source/DataJdbcSource.java +++ b/src/main/java/org/redkale/source/DataJdbcSource.java @@ -453,7 +453,7 @@ public class DataJdbcSource extends AbstractDataSqlSource { if (pos > 0) { newCatalogs.add(t.substring(0, pos)); } - tableCopys.add(getTableCopySQL(info, t)); + tableCopys.add(getTableCopySql(info, t)); }); try { // 执行一遍创建分表操作 @@ -2584,7 +2584,7 @@ public class DataJdbcSource extends AbstractDataSqlSource { + (union) + ") a"; } listSql = listSubSql + createOrderbySql(info, flipper); - listSql = createLimitSQL(listSql, flipper); + listSql = createLimitSql(listSql, flipper); if (readCache && info.isLoggable(logger, Level.FINEST, listSql)) { logger.finest(info.getType().getSimpleName() + " query sql=" + listSql); } @@ -2862,7 +2862,7 @@ public class DataJdbcSource extends AbstractDataSqlSource { } slowLog(s, countSql); if (total > 0) { - String listSql = createLimitSQL(sinfo.getNativeSql(), flipper); + String listSql = createLimitSql(sinfo.getNativePageSql(), flipper); if (sinfo.isEmptyNamed()) { Statement stmt = conn.createQueryStatement(); ResultSet set = stmt.executeQuery(listSql); diff --git a/src/main/java/org/redkale/source/DataNativeSqlStatement.java b/src/main/java/org/redkale/source/DataNativeSqlStatement.java index 4af066c32..8826fb22c 100644 --- a/src/main/java/org/redkale/source/DataNativeSqlStatement.java +++ b/src/main/java/org/redkale/source/DataNativeSqlStatement.java @@ -42,6 +42,9 @@ public class DataNativeSqlStatement { // 根据参数值集合重新生成的带?参数可执行的sql protected String nativeSql; + // 根据参数值集合重新生成的带?参数可执行的sql + protected String nativePageSql; + // 根据参数值集合重新生成的带?参数可执行的计算总数sql,用于返回Sheet对象 @Nullable protected String nativeCountSql; @@ -73,6 +76,14 @@ public class DataNativeSqlStatement { this.nativeSql = nativeSql; } + public String getNativePageSql() { + return nativePageSql == null ? nativeSql : nativePageSql; + } + + public void setNativePageSql(String nativePageSql) { + this.nativePageSql = nativePageSql; + } + public String getNativeCountSql() { return nativeCountSql; } diff --git a/src/main/java/org/redkale/source/EntityInfo.java b/src/main/java/org/redkale/source/EntityInfo.java index cfa489e80..58041ee1b 100644 --- a/src/main/java/org/redkale/source/EntityInfo.java +++ b/src/main/java/org/redkale/source/EntityInfo.java @@ -196,9 +196,6 @@ public final class EntityInfo { // 日志控制 private final Map excludeLogLevels; - // Flipper.sort转换成以ORDER BY开头SQL的缓存 - private final Map sortOrderbySqls = new ConcurrentHashMap<>(); - // 所属的DataSource final DataSource source; @@ -1409,51 +1406,6 @@ public final class EntityInfo { return this.updateAttributeMap.get(fieldname); } - /** - * 根据Flipper获取ORDER BY的SQL语句,不存在Flipper或sort字段返回空字符串 - * - * @param flipper 翻页对象 - * @return String - */ - protected String createOrderbySql(Flipper flipper) { - if (flipper == null || flipper.getSort() == null) { - return ""; - } - final String sort = flipper.getSort(); - if (sort.isEmpty() || sort.indexOf(';') >= 0 || sort.indexOf('\n') >= 0) { - return ""; - } - String sql = this.sortOrderbySqls.get(sort); - if (sql != null) { - return sql; - } - final StringBuilder sb = new StringBuilder(); - sb.append(" ORDER BY "); - if (builder.isNoAlias()) { - sb.append(sort); - } else { - boolean flag = false; - for (String item : sort.split(",")) { - if (item.isEmpty()) { - continue; - } - String[] sub = item.split("\\s+"); - if (flag) { - sb.append(','); - } - if (sub.length < 2 || sub[1].equalsIgnoreCase("ASC")) { - sb.append(getSQLColumn("a", sub[0])).append(" ASC"); - } else { - sb.append(getSQLColumn("a", sub[0])).append(" DESC"); - } - flag = true; - } - } - sql = sb.toString(); - this.sortOrderbySqls.put(sort, sql); - return sql; - } - /** * 根据field字段名获取数据库对应的字段名 *