From 43a665497dc186827045a1ce530b73b908d322c5 Mon Sep 17 00:00:00 2001 From: Redkale Date: Wed, 28 Dec 2022 21:26:12 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96DataJdbcSource?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/redkale/source/DataJdbcSource.java | 502 ++++++++++-------- .../org/redkale/source/DataSqlSource.java | 8 +- 2 files changed, 280 insertions(+), 230 deletions(-) diff --git a/src/main/java/org/redkale/source/DataJdbcSource.java b/src/main/java/org/redkale/source/DataJdbcSource.java index e73b37aeb..2ab623f34 100644 --- a/src/main/java/org/redkale/source/DataJdbcSource.java +++ b/src/main/java/org/redkale/source/DataJdbcSource.java @@ -445,7 +445,6 @@ public class DataJdbcSource extends DataSqlSource { st.close(); } else { //分库分表 synchronized (info.disTableLock()) { - final String catalog = conn.getCatalog(); final Set newCatalogs = new LinkedHashSet<>(); final List tableCopys = new ArrayList<>(); prepareInfos.forEach((t, p) -> { @@ -647,31 +646,83 @@ public class DataJdbcSource extends DataSqlSource { List prestmts = null; Map> prepareInfos = null; - SQLException ex = null; try { conn = writePool.pollConnection(); conn.setReadOnly(false); conn.setAutoCommit(false); - int c = -1; final Attribute[] attrs = info.updateAttributes; - int retry = 0; - AGAIN: - while (retry++ < MAX_RETRYS) { - try { - if (info.getTableStrategy() == null) { - presql = info.getUpdateQuestionPrepareSQL(entitys[0]); - prestmt = createUpdatePreparedStatement(conn, presql, info, entitys); - int c1 = 0; - int[] pc = prestmt.executeBatch(); - for (int p : pc) { - if (p >= 0) c1 += p; + try { + if (info.getTableStrategy() == null) { + presql = info.getUpdateQuestionPrepareSQL(entitys[0]); + prestmt = createUpdatePreparedStatement(conn, presql, info, entitys); + int c1 = 0; + int[] pc = prestmt.executeBatch(); + for (int p : pc) { + if (p >= 0) c1 += p; + } + c = c1; + prestmt.close(); + } else { + prepareInfos = getUpdateQuestionPrepareInfo(info, entitys); + prestmts = createUpdatePreparedStatements(conn, info, prepareInfos, entitys); + int c1 = 0; + for (PreparedStatement stmt : prestmts) { + int[] cs = stmt.executeBatch(); + for (int cc : cs) { + c1 += cc; } - c = c1; - prestmt.close(); + } + c = c1; + for (PreparedStatement stmt : prestmts) { + stmt.close(); + } + } + conn.commit(); + } catch (SQLException se) { + conn.rollback(); + if (isTableNotExist(info, se.getSQLState())) { + if (info.getTableStrategy() == null) { + String[] tableSqls = createTableSqls(info); + if (tableSqls != null) { + try { + Statement st = conn.createStatement(); + if (tableSqls.length == 1) { + st.execute(tableSqls[0]); + } else { + for (String tableSql : tableSqls) { + st.addBatch(tableSql); + } + st.executeBatch(); + } + st.close(); + } catch (SQLException e2) { + } + } + //表不存在,更新条数为0 + return CompletableFuture.completedFuture(0); } else { - if (prepareInfos == null) { - prepareInfos = getUpdateQuestionPrepareInfo(info, entitys); + String tableName = parseNotExistTableName(se); + if (tableName == null || prepareInfos == null) { + return CompletableFuture.failedFuture(se); + } + for (PreparedStatement stmt : prestmts) { + stmt.close(); + } + + String[] oldTables = prepareInfos.keySet().toArray(new String[prepareInfos.size()]); + List notExistTables = checkNotExistTables(conn, oldTables, tableName); + if (notExistTables.isEmpty()) { + return CompletableFuture.failedFuture(se); + } + for (String t : notExistTables) { + prepareInfos.remove(t); + } + if (logger.isLoggable(Level.FINE)) { + logger.log(Level.FINE, "update entitys, old-tables: " + Arrays.toString(oldTables) + ", new-tables: " + prepareInfos.keySet()); + } + if (prepareInfos.isEmpty()) { //分表全部不存在 + return CompletableFuture.completedFuture(0); } prestmts = createUpdatePreparedStatements(conn, info, prepareInfos, entitys); int c1 = 0; @@ -685,64 +736,9 @@ public class DataJdbcSource extends DataSqlSource { for (PreparedStatement stmt : prestmts) { stmt.close(); } + conn.commit(); } - conn.commit(); - break; - } catch (SQLException se) { - ex = se; - conn.rollback(); - if (isTableNotExist(info, se.getSQLState())) { - if (info.getTableStrategy() == null) { - String[] tableSqls = createTableSqls(info); - if (tableSqls != null) { - try { - Statement st = conn.createStatement(); - if (tableSqls.length == 1) { - st.execute(tableSqls[0]); - } else { - for (String tableSql : tableSqls) { - st.addBatch(tableSql); - } - st.executeBatch(); - } - st.close(); - } catch (SQLException e2) { - } - } - //表都不存在,更新条数为0 - return CompletableFuture.completedFuture(0); - } else { - String tableName = parseNotExistTableName(se); - if (tableName == null || prepareInfos == null) { - return CompletableFuture.failedFuture(se); - } - String minTableName = (tableName.indexOf('.') > 0) ? tableName.substring(tableName.indexOf('.') + 1) : null; - for (String t : prepareInfos.keySet()) { - if (t.equals(tableName)) { - prepareInfos.remove(t); - if (info.getTableStrategy() == null) { - prestmt.close(); - } else { - for (PreparedStatement stmt : prestmts) { - stmt.close(); - } - } - continue AGAIN; - } else if (minTableName != null && t.equals(minTableName)) { - prepareInfos.remove(t); - if (info.getTableStrategy() == null) { - prestmt.close(); - } else { - for (PreparedStatement stmt : prestmts) { - stmt.close(); - } - } - continue AGAIN; - } - } - return CompletableFuture.failedFuture(se); - } - } + } else { throw se; } } @@ -804,11 +800,7 @@ public class DataJdbcSource extends DataSqlSource { }); slowLog(s, presqls.toArray(new String[presqls.size()])); } - if (c >= 0) { - return CompletableFuture.completedFuture(c); - } else { - return CompletableFuture.failedFuture(ex); - } + return CompletableFuture.completedFuture(c); } catch (SQLException e) { if (conn != null) { try { @@ -1250,166 +1242,78 @@ public class DataJdbcSource extends DataSqlSource { } @Override - protected CompletableFuture> querySheetDB(EntityInfo info, final boolean readcache, boolean needTotal, final boolean distinct, SelectColumn selects, Flipper flipper, FilterNode node) { + protected CompletableFuture> querySheetDB(EntityInfo info, final boolean readCache, boolean needTotal, final boolean distinct, SelectColumn selects, Flipper flipper, FilterNode node) { Connection conn = null; final long s = System.currentTimeMillis(); - final SelectColumn sels = selects; - final List list = new ArrayList(); 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); final String joinAndWhere = (join == null ? "" : join) + ((where == null || where.length() == 0) ? "" : (" WHERE " + where)); final boolean mysqlOrPgsql = "mysql".equals(dbtype()) || "postgresql".equals(dbtype()); - SQLException ex = null; try { conn = readPool.pollConnection(); - PreparedStatement ps = null; - //conn.setReadOnly(true); - int retry = 0; - AGAIN: - while (retry++ < MAX_RETRYS) { - String listSql = null; - String countSql = null; - { //组装listSql、countSql - 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 "); - union.append("SELECT ").append(info.getFullQueryColumns("a", selects)).append(" FROM ").append(table).append(" a").append(joinAndWhere); - } - listSubSql = "SELECT " + (distinct ? "DISTINCT " : "") + info.getFullQueryColumns("a", selects) + " FROM (" + (union) + ") a"; - } - listSql = listSubSql + createSQLOrderby(info, flipper); - if (mysqlOrPgsql) { - listSql += (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); - } - } else { - 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()))); - } - } - if (mysqlOrPgsql && needTotal) { - 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"; - } - countSql = countSubSql; - if (readcache && info.isLoggable(logger, Level.FINEST, countSql)) { - logger.finest(info.getType().getSimpleName() + " query countsql=" + countSql); - } - } - } - try { - if (mysqlOrPgsql) { //sql可以带limit、offset - ps = conn.prepareStatement(listSql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); - ResultSet set = ps.executeQuery(); - final DataResultSet rr = createDataResultSet(info, set); - while (set.next()) { - list.add(getEntityValue(info, sels, rr)); - } - set.close(); - ps.close(); - long total = list.size(); - if (needTotal) { - ps = conn.prepareStatement(countSql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); - set = ps.executeQuery(); - if (set.next()) total = set.getLong(1); - set.close(); - ps.close(); - } - slowLog(s, listSql); - return CompletableFuture.completedFuture(new Sheet<>(total, list)); - } else { - //conn.setReadOnly(true); - ps = conn.prepareStatement(listSql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); - if (flipper != null && flipper.getLimit() > 0) ps.setFetchSize(flipper.getLimit()); - ResultSet set = ps.executeQuery(); - if (flipper != null && flipper.getOffset() > 0) set.absolute(flipper.getOffset()); - final int limit = flipper == null || flipper.getLimit() < 1 ? Integer.MAX_VALUE : flipper.getLimit(); - int i = 0; - final DataResultSet rr = createDataResultSet(info, set); - if (sels == null) { - while (set.next()) { - i++; - list.add(info.getFullEntityValue(rr)); - if (limit <= i) break; - } - } else { - while (set.next()) { - i++; - list.add(info.getEntityValue(sels, rr)); - if (limit <= i) break; - } - } - long total = list.size(); - if (needTotal && flipper != null) { - set.last(); - total = set.getRow(); - } - set.close(); - ps.close(); - slowLog(s, listSql); - return CompletableFuture.completedFuture(new Sheet<>(total, list)); - } - } catch (SQLException se) { - ex = se; - if (isTableNotExist(info, se.getSQLState())) { - if (info.getTableStrategy() == null) { - String[] tableSqls = createTableSqls(info); - if (tableSqls != null) { - try { - Statement st = conn.createStatement(); - if (tableSqls.length == 1) { - st.execute(tableSqls[0]); - } else { - for (String tableSql : tableSqls) { - st.addBatch(tableSql); - } - st.executeBatch(); + String[] sqls = createSheetListAndCountSql(info, readCache, needTotal, distinct, selects, flipper, mysqlOrPgsql, tables, joinAndWhere); + String listSql = sqls[0]; + String countSql = sqls[1]; + try { + return executeQuerySheet(info, needTotal, flipper, sels, s, conn, mysqlOrPgsql, listSql, countSql); + } catch (SQLException se) { + if (isTableNotExist(info, se.getSQLState())) { + if (info.getTableStrategy() == null) { + String[] tableSqls = createTableSqls(info); + if (tableSqls != null) { + try { + Statement st = conn.createStatement(); + if (tableSqls.length == 1) { + st.execute(tableSqls[0]); + } else { + for (String tableSql : tableSqls) { + st.addBatch(tableSql); } - st.close(); - } catch (SQLException e2) { + st.executeBatch(); } + st.close(); + } catch (SQLException e2) { } - return CompletableFuture.completedFuture(new Sheet<>(0, new ArrayList())); - } else if (tables != null && tables.length == 1) { - //只查一个不存在的分表 - return CompletableFuture.completedFuture(new Sheet<>(0, new ArrayList())); - } else if (tables != null && tables.length > 1) { - //多分表查询中一个或多个分表不存在 - String tableName = parseNotExistTableName(se); - if (tableName == null) { - return CompletableFuture.failedFuture(se); - } - String minTableName = (tableName.indexOf('.') > 0) ? tableName.substring(tableName.indexOf('.') + 1) : null; - if (ps != null) ps.close(); - for (String t : tables) { - if (t.equals(tableName) || (minTableName != null && t.equals(minTableName))) { - tables = Utility.remove(tables, t); - if (tables.length < 1) { //分表都不存在 - return CompletableFuture.completedFuture(new Sheet<>(0, new ArrayList())); - } - continue AGAIN; - } - } - } else { + } + return CompletableFuture.completedFuture(new Sheet<>(0, new ArrayList())); + } else if (tables != null && tables.length == 1) { + //只查一个不存在的分表 + return CompletableFuture.completedFuture(new Sheet<>(0, new ArrayList())); + } else if (tables != null && tables.length > 1) { + //多分表查询中一个或多个分表不存在 + String tableName = parseNotExistTableName(se); + if (tableName == null) { return CompletableFuture.failedFuture(se); } + String[] oldTables = tables; + List notExistTables = checkNotExistTables(conn, tables, tableName); + if (notExistTables.isEmpty()) { + return CompletableFuture.failedFuture(se); + } + for (String t : notExistTables) { + tables = Utility.remove(tables, t); + } + if (logger.isLoggable(Level.FINE)) { + logger.log(Level.FINE, "query sheet, old-tables: " + Arrays.toString(oldTables) + ", new-tables: " + Arrays.toString(tables)); + } + if (tables.length == 0) { //分表全部不存在 + return CompletableFuture.completedFuture(new Sheet<>(0, new ArrayList())); + } + + //重新查询一次 + sqls = createSheetListAndCountSql(info, readCache, needTotal, distinct, selects, flipper, mysqlOrPgsql, tables, joinAndWhere); + listSql = sqls[0]; + countSql = sqls[1]; + return executeQuerySheet(info, needTotal, flipper, sels, s, conn, mysqlOrPgsql, listSql, countSql); + } else { + return CompletableFuture.failedFuture(se); } - return CompletableFuture.failedFuture(se); } + return CompletableFuture.failedFuture(se); } - throw ex; } catch (Exception e) { return CompletableFuture.failedFuture(e); } finally { @@ -1417,6 +1321,141 @@ public class DataJdbcSource extends DataSqlSource { } } + private CompletableFuture> executeQuerySheet(EntityInfo info, boolean needTotal, Flipper flipper, SelectColumn sels, + long s, Connection conn, boolean mysqlOrPgsql, String listSql, String countSql) throws SQLException { + final List list = new ArrayList(); + if (mysqlOrPgsql) { //sql可以带limit、offset + PreparedStatement ps = conn.prepareStatement(listSql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); + ResultSet set = ps.executeQuery(); + final DataResultSet rr = createDataResultSet(info, set); + while (set.next()) { + list.add(getEntityValue(info, sels, rr)); + } + set.close(); + ps.close(); + long total = list.size(); + if (needTotal) { + ps = conn.prepareStatement(countSql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); + set = ps.executeQuery(); + if (set.next()) total = set.getLong(1); + set.close(); + ps.close(); + } + slowLog(s, listSql); + return CompletableFuture.completedFuture(new Sheet<>(total, list)); + } else { + //conn.setReadOnly(true); + PreparedStatement ps = conn.prepareStatement(listSql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); + if (flipper != null && flipper.getLimit() > 0) ps.setFetchSize(flipper.getLimit()); + ResultSet set = ps.executeQuery(); + if (flipper != null && flipper.getOffset() > 0) set.absolute(flipper.getOffset()); + final int limit = flipper == null || flipper.getLimit() < 1 ? Integer.MAX_VALUE : flipper.getLimit(); + int i = 0; + final DataResultSet rr = createDataResultSet(info, set); + if (sels == null) { + while (set.next()) { + i++; + list.add(info.getFullEntityValue(rr)); + if (limit <= i) break; + } + } else { + while (set.next()) { + i++; + list.add(info.getEntityValue(sels, rr)); + if (limit <= i) break; + } + } + long total = list.size(); + if (needTotal && flipper != null) { + set.last(); + total = set.getRow(); + } + set.close(); + ps.close(); + slowLog(s, listSql); + return CompletableFuture.completedFuture(new Sheet<>(total, list)); + } + } + + private String[] createSheetListAndCountSql(EntityInfo info, final boolean readCache, boolean needTotal, + final boolean distinct, SelectColumn selects, Flipper flipper, boolean mysqlOrPgsql, String[] tables, String joinAndWhere) { + String listSql = null; + String countSql = null; + { //组装listSql、countSql + 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 "); + union.append("SELECT ").append(info.getFullQueryColumns("a", selects)).append(" FROM ").append(table).append(" a").append(joinAndWhere); + } + listSubSql = "SELECT " + (distinct ? "DISTINCT " : "") + info.getFullQueryColumns("a", selects) + " FROM (" + (union) + ") a"; + } + listSql = listSubSql + createSQLOrderby(info, flipper); + if (mysqlOrPgsql) { + listSql += (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); + } + } else { + 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()))); + } + } + if (mysqlOrPgsql && needTotal) { + 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"; + } + countSql = countSubSql; + if (readCache && info.isLoggable(logger, Level.FINEST, countSql)) { + logger.finest(info.getType().getSimpleName() + " query countsql=" + countSql); + } + } + } + return new String[]{listSql, countSql}; + } + + protected List checkNotExistTables(Connection conn, String[] tables, String firstNotExistTable) throws SQLException { + String minTableName = (firstNotExistTable.indexOf('.') > 0) ? firstNotExistTable.substring(firstNotExistTable.indexOf('.') + 1) : null; + List maybeNoTables = new ArrayList<>(); + for (String t : tables) { + if (!maybeNoTables.isEmpty()) { + maybeNoTables.add(t); + } + if (t.equals(firstNotExistTable) || (minTableName != null && t.equals(minTableName))) { + maybeNoTables.add(t); + } + } + if (maybeNoTables.isEmpty()) { + return maybeNoTables; + } + + String[] tableTypes = new String[]{"TABLE"}; + DatabaseMetaData dmd = conn.getMetaData(); + List rs = new ArrayList<>(); + for (String t : maybeNoTables) { + String catalog = null; + String table = t; + int pos = t.indexOf('.'); + if (pos > 0) { + catalog = t.substring(0, pos); + table = t.substring(pos + 1); + } + ResultSet dmdrs = dmd.getTables(catalog, null, table, tableTypes); + if (!dmdrs.next()) { //不存在表 + rs.add(t); + } + dmdrs.close(); + } + return rs; + } + /** * 直接本地执行SQL语句进行增删改操作,远程模式不可用
* 通常用于复杂的更新操作
@@ -1511,21 +1550,31 @@ public class DataJdbcSource extends DataSqlSource { @Override public Serializable getObject(Attribute attr, int index, String column) { Class t = attr.type(); + if (t == java.util.Date.class) { Object val = index > 0 ? getObject(index) : getObject(column); - if (val == null) return null; - return new java.util.Date(((java.sql.Date) val).getTime()); + + if (val + == null) return null; + return new java.util.Date( + ((java.sql.Date) val).getTime()); } else if (t == java.time.LocalDate.class) { Object val = index > 0 ? getObject(index) : getObject(column); - if (val == null) return null; + + if (val + == null) return null; return ((java.sql.Date) val).toLocalDate(); } else if (t == java.time.LocalTime.class) { Object val = index > 0 ? getObject(index) : getObject(column); - if (val == null) return null; + + if (val + == null) return null; return ((java.sql.Time) val).toLocalTime(); } else if (t == java.time.LocalDateTime.class) { Object val = index > 0 ? getObject(index) : getObject(column); - if (val == null) return null; + + if (val + == null) return null; return ((java.sql.Timestamp) val).toLocalDateTime(); } else if (t.getName().startsWith("java.sql.")) { return index > 0 ? (Serializable) getObject(index) : (Serializable) getObject(column); @@ -1599,6 +1648,7 @@ public class DataJdbcSource extends DataSqlSource { } }; + } protected class ConnectionPool implements AutoCloseable { diff --git a/src/main/java/org/redkale/source/DataSqlSource.java b/src/main/java/org/redkale/source/DataSqlSource.java index 1d8984a2a..867672807 100644 --- a/src/main/java/org/redkale/source/DataSqlSource.java +++ b/src/main/java/org/redkale/source/DataSqlSource.java @@ -537,7 +537,7 @@ public abstract class DataSqlSource extends AbstractDataSource implements Functi @Local protected Map> getInsertQuestionPrepareInfo(EntityInfo info, T... entitys) { - Map> map = new LinkedHashMap<>(); + Map> map = new LinkedHashMap<>();//一定要是LinkedHashMap for (T entity : entitys) { String table = info.getTable(entity); map.computeIfAbsent(table, t -> new PrepareInfo(info.getInsertQuestionPrepareSQL(entity))).addEntity(entity); @@ -547,7 +547,7 @@ public abstract class DataSqlSource extends AbstractDataSource implements Functi @Local protected Map> getInsertDollarPrepareInfo(EntityInfo info, T... entitys) { - Map> map = new LinkedHashMap<>(); + Map> map = new LinkedHashMap<>();//一定要是LinkedHashMap for (T entity : entitys) { String table = info.getTable(entity); map.computeIfAbsent(table, t -> new PrepareInfo(info.getInsertDollarPrepareSQL(entity))).addEntity(entity); @@ -557,7 +557,7 @@ public abstract class DataSqlSource extends AbstractDataSource implements Functi @Local protected Map> getUpdateQuestionPrepareInfo(EntityInfo info, T... entitys) { - Map> map = new LinkedHashMap<>(); + Map> map = new LinkedHashMap<>(); //一定要是LinkedHashMap for (T entity : entitys) { String table = info.getTable(entity); map.computeIfAbsent(table, t -> new PrepareInfo(info.getUpdateQuestionPrepareSQL(entity))).addEntity(entity); @@ -567,7 +567,7 @@ public abstract class DataSqlSource extends AbstractDataSource implements Functi @Local protected Map> getUpdateDollarPrepareInfo(EntityInfo info, T... entitys) { - Map> map = new LinkedHashMap<>(); + Map> map = new LinkedHashMap<>();//一定要是LinkedHashMap for (T entity : entitys) { String table = info.getTable(entity); map.computeIfAbsent(table, t -> new PrepareInfo(info.getUpdateDollarPrepareSQL(entity))).addEntity(entity);