diff --git a/src/main/java/org/redkale/boot/LoggingSearchHandler.java b/src/main/java/org/redkale/boot/LoggingSearchHandler.java
index 00e318c96..22fcebc53 100644
--- a/src/main/java/org/redkale/boot/LoggingSearchHandler.java
+++ b/src/main/java/org/redkale/boot/LoggingSearchHandler.java
@@ -6,10 +6,9 @@ import java.io.*;
import java.util.*;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
-import java.util.logging.*;
import java.util.logging.Formatter;
+import java.util.logging.*;
import java.util.regex.Pattern;
-
import static org.redkale.boot.Application.RESNAME_APP_NAME;
import org.redkale.convert.*;
import org.redkale.convert.json.JsonConvert;
@@ -18,7 +17,6 @@ import org.redkale.persistence.*;
import org.redkale.source.*;
import org.redkale.util.*;
-
/**
* 基于SearchSource的日志输出类
*
@@ -305,7 +303,7 @@ public class LoggingSearchHandler extends LoggingBaseHandler {
}
@Override
- public String getTable(String table, FilterNode node) {
+ public String[] getTables(String table, FilterNode node) {
throw new UnsupportedOperationException("Not supported yet.");
}
diff --git a/src/main/java/org/redkale/source/DataJdbcSource.java b/src/main/java/org/redkale/source/DataJdbcSource.java
index cd50f9c26..557f0ca5a 100644
--- a/src/main/java/org/redkale/source/DataJdbcSource.java
+++ b/src/main/java/org/redkale/source/DataJdbcSource.java
@@ -315,19 +315,53 @@ public class DataJdbcSource extends DataSqlSource {
}
@Override
- protected CompletableFuture deleteDB(EntityInfo info, Flipper flipper, String sql) {
+ protected CompletableFuture deleteDB(EntityInfo info, Flipper flipper, String... sqls) {
Connection conn = null;
final long s = System.currentTimeMillis();
try {
conn = writePool.pollConnection();
conn.setReadOnly(false);
conn.setAutoCommit(true);
- sql += ((flipper == null || flipper.getLimit() < 1) ? "" : (" LIMIT " + flipper.getLimit()));
- if (info.isLoggable(logger, Level.FINEST, sql)) logger.finest(info.getType().getSimpleName() + " delete sql=" + sql);
- final Statement stmt = conn.createStatement();
- int c = stmt.executeUpdate(sql);
- stmt.close();
- slowLog(s, sql);
+ int c = 0;
+ if (sqls.length == 1) {
+ String sql = sqls[0];
+ sql += ((flipper == null || flipper.getLimit() < 1) ? "" : (" LIMIT " + flipper.getLimit()));
+ if (info.isLoggable(logger, Level.FINEST, sql)) {
+ logger.finest(info.getType().getSimpleName() + " delete sql=" + sql);
+ }
+ final Statement stmt = conn.createStatement();
+ c = stmt.executeUpdate(sql);
+ stmt.close();
+ } else {
+ if (flipper == null || flipper.getLimit() < 1) {
+ if (info.isLoggable(logger, Level.FINEST, sqls[0])) {
+ logger.finest(info.getType().getSimpleName() + " delete sqls=" + Arrays.toString(sqls));
+ }
+ final Statement stmt = conn.createStatement();
+ for (String sql : sqls) {
+ stmt.addBatch(sql);
+ }
+ int[] cs = stmt.executeBatch();
+ stmt.close();
+ for (int cc : cs) {
+ c += cc;
+ }
+ } else {
+ if (info.isLoggable(logger, Level.FINEST, sqls[0])) {
+ logger.finest(info.getType().getSimpleName() + " limit " + flipper.getLimit() + " delete sqls=" + Arrays.toString(sqls));
+ }
+ final Statement stmt = conn.createStatement();
+ for (String sql : sqls) {
+ stmt.addBatch(sql + " LIMIT " + flipper.getLimit());
+ }
+ int[] cs = stmt.executeBatch();
+ stmt.close();
+ for (int cc : cs) {
+ c += cc;
+ }
+ }
+ }
+ slowLog(s, sqls);
return CompletableFuture.completedFuture(c);
} catch (SQLException e) {
if (isTableNotExist(info, e.getSQLState())) {
@@ -345,7 +379,6 @@ public class DataJdbcSource extends DataSqlSource {
st.executeBatch();
}
st.close();
- slowLog(s, sql);
return CompletableFuture.completedFuture(0);
} catch (SQLException e2) {
return CompletableFuture.failedFuture(e2);
@@ -360,17 +393,29 @@ public class DataJdbcSource extends DataSqlSource {
}
@Override
- protected CompletableFuture clearTableDB(EntityInfo info, final String table, String sql) {
+ protected CompletableFuture clearTableDB(EntityInfo info, final String[] tables, String... sqls) {
Connection conn = null;
final long s = System.currentTimeMillis();
try {
conn = writePool.pollConnection();
conn.setReadOnly(false);
conn.setAutoCommit(true);
+ int c = 0;
final Statement stmt = conn.createStatement();
- int c = stmt.executeUpdate(sql);
+ if (sqls.length == 1) {
+ String sql = sqls[0];
+ c = stmt.executeUpdate(sql);
+ } else {
+ for (String sql : sqls) {
+ stmt.addBatch(sql);
+ }
+ int[] cs = stmt.executeBatch();
+ for (int cc : cs) {
+ c += cc;
+ }
+ }
stmt.close();
- slowLog(s, sql);
+ slowLog(s, sqls);
return CompletableFuture.completedFuture(c);
} catch (SQLException e) {
if (isTableNotExist(info, e.getSQLState())) return CompletableFuture.completedFuture(-1);
@@ -381,21 +426,35 @@ public class DataJdbcSource extends DataSqlSource {
}
@Override
- protected CompletableFuture dropTableDB(EntityInfo info, final String table, String sql) {
+ protected CompletableFuture dropTableDB(EntityInfo info, String[] tables, String... sqls) {
Connection conn = null;
final long s = System.currentTimeMillis();
try {
conn = writePool.pollConnection();
conn.setReadOnly(false);
conn.setAutoCommit(true);
+ int c = 0;
final Statement stmt = conn.createStatement();
- int c = stmt.executeUpdate(sql);
+ if (sqls.length == 1) {
+ String sql = sqls[0];
+ c = stmt.executeUpdate(sql);
+ } else {
+ for (String sql : sqls) {
+ stmt.addBatch(sql);
+ }
+ int[] cs = stmt.executeBatch();
+ for (int cc : cs) {
+ c += cc;
+ }
+ }
stmt.close();
if (info.getTableStrategy() != null) {
- String tablekey = table.indexOf('.') > 0 ? table : (conn.getCatalog() + '.' + table);
- info.removeDisTable(tablekey);
+ for (String table : tables) {
+ String tablekey = table.indexOf('.') > 0 ? table : (conn.getCatalog() + '.' + table);
+ info.removeDisTable(tablekey);
+ }
}
- slowLog(s, sql);
+ slowLog(s, sqls);
return CompletableFuture.completedFuture(c);
} catch (SQLException e) {
if (isTableNotExist(info, e.getSQLState())) return CompletableFuture.completedFuture(-1);
@@ -480,31 +539,51 @@ public class DataJdbcSource extends DataSqlSource {
}
@Override
- protected CompletableFuture updateColumnDB(EntityInfo info, Flipper flipper, String sql, boolean prepared, Object... params) {
+ protected CompletableFuture updateColumnDB(EntityInfo info, Flipper flipper, SqlInfo sql) { //String sql, boolean prepared, Object... blobs) {
Connection conn = null;
final long s = System.currentTimeMillis();
try {
conn = writePool.pollConnection();
conn.setReadOnly(false);
conn.setAutoCommit(true);
- if (prepared) {
- final PreparedStatement prestmt = conn.prepareStatement(sql);
- int index = 0;
- for (Object param : params) {
- Blob blob = conn.createBlob();
- blob.setBytes(1, (byte[]) param);
- prestmt.setBlob(++index, blob);
+ if (sql.blobs != null || sql.tables != null) {
+ final PreparedStatement prestmt = conn.prepareStatement(sql.sql);
+ int c = 0;
+ if (sql.tables == null) {
+ int index = 0;
+ for (byte[] param : sql.blobs) {
+ Blob blob = conn.createBlob();
+ blob.setBytes(1, param);
+ prestmt.setBlob(++index, blob);
+ }
+ c = prestmt.executeUpdate();
+ } else {
+ for (String table : sql.tables) {
+ int index = 0;
+ if (sql.blobs != null) {
+ for (byte[] param : sql.blobs) {
+ Blob blob = conn.createBlob();
+ blob.setBytes(1, param);
+ prestmt.setBlob(++index, blob);
+ }
+ }
+ prestmt.setString(++index, table);
+ prestmt.addBatch();
+ }
+ int[] cs = prestmt.executeBatch();
+ for (int cc : cs) {
+ c += cc;
+ }
}
- int c = prestmt.executeUpdate();
prestmt.close();
- slowLog(s, sql);
+ slowLog(s, sql.sql);
return CompletableFuture.completedFuture(c);
} else {
- if (info.isLoggable(logger, Level.FINEST, sql)) logger.finest(info.getType().getSimpleName() + " update sql=" + sql);
+ if (info.isLoggable(logger, Level.FINEST, sql.sql)) logger.finest(info.getType().getSimpleName() + " update sql=" + sql);
final Statement stmt = conn.createStatement();
- int c = stmt.executeUpdate(sql);
+ int c = stmt.executeUpdate(sql.sql);
stmt.close();
- slowLog(s, sql);
+ slowLog(s, sql.sql);
return CompletableFuture.completedFuture(c);
}
} catch (SQLException e) {
@@ -888,9 +967,23 @@ public class DataJdbcSource extends DataSqlSource {
final Map joinTabalis = node == null ? null : node.getJoinTabalis();
final CharSequence join = node == null ? null : node.createSQLJoin(this, false, joinTabalis, new HashSet<>(), info);
final CharSequence where = node == null ? null : node.createSQLExpress(this, info, joinTabalis);
+ String[] tables = info.getTables(node);
+ String joinAndWhere = (join == null ? "" : join) + ((where == null || where.length() == 0) ? "" : (" WHERE " + where));
if ("mysql".equals(dbtype()) || "postgresql".equals(dbtype())) { //sql可以带limit、offset
- final String listsql = "SELECT " + (distinct ? "DISTINCT " : "") + info.getFullQueryColumns("a", selects) + " FROM " + info.getTable(node) + " a" + (join == null ? "" : join)
- + ((where == null || where.length() == 0) ? "" : (" WHERE " + where)) + createSQLOrderby(info, flipper)
+ String listsubsql;
+ StringBuilder union = new StringBuilder();
+ if (tables.length == 1) {
+ listsubsql = "SELECT " + (distinct ? "DISTINCT " : "") + info.getFullQueryColumns("a", selects) + " FROM " + tables[0] + " a" + joinAndWhere;
+ } else {
+ int b = 0;
+ for (String table : tables) {
+ if (!union.isEmpty()) union.append(" UNION ALL ");
+ String tabalis = "t" + (++b);
+ union.append("SELECT ").append(info.getFullQueryColumns(tabalis, selects)).append(" FROM ").append(table).append(" ").append(tabalis).append(joinAndWhere);
+ }
+ listsubsql = "SELECT " + (distinct ? "DISTINCT " : "") + info.getFullQueryColumns("a", selects) + " FROM (" + (union) + ") a";
+ }
+ final String listsql = listsubsql + createSQLOrderby(info, flipper)
+ (flipper == null || flipper.getLimit() < 1 ? "" : (" LIMIT " + flipper.getLimit() + " OFFSET " + flipper.getOffset()));
if (readcache && info.isLoggable(logger, Level.FINEST, listsql)) {
logger.finest(info.getType().getSimpleName() + " query sql=" + listsql);
@@ -905,7 +998,13 @@ public class DataJdbcSource extends DataSqlSource {
ps.close();
long total = list.size();
if (needtotal) {
- final String countsql = "SELECT " + (distinct ? "DISTINCT COUNT(" + info.getQueryColumns("a", selects) + ")" : "COUNT(*)") + " FROM " + info.getTable(node) + " a" + (join == null ? "" : join) + ((where == null || where.length() == 0) ? "" : (" WHERE " + where));
+ String countsubsql;
+ if (tables.length == 1) {
+ countsubsql = "SELECT " + (distinct ? "DISTINCT COUNT(" + info.getQueryColumns("a", selects) + ")" : "COUNT(*)") + " FROM " + tables[0] + " a" + joinAndWhere;
+ } else {
+ countsubsql = "SELECT " + (distinct ? "DISTINCT COUNT(" + info.getQueryColumns("a", selects) + ")" : "COUNT(*)") + " FROM (" + (union) + ") a";
+ }
+ final String countsql = countsubsql;
if (readcache && info.isLoggable(logger, Level.FINEST, countsql)) {
logger.finest(info.getType().getSimpleName() + " query countsql=" + countsql);
}
@@ -918,8 +1017,20 @@ public class DataJdbcSource extends DataSqlSource {
slowLog(s, listsql);
return CompletableFuture.completedFuture(new Sheet<>(total, list));
}
- final String listsql = "SELECT " + (distinct ? "DISTINCT " : "") + info.getFullQueryColumns("a", selects) + " FROM " + info.getTable(node) + " a" + (join == null ? "" : join)
- + ((where == null || where.length() == 0) ? "" : (" WHERE " + where)) + info.createSQLOrderby(flipper);
+ String listsubsql;
+ StringBuilder union = new StringBuilder();
+ if (tables.length == 1) {
+ listsubsql = "SELECT " + (distinct ? "DISTINCT " : "") + info.getFullQueryColumns("a", selects) + " FROM " + tables[0] + " a" + joinAndWhere;
+ } else {
+ int b = 0;
+ for (String table : tables) {
+ if (!union.isEmpty()) union.append(" UNION ALL ");
+ String tabalis = "t" + (++b);
+ union.append("SELECT ").append(distinct ? "DISTINCT " : "").append(info.getFullQueryColumns(tabalis, selects)).append(" FROM ").append(table).append(" ").append(tabalis).append(joinAndWhere);
+ }
+ listsubsql = "SELECT " + (distinct ? "DISTINCT " : "") + info.getFullQueryColumns("a", selects) + " FROM (" + (union) + ") a";
+ }
+ final String listsql = listsubsql + info.createSQLOrderby(flipper);
if (readcache && info.isLoggable(logger, Level.FINEST, listsql)) {
logger.finest(info.getType().getSimpleName() + " query sql=" + listsql + (flipper == null || flipper.getLimit() < 1 ? "" : (" LIMIT " + flipper.getLimit() + " OFFSET " + flipper.getOffset())));
}
diff --git a/src/main/java/org/redkale/source/DataMemorySource.java b/src/main/java/org/redkale/source/DataMemorySource.java
index 4bf49ff86..3f0bb314e 100644
--- a/src/main/java/org/redkale/source/DataMemorySource.java
+++ b/src/main/java/org/redkale/source/DataMemorySource.java
@@ -120,17 +120,17 @@ public class DataMemorySource extends DataSqlSource implements SearchSource {
}
@Override
- protected CompletableFuture deleteDB(EntityInfo info, Flipper flipper, String sql) {
+ protected CompletableFuture deleteDB(EntityInfo info, Flipper flipper, String... sqls) {
return CompletableFuture.completedFuture(0);
}
@Override
- protected CompletableFuture clearTableDB(EntityInfo info, final String table, String sql) {
+ protected CompletableFuture clearTableDB(EntityInfo info, String[] tables, String... sqls) {
return CompletableFuture.completedFuture(0);
}
@Override
- protected CompletableFuture dropTableDB(EntityInfo info, final String table, String sql) {
+ protected CompletableFuture dropTableDB(EntityInfo info, String[] tables, String... sqls) {
return CompletableFuture.completedFuture(0);
}
@@ -140,7 +140,7 @@ public class DataMemorySource extends DataSqlSource implements SearchSource {
}
@Override
- protected CompletableFuture updateColumnDB(EntityInfo info, Flipper flipper, String sql, boolean prepared, Object... params) {
+ protected CompletableFuture updateColumnDB(EntityInfo info, Flipper flipper, SqlInfo sql) {
return CompletableFuture.completedFuture(0);
}
diff --git a/src/main/java/org/redkale/source/DataSqlSource.java b/src/main/java/org/redkale/source/DataSqlSource.java
index 214e0ef88..af7d044c3 100644
--- a/src/main/java/org/redkale/source/DataSqlSource.java
+++ b/src/main/java/org/redkale/source/DataSqlSource.java
@@ -560,19 +560,19 @@ public abstract class DataSqlSource extends AbstractDataSource implements Functi
protected abstract CompletableFuture insertDB(final EntityInfo info, T... entitys);
//删除记录
- protected abstract CompletableFuture deleteDB(final EntityInfo info, Flipper flipper, final String sql);
+ protected abstract CompletableFuture deleteDB(final EntityInfo info, Flipper flipper, final String... sqls);
//清空表
- protected abstract CompletableFuture clearTableDB(final EntityInfo info, final String table, final String sql);
+ protected abstract CompletableFuture clearTableDB(final EntityInfo info, String[] tables, final String... sqls);
//删除表
- protected abstract CompletableFuture dropTableDB(final EntityInfo info, final String table, final String sql);
+ protected abstract CompletableFuture dropTableDB(final EntityInfo info, String[] tables, final String... sqls);
//更新纪录
protected abstract CompletableFuture updateEntityDB(final EntityInfo info, T... entitys);
//更新纪录
- protected abstract CompletableFuture updateColumnDB(final EntityInfo info, Flipper flipper, final String sql, final boolean prepared, Object... params);
+ protected abstract CompletableFuture updateColumnDB(final EntityInfo info, Flipper flipper, final SqlInfo sql);
//查询Number Map数据
protected abstract CompletableFuture