优化DataJdbcSource
This commit is contained in:
@@ -445,7 +445,6 @@ public class DataJdbcSource extends DataSqlSource {
|
|||||||
st.close();
|
st.close();
|
||||||
} else { //分库分表
|
} else { //分库分表
|
||||||
synchronized (info.disTableLock()) {
|
synchronized (info.disTableLock()) {
|
||||||
final String catalog = conn.getCatalog();
|
|
||||||
final Set<String> newCatalogs = new LinkedHashSet<>();
|
final Set<String> newCatalogs = new LinkedHashSet<>();
|
||||||
final List<String> tableCopys = new ArrayList<>();
|
final List<String> tableCopys = new ArrayList<>();
|
||||||
prepareInfos.forEach((t, p) -> {
|
prepareInfos.forEach((t, p) -> {
|
||||||
@@ -647,17 +646,12 @@ public class DataJdbcSource extends DataSqlSource {
|
|||||||
|
|
||||||
List<PreparedStatement> prestmts = null;
|
List<PreparedStatement> prestmts = null;
|
||||||
Map<String, PrepareInfo<T>> prepareInfos = null;
|
Map<String, PrepareInfo<T>> prepareInfos = null;
|
||||||
SQLException ex = null;
|
|
||||||
try {
|
try {
|
||||||
conn = writePool.pollConnection();
|
conn = writePool.pollConnection();
|
||||||
conn.setReadOnly(false);
|
conn.setReadOnly(false);
|
||||||
conn.setAutoCommit(false);
|
conn.setAutoCommit(false);
|
||||||
|
|
||||||
int c = -1;
|
int c = -1;
|
||||||
final Attribute<T, Serializable>[] attrs = info.updateAttributes;
|
final Attribute<T, Serializable>[] attrs = info.updateAttributes;
|
||||||
int retry = 0;
|
|
||||||
AGAIN:
|
|
||||||
while (retry++ < MAX_RETRYS) {
|
|
||||||
try {
|
try {
|
||||||
if (info.getTableStrategy() == null) {
|
if (info.getTableStrategy() == null) {
|
||||||
presql = info.getUpdateQuestionPrepareSQL(entitys[0]);
|
presql = info.getUpdateQuestionPrepareSQL(entitys[0]);
|
||||||
@@ -670,9 +664,7 @@ public class DataJdbcSource extends DataSqlSource {
|
|||||||
c = c1;
|
c = c1;
|
||||||
prestmt.close();
|
prestmt.close();
|
||||||
} else {
|
} else {
|
||||||
if (prepareInfos == null) {
|
|
||||||
prepareInfos = getUpdateQuestionPrepareInfo(info, entitys);
|
prepareInfos = getUpdateQuestionPrepareInfo(info, entitys);
|
||||||
}
|
|
||||||
prestmts = createUpdatePreparedStatements(conn, info, prepareInfos, entitys);
|
prestmts = createUpdatePreparedStatements(conn, info, prepareInfos, entitys);
|
||||||
int c1 = 0;
|
int c1 = 0;
|
||||||
for (PreparedStatement stmt : prestmts) {
|
for (PreparedStatement stmt : prestmts) {
|
||||||
@@ -687,9 +679,7 @@ public class DataJdbcSource extends DataSqlSource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
conn.commit();
|
conn.commit();
|
||||||
break;
|
|
||||||
} catch (SQLException se) {
|
} catch (SQLException se) {
|
||||||
ex = se;
|
|
||||||
conn.rollback();
|
conn.rollback();
|
||||||
if (isTableNotExist(info, se.getSQLState())) {
|
if (isTableNotExist(info, se.getSQLState())) {
|
||||||
if (info.getTableStrategy() == null) {
|
if (info.getTableStrategy() == null) {
|
||||||
@@ -709,40 +699,46 @@ public class DataJdbcSource extends DataSqlSource {
|
|||||||
} catch (SQLException e2) {
|
} catch (SQLException e2) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//表都不存在,更新条数为0
|
//表不存在,更新条数为0
|
||||||
return CompletableFuture.completedFuture(0);
|
return CompletableFuture.completedFuture(0);
|
||||||
} else {
|
} else {
|
||||||
String tableName = parseNotExistTableName(se);
|
String tableName = parseNotExistTableName(se);
|
||||||
if (tableName == null || prepareInfos == null) {
|
if (tableName == null || prepareInfos == null) {
|
||||||
return CompletableFuture.failedFuture(se);
|
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) {
|
for (PreparedStatement stmt : prestmts) {
|
||||||
stmt.close();
|
stmt.close();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
continue AGAIN;
|
String[] oldTables = prepareInfos.keySet().toArray(new String[prepareInfos.size()]);
|
||||||
} else if (minTableName != null && t.equals(minTableName)) {
|
List<String> notExistTables = checkNotExistTables(conn, oldTables, tableName);
|
||||||
prepareInfos.remove(t);
|
if (notExistTables.isEmpty()) {
|
||||||
if (info.getTableStrategy() == null) {
|
|
||||||
prestmt.close();
|
|
||||||
} else {
|
|
||||||
for (PreparedStatement stmt : prestmts) {
|
|
||||||
stmt.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue AGAIN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return CompletableFuture.failedFuture(se);
|
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;
|
||||||
|
for (PreparedStatement stmt : prestmts) {
|
||||||
|
int[] cs = stmt.executeBatch();
|
||||||
|
for (int cc : cs) {
|
||||||
|
c1 += cc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c = c1;
|
||||||
|
for (PreparedStatement stmt : prestmts) {
|
||||||
|
stmt.close();
|
||||||
|
}
|
||||||
|
conn.commit();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
throw se;
|
throw se;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -804,11 +800,7 @@ public class DataJdbcSource extends DataSqlSource {
|
|||||||
});
|
});
|
||||||
slowLog(s, presqls.toArray(new String[presqls.size()]));
|
slowLog(s, presqls.toArray(new String[presqls.size()]));
|
||||||
}
|
}
|
||||||
if (c >= 0) {
|
|
||||||
return CompletableFuture.completedFuture(c);
|
return CompletableFuture.completedFuture(c);
|
||||||
} else {
|
|
||||||
return CompletableFuture.failedFuture(ex);
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
if (conn != null) {
|
if (conn != null) {
|
||||||
try {
|
try {
|
||||||
@@ -1250,68 +1242,90 @@ public class DataJdbcSource extends DataSqlSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected <T> CompletableFuture<Sheet<T>> querySheetDB(EntityInfo<T> info, final boolean readcache, boolean needTotal, final boolean distinct, SelectColumn selects, Flipper flipper, FilterNode node) {
|
protected <T> CompletableFuture<Sheet<T>> querySheetDB(EntityInfo<T> info, final boolean readCache, boolean needTotal, final boolean distinct, SelectColumn selects, Flipper flipper, FilterNode node) {
|
||||||
Connection conn = null;
|
Connection conn = null;
|
||||||
final long s = System.currentTimeMillis();
|
final long s = System.currentTimeMillis();
|
||||||
|
|
||||||
final SelectColumn sels = selects;
|
final SelectColumn sels = selects;
|
||||||
final List<T> list = new ArrayList();
|
|
||||||
final Map<Class, String> joinTabalis = node == null ? null : node.getJoinTabalis();
|
final Map<Class, String> joinTabalis = node == null ? null : node.getJoinTabalis();
|
||||||
final CharSequence join = node == null ? null : node.createSQLJoin(this, false, joinTabalis, new HashSet<>(), info);
|
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);
|
final CharSequence where = node == null ? null : node.createSQLExpress(this, info, joinTabalis);
|
||||||
String[] tables = info.getTables(node);
|
String[] tables = info.getTables(node);
|
||||||
final String joinAndWhere = (join == null ? "" : join) + ((where == null || where.length() == 0) ? "" : (" WHERE " + where));
|
final String joinAndWhere = (join == null ? "" : join) + ((where == null || where.length() == 0) ? "" : (" WHERE " + where));
|
||||||
final boolean mysqlOrPgsql = "mysql".equals(dbtype()) || "postgresql".equals(dbtype());
|
final boolean mysqlOrPgsql = "mysql".equals(dbtype()) || "postgresql".equals(dbtype());
|
||||||
SQLException ex = null;
|
|
||||||
try {
|
try {
|
||||||
conn = readPool.pollConnection();
|
conn = readPool.pollConnection();
|
||||||
PreparedStatement ps = null;
|
String[] sqls = createSheetListAndCountSql(info, readCache, needTotal, distinct, selects, flipper, mysqlOrPgsql, tables, joinAndWhere);
|
||||||
//conn.setReadOnly(true);
|
String listSql = sqls[0];
|
||||||
int retry = 0;
|
String countSql = sqls[1];
|
||||||
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 {
|
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.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[] oldTables = tables;
|
||||||
|
List<String> 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);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
return CompletableFuture.failedFuture(e);
|
||||||
|
} finally {
|
||||||
|
if (conn != null) readPool.offerConnection(conn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> CompletableFuture<Sheet<T>> executeQuerySheet(EntityInfo<T> info, boolean needTotal, Flipper flipper, SelectColumn sels,
|
||||||
|
long s, Connection conn, boolean mysqlOrPgsql, String listSql, String countSql) throws SQLException {
|
||||||
|
final List<T> list = new ArrayList();
|
||||||
if (mysqlOrPgsql) { //sql可以带limit、offset
|
if (mysqlOrPgsql) { //sql可以带limit、offset
|
||||||
ps = conn.prepareStatement(listSql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
|
PreparedStatement ps = conn.prepareStatement(listSql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
|
||||||
ResultSet set = ps.executeQuery();
|
ResultSet set = ps.executeQuery();
|
||||||
final DataResultSet rr = createDataResultSet(info, set);
|
final DataResultSet rr = createDataResultSet(info, set);
|
||||||
while (set.next()) {
|
while (set.next()) {
|
||||||
@@ -1331,7 +1345,7 @@ public class DataJdbcSource extends DataSqlSource {
|
|||||||
return CompletableFuture.completedFuture(new Sheet<>(total, list));
|
return CompletableFuture.completedFuture(new Sheet<>(total, list));
|
||||||
} else {
|
} else {
|
||||||
//conn.setReadOnly(true);
|
//conn.setReadOnly(true);
|
||||||
ps = conn.prepareStatement(listSql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
|
PreparedStatement ps = conn.prepareStatement(listSql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
|
||||||
if (flipper != null && flipper.getLimit() > 0) ps.setFetchSize(flipper.getLimit());
|
if (flipper != null && flipper.getLimit() > 0) ps.setFetchSize(flipper.getLimit());
|
||||||
ResultSet set = ps.executeQuery();
|
ResultSet set = ps.executeQuery();
|
||||||
if (flipper != null && flipper.getOffset() > 0) set.absolute(flipper.getOffset());
|
if (flipper != null && flipper.getOffset() > 0) set.absolute(flipper.getOffset());
|
||||||
@@ -1361,60 +1375,85 @@ public class DataJdbcSource extends DataSqlSource {
|
|||||||
slowLog(s, listSql);
|
slowLog(s, listSql);
|
||||||
return CompletableFuture.completedFuture(new Sheet<>(total, list));
|
return CompletableFuture.completedFuture(new Sheet<>(total, list));
|
||||||
}
|
}
|
||||||
} catch (SQLException se) {
|
}
|
||||||
ex = se;
|
|
||||||
if (isTableNotExist(info, se.getSQLState())) {
|
private <T> String[] createSheetListAndCountSql(EntityInfo<T> info, final boolean readCache, boolean needTotal,
|
||||||
if (info.getTableStrategy() == null) {
|
final boolean distinct, SelectColumn selects, Flipper flipper, boolean mysqlOrPgsql, String[] tables, String joinAndWhere) {
|
||||||
String[] tableSqls = createTableSqls(info);
|
String listSql = null;
|
||||||
if (tableSqls != null) {
|
String countSql = null;
|
||||||
try {
|
{ //组装listSql、countSql
|
||||||
Statement st = conn.createStatement();
|
String listSubSql;
|
||||||
if (tableSqls.length == 1) {
|
StringBuilder union = new StringBuilder();
|
||||||
st.execute(tableSqls[0]);
|
if (tables.length == 1) {
|
||||||
|
listSubSql = "SELECT " + (distinct ? "DISTINCT " : "") + info.getFullQueryColumns("a", selects) + " FROM " + tables[0] + " a" + joinAndWhere;
|
||||||
} else {
|
} else {
|
||||||
for (String tableSql : tableSqls) {
|
int b = 0;
|
||||||
st.addBatch(tableSql);
|
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);
|
||||||
}
|
}
|
||||||
st.executeBatch();
|
listSubSql = "SELECT " + (distinct ? "DISTINCT " : "") + info.getFullQueryColumns("a", selects) + " FROM (" + (union) + ") a";
|
||||||
}
|
}
|
||||||
st.close();
|
listSql = listSubSql + createSQLOrderby(info, flipper);
|
||||||
} catch (SQLException e2) {
|
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())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return CompletableFuture.completedFuture(new Sheet<>(0, new ArrayList()));
|
if (mysqlOrPgsql && needTotal) {
|
||||||
} else if (tables != null && tables.length == 1) {
|
String countSubSql;
|
||||||
//只查一个不存在的分表
|
if (tables.length == 1) {
|
||||||
return CompletableFuture.completedFuture(new Sheet<>(0, new ArrayList()));
|
countSubSql = "SELECT " + (distinct ? "DISTINCT COUNT(" + info.getQueryColumns("a", selects) + ")" : "COUNT(*)") + " FROM " + tables[0] + " a" + joinAndWhere;
|
||||||
} else if (tables != null && tables.length > 1) {
|
} else {
|
||||||
//多分表查询中一个或多个分表不存在
|
countSubSql = "SELECT " + (distinct ? "DISTINCT COUNT(" + info.getQueryColumns("a", selects) + ")" : "COUNT(*)") + " FROM (" + (union) + ") a";
|
||||||
String tableName = parseNotExistTableName(se);
|
|
||||||
if (tableName == null) {
|
|
||||||
return CompletableFuture.failedFuture(se);
|
|
||||||
}
|
}
|
||||||
String minTableName = (tableName.indexOf('.') > 0) ? tableName.substring(tableName.indexOf('.') + 1) : null;
|
countSql = countSubSql;
|
||||||
if (ps != null) ps.close();
|
if (readCache && info.isLoggable(logger, Level.FINEST, countSql)) {
|
||||||
|
logger.finest(info.getType().getSimpleName() + " query countsql=" + countSql);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new String[]{listSql, countSql};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<String> checkNotExistTables(Connection conn, String[] tables, String firstNotExistTable) throws SQLException {
|
||||||
|
String minTableName = (firstNotExistTable.indexOf('.') > 0) ? firstNotExistTable.substring(firstNotExistTable.indexOf('.') + 1) : null;
|
||||||
|
List<String> maybeNoTables = new ArrayList<>();
|
||||||
for (String t : tables) {
|
for (String t : tables) {
|
||||||
if (t.equals(tableName) || (minTableName != null && t.equals(minTableName))) {
|
if (!maybeNoTables.isEmpty()) {
|
||||||
tables = Utility.remove(tables, t);
|
maybeNoTables.add(t);
|
||||||
if (tables.length < 1) { //分表都不存在
|
|
||||||
return CompletableFuture.completedFuture(new Sheet<>(0, new ArrayList()));
|
|
||||||
}
|
}
|
||||||
continue AGAIN;
|
if (t.equals(firstNotExistTable) || (minTableName != null && t.equals(minTableName))) {
|
||||||
|
maybeNoTables.add(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
if (maybeNoTables.isEmpty()) {
|
||||||
return CompletableFuture.failedFuture(se);
|
return maybeNoTables;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String[] tableTypes = new String[]{"TABLE"};
|
||||||
|
DatabaseMetaData dmd = conn.getMetaData();
|
||||||
|
List<String> 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);
|
||||||
}
|
}
|
||||||
return CompletableFuture.failedFuture(se);
|
ResultSet dmdrs = dmd.getTables(catalog, null, table, tableTypes);
|
||||||
|
if (!dmdrs.next()) { //不存在表
|
||||||
|
rs.add(t);
|
||||||
}
|
}
|
||||||
|
dmdrs.close();
|
||||||
}
|
}
|
||||||
throw ex;
|
return rs;
|
||||||
} catch (Exception e) {
|
|
||||||
return CompletableFuture.failedFuture(e);
|
|
||||||
} finally {
|
|
||||||
if (conn != null) readPool.offerConnection(conn);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1511,21 +1550,31 @@ public class DataJdbcSource extends DataSqlSource {
|
|||||||
@Override
|
@Override
|
||||||
public <T> Serializable getObject(Attribute<T, Serializable> attr, int index, String column) {
|
public <T> Serializable getObject(Attribute<T, Serializable> attr, int index, String column) {
|
||||||
Class t = attr.type();
|
Class t = attr.type();
|
||||||
|
|
||||||
if (t == java.util.Date.class) {
|
if (t == java.util.Date.class) {
|
||||||
Object val = index > 0 ? getObject(index) : getObject(column);
|
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) {
|
} else if (t == java.time.LocalDate.class) {
|
||||||
Object val = index > 0 ? getObject(index) : getObject(column);
|
Object val = index > 0 ? getObject(index) : getObject(column);
|
||||||
if (val == null) return null;
|
|
||||||
|
if (val
|
||||||
|
== null) return null;
|
||||||
return ((java.sql.Date) val).toLocalDate();
|
return ((java.sql.Date) val).toLocalDate();
|
||||||
} else if (t == java.time.LocalTime.class) {
|
} else if (t == java.time.LocalTime.class) {
|
||||||
Object val = index > 0 ? getObject(index) : getObject(column);
|
Object val = index > 0 ? getObject(index) : getObject(column);
|
||||||
if (val == null) return null;
|
|
||||||
|
if (val
|
||||||
|
== null) return null;
|
||||||
return ((java.sql.Time) val).toLocalTime();
|
return ((java.sql.Time) val).toLocalTime();
|
||||||
} else if (t == java.time.LocalDateTime.class) {
|
} else if (t == java.time.LocalDateTime.class) {
|
||||||
Object val = index > 0 ? getObject(index) : getObject(column);
|
Object val = index > 0 ? getObject(index) : getObject(column);
|
||||||
if (val == null) return null;
|
|
||||||
|
if (val
|
||||||
|
== null) return null;
|
||||||
return ((java.sql.Timestamp) val).toLocalDateTime();
|
return ((java.sql.Timestamp) val).toLocalDateTime();
|
||||||
} else if (t.getName().startsWith("java.sql.")) {
|
} else if (t.getName().startsWith("java.sql.")) {
|
||||||
return index > 0 ? (Serializable) getObject(index) : (Serializable) getObject(column);
|
return index > 0 ? (Serializable) getObject(index) : (Serializable) getObject(column);
|
||||||
@@ -1599,6 +1648,7 @@ public class DataJdbcSource extends DataSqlSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected class ConnectionPool implements AutoCloseable {
|
protected class ConnectionPool implements AutoCloseable {
|
||||||
|
|||||||
@@ -537,7 +537,7 @@ public abstract class DataSqlSource extends AbstractDataSource implements Functi
|
|||||||
|
|
||||||
@Local
|
@Local
|
||||||
protected <T> Map<String, PrepareInfo<T>> getInsertQuestionPrepareInfo(EntityInfo<T> info, T... entitys) {
|
protected <T> Map<String, PrepareInfo<T>> getInsertQuestionPrepareInfo(EntityInfo<T> info, T... entitys) {
|
||||||
Map<String, PrepareInfo<T>> map = new LinkedHashMap<>();
|
Map<String, PrepareInfo<T>> map = new LinkedHashMap<>();//一定要是LinkedHashMap
|
||||||
for (T entity : entitys) {
|
for (T entity : entitys) {
|
||||||
String table = info.getTable(entity);
|
String table = info.getTable(entity);
|
||||||
map.computeIfAbsent(table, t -> new PrepareInfo(info.getInsertQuestionPrepareSQL(entity))).addEntity(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
|
@Local
|
||||||
protected <T> Map<String, PrepareInfo<T>> getInsertDollarPrepareInfo(EntityInfo<T> info, T... entitys) {
|
protected <T> Map<String, PrepareInfo<T>> getInsertDollarPrepareInfo(EntityInfo<T> info, T... entitys) {
|
||||||
Map<String, PrepareInfo<T>> map = new LinkedHashMap<>();
|
Map<String, PrepareInfo<T>> map = new LinkedHashMap<>();//一定要是LinkedHashMap
|
||||||
for (T entity : entitys) {
|
for (T entity : entitys) {
|
||||||
String table = info.getTable(entity);
|
String table = info.getTable(entity);
|
||||||
map.computeIfAbsent(table, t -> new PrepareInfo(info.getInsertDollarPrepareSQL(entity))).addEntity(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
|
@Local
|
||||||
protected <T> Map<String, PrepareInfo<T>> getUpdateQuestionPrepareInfo(EntityInfo<T> info, T... entitys) {
|
protected <T> Map<String, PrepareInfo<T>> getUpdateQuestionPrepareInfo(EntityInfo<T> info, T... entitys) {
|
||||||
Map<String, PrepareInfo<T>> map = new LinkedHashMap<>();
|
Map<String, PrepareInfo<T>> map = new LinkedHashMap<>(); //一定要是LinkedHashMap
|
||||||
for (T entity : entitys) {
|
for (T entity : entitys) {
|
||||||
String table = info.getTable(entity);
|
String table = info.getTable(entity);
|
||||||
map.computeIfAbsent(table, t -> new PrepareInfo(info.getUpdateQuestionPrepareSQL(entity))).addEntity(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
|
@Local
|
||||||
protected <T> Map<String, PrepareInfo<T>> getUpdateDollarPrepareInfo(EntityInfo<T> info, T... entitys) {
|
protected <T> Map<String, PrepareInfo<T>> getUpdateDollarPrepareInfo(EntityInfo<T> info, T... entitys) {
|
||||||
Map<String, PrepareInfo<T>> map = new LinkedHashMap<>();
|
Map<String, PrepareInfo<T>> map = new LinkedHashMap<>();//一定要是LinkedHashMap
|
||||||
for (T entity : entitys) {
|
for (T entity : entitys) {
|
||||||
String table = info.getTable(entity);
|
String table = info.getTable(entity);
|
||||||
map.computeIfAbsent(table, t -> new PrepareInfo(info.getUpdateDollarPrepareSQL(entity))).addEntity(entity);
|
map.computeIfAbsent(table, t -> new PrepareInfo(info.getUpdateDollarPrepareSQL(entity))).addEntity(entity);
|
||||||
|
|||||||
Reference in New Issue
Block a user