nativePageSql

This commit is contained in:
redkale
2024-06-06 08:32:52 +08:00
parent 5a8557bf63
commit 07d2ca87b9
5 changed files with 75 additions and 80 deletions

View File

@@ -5,9 +5,6 @@
*/ */
package org.redkale.source; 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.io.Serializable;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.*; import java.util.*;
@@ -19,12 +16,14 @@ import org.redkale.annotation.*;
import org.redkale.annotation.AutoLoad; import org.redkale.annotation.AutoLoad;
import org.redkale.annotation.Comment; import org.redkale.annotation.Comment;
import org.redkale.annotation.ResourceType; import org.redkale.annotation.ResourceType;
import static org.redkale.boot.Application.RESNAME_APP_EXECUTOR;
import org.redkale.convert.json.JsonConvert; import org.redkale.convert.json.JsonConvert;
import org.redkale.inject.Resourcable; import org.redkale.inject.Resourcable;
import org.redkale.inject.ResourceEvent; import org.redkale.inject.ResourceEvent;
import org.redkale.net.WorkThread; import org.redkale.net.WorkThread;
import org.redkale.persistence.Entity; import org.redkale.persistence.Entity;
import org.redkale.service.*; import org.redkale.service.*;
import static org.redkale.source.DataSources.*;
import org.redkale.util.*; import org.redkale.util.*;
/** /**
@@ -223,18 +222,6 @@ public abstract class AbstractDataSource extends AbstractService implements Data
return info.getBuilder().getEntityValue(sels, row); return info.getBuilder().getEntityValue(sels, row);
} }
/**
* 根据翻页参数构建排序SQL
*
* @param <T> 泛型
* @param info EntityInfo
* @param flipper 翻页参数
* @return SQL
*/
protected <T> String createOrderbySql(EntityInfo<T> info, Flipper flipper) {
return info.createOrderbySql(flipper);
}
/** /**
* 根据过滤条件生成关联表与别名的映射关系 * 根据过滤条件生成关联表与别名的映射关系
* *

View File

@@ -82,6 +82,9 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource
protected final IntFunction<String> signFunc = index -> prepareParamSign(index); protected final IntFunction<String> signFunc = index -> prepareParamSign(index);
// Flipper.sort转换成以ORDER BY开头SQL的缓存
protected final Map<String, String> sortOrderbySqls = new ConcurrentHashMap<>();
// 超过多少毫秒视为较慢, 会打印警告级别的日志, 默认值: 2000 // 超过多少毫秒视为较慢, 会打印警告级别的日志, 默认值: 2000
protected long slowmsWarn; protected long slowmsWarn;
@@ -156,7 +159,7 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource
readConfProps.getProperty(DATA_SOURCE_SLOWMS_ERROR, "3000").trim()); 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) { if (flipper == null || flipper.getLimit() < 1) {
return listSql; return listSql;
} }
@@ -167,6 +170,47 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource
throw new SourceException("Not support page sql: " + listSql); 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 @Override
@ResourceChanged @ResourceChanged
public void onResourceChange(ResourceEvent[] events) { public void onResourceChange(ResourceEvent[] events) {
@@ -336,7 +380,8 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource
// #{oldtable} LIMIT 0)"); // #{oldtable} LIMIT 0)");
props.setProperty( props.setProperty(
DATA_SOURCE_TABLECOPY_SQLTEMPLATE, 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)) { if (!props.containsKey(DATA_SOURCE_TABLENOTEXIST_SQLSTATES)) {
props.setProperty(DATA_SOURCE_TABLENOTEXIST_SQLSTATES, "42P01;3F000"); 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 + ';'); 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); return tablecopySQL.replace("#{newtable}", newTable).replace("#{oldtable}", info.table);
} }
protected <T> Serializable getSQLAttrValue(EntityInfo info, Attribute attr, Serializable val) { protected Serializable getSQLAttrValue(EntityInfo info, Attribute attr, Serializable val) {
if (val != null if (val != null
&& !(val instanceof Number) && !(val instanceof Number)
&& !(val instanceof CharSequence) && !(val instanceof CharSequence)
@@ -1468,7 +1513,7 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource
String sql = "DELETE FROM " + table + " a" + (join1 == null ? "" : (", " + join1)) String sql = "DELETE FROM " + table + " a" + (join1 == null ? "" : (", " + join1))
+ " WHERE " + info.getPrimarySQLColumn() + " IN (SELECT " + info.getPrimaryField() + " FROM " + " WHERE " + info.getPrimarySQLColumn() + " IN (SELECT " + info.getPrimaryField() + " FROM "
+ table + table
+ join2AndWhere + info.createOrderbySql(flipper) + " OFFSET 0 LIMIT " + flipper.getLimit() + join2AndWhere + createOrderbySql(info, flipper) + " OFFSET 0 LIMIT " + flipper.getLimit()
+ ")"; + ")";
sqls.add(sql); sqls.add(sql);
} }
@@ -1478,7 +1523,7 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource
List<String> sqls = new ArrayList<>(); List<String> sqls = new ArrayList<>();
for (String table : tables) { for (String table : tables) {
String sql = "DELETE " + (mysql ? "a" : "") + " FROM " + table + " a" 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) + ((mysql && flipper != null && flipper.getLimit() > 0)
? (" LIMIT " + flipper.getLimit()) ? (" LIMIT " + flipper.getLimit())
: ""); : "");
@@ -1562,7 +1607,7 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource
if (sqls == null) { if (sqls == null) {
return -1; 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])) { if (info.isLoggable(logger, Level.FINEST, sqls[0])) {
logger.finest(info.getType().getSimpleName() + " createTable sql=" + Arrays.toString(sqls)); logger.finest(info.getType().getSimpleName() + " createTable sql=" + Arrays.toString(sqls));
} }
@@ -1582,7 +1627,7 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource
if (sqls == null) { if (sqls == null) {
return CompletableFuture.completedFuture(-1); 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 (copyTableSql == null) {
if (info.isLoggable(logger, Level.FINEST, sqls[0])) { if (info.isLoggable(logger, Level.FINEST, sqls[0])) {
logger.finest(info.getType().getSimpleName() + " createTable sql=" + Arrays.toString(sqls)); 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 sql = "UPDATE " + tables[0] + " a " + (join1 == null ? "" : (", " + join1)) + " SET " + setsql
+ " WHERE " + info.getPrimarySQLColumn() + " IN (SELECT " + info.getPrimaryField() + " FROM " + " WHERE " + info.getPrimarySQLColumn() + " IN (SELECT " + info.getPrimaryField() + " FROM "
+ tables[0] + tables[0]
+ wherestr + info.createOrderbySql(flipper) + " OFFSET 0 LIMIT " + flipper.getLimit() + ")"; + wherestr + createOrderbySql(info, flipper) + " OFFSET 0 LIMIT " + flipper.getLimit() + ")";
} else { } else {
sql = "UPDATE " + tables[0] + " a " + (join1 == null ? "" : (", " + join1)) + " SET " + setsql sql = "UPDATE " + tables[0] + " a " + (join1 == null ? "" : (", " + join1)) + " SET " + setsql
+ ((where == null || where.length() == 0) + ((where == null || where.length() == 0)
? (join2 == null ? "" : (" WHERE " + join2)) ? (join2 == null ? "" : (" WHERE " + join2))
: (" WHERE " + where + (join2 == null ? "" : (" AND " + join2)))) : (" WHERE " + where + (join2 == null ? "" : (" AND " + join2))))
+ info.createOrderbySql(flipper) + createOrderbySql(info, flipper)
+ (("mysql".equals(dbtype()) && flipper != null && flipper.getLimit() > 0) + (("mysql".equals(dbtype()) && flipper != null && flipper.getLimit() > 0)
? (" LIMIT " + flipper.getLimit()) ? (" LIMIT " + flipper.getLimit())
: ""); : "");
@@ -2703,7 +2748,7 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource
} }
final String[] tables = info.getTables(node); 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)) { if (info.isLoggable(logger, Level.FINEST, sql)) {
logger.finest(info.getType().getSimpleName() + " queryColumnMap sql=" + 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); 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)) { if (info.isLoggable(logger, Level.FINEST, sql)) {
logger.finest(info.getType().getSimpleName() + " queryColumnMap sql=" + sql); logger.finest(info.getType().getSimpleName() + " queryColumnMap sql=" + sql);
} }
@@ -3060,7 +3105,7 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource
protected <T> T findUnCache(final EntityInfo<T> info, final SelectColumn selects, final Serializable pk) { protected <T> T findUnCache(final EntityInfo<T> info, final SelectColumn selects, final Serializable pk) {
String[] tables = info.getTableOneArray(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)) { if (info.isLoggable(logger, Level.FINEST, sql)) {
logger.finest(info.getType().getSimpleName() + " find sql=" + sql); logger.finest(info.getType().getSimpleName() + " find sql=" + sql);
} }
@@ -3074,7 +3119,7 @@ public abstract class AbstractDataSqlSource extends AbstractDataSource
protected <T> CompletableFuture<T> findUnCacheAsync( protected <T> CompletableFuture<T> findUnCacheAsync(
final EntityInfo<T> info, final SelectColumn selects, final Serializable pk) { final EntityInfo<T> info, final SelectColumn selects, final Serializable pk) {
String[] tables = info.getTableOneArray(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)) { if (info.isLoggable(logger, Level.FINEST, sql)) {
logger.finest(info.getType().getSimpleName() + " find sql=" + sql); logger.finest(info.getType().getSimpleName() + " find sql=" + sql);
} }

View File

@@ -453,7 +453,7 @@ public class DataJdbcSource extends AbstractDataSqlSource {
if (pos > 0) { if (pos > 0) {
newCatalogs.add(t.substring(0, pos)); newCatalogs.add(t.substring(0, pos));
} }
tableCopys.add(getTableCopySQL(info, t)); tableCopys.add(getTableCopySql(info, t));
}); });
try { try {
// 执行一遍创建分表操作 // 执行一遍创建分表操作
@@ -2584,7 +2584,7 @@ public class DataJdbcSource extends AbstractDataSqlSource {
+ (union) + ") a"; + (union) + ") a";
} }
listSql = listSubSql + createOrderbySql(info, flipper); listSql = listSubSql + createOrderbySql(info, flipper);
listSql = createLimitSQL(listSql, flipper); listSql = createLimitSql(listSql, flipper);
if (readCache && info.isLoggable(logger, Level.FINEST, listSql)) { if (readCache && info.isLoggable(logger, Level.FINEST, listSql)) {
logger.finest(info.getType().getSimpleName() + " query sql=" + listSql); logger.finest(info.getType().getSimpleName() + " query sql=" + listSql);
} }
@@ -2862,7 +2862,7 @@ public class DataJdbcSource extends AbstractDataSqlSource {
} }
slowLog(s, countSql); slowLog(s, countSql);
if (total > 0) { if (total > 0) {
String listSql = createLimitSQL(sinfo.getNativeSql(), flipper); String listSql = createLimitSql(sinfo.getNativePageSql(), flipper);
if (sinfo.isEmptyNamed()) { if (sinfo.isEmptyNamed()) {
Statement stmt = conn.createQueryStatement(); Statement stmt = conn.createQueryStatement();
ResultSet set = stmt.executeQuery(listSql); ResultSet set = stmt.executeQuery(listSql);

View File

@@ -42,6 +42,9 @@ public class DataNativeSqlStatement {
// 根据参数值集合重新生成的带?参数可执行的sql // 根据参数值集合重新生成的带?参数可执行的sql
protected String nativeSql; protected String nativeSql;
// 根据参数值集合重新生成的带?参数可执行的sql
protected String nativePageSql;
// 根据参数值集合重新生成的带?参数可执行的计算总数sql,用于返回Sheet对象 // 根据参数值集合重新生成的带?参数可执行的计算总数sql,用于返回Sheet对象
@Nullable @Nullable
protected String nativeCountSql; protected String nativeCountSql;
@@ -73,6 +76,14 @@ public class DataNativeSqlStatement {
this.nativeSql = nativeSql; this.nativeSql = nativeSql;
} }
public String getNativePageSql() {
return nativePageSql == null ? nativeSql : nativePageSql;
}
public void setNativePageSql(String nativePageSql) {
this.nativePageSql = nativePageSql;
}
public String getNativeCountSql() { public String getNativeCountSql() {
return nativeCountSql; return nativeCountSql;
} }

View File

@@ -196,9 +196,6 @@ public final class EntityInfo<T> {
// 日志控制 // 日志控制
private final Map<Integer, String[]> excludeLogLevels; private final Map<Integer, String[]> excludeLogLevels;
// Flipper.sort转换成以ORDER BY开头SQL的缓存
private final Map<String, String> sortOrderbySqls = new ConcurrentHashMap<>();
// 所属的DataSource // 所属的DataSource
final DataSource source; final DataSource source;
@@ -1409,51 +1406,6 @@ public final class EntityInfo<T> {
return this.updateAttributeMap.get(fieldname); 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字段名获取数据库对应的字段名 * 根据field字段名获取数据库对应的字段名
* *