From 27a587d31f3561ffa68174dbf8f0bb0e0a561429 Mon Sep 17 00:00:00 2001 From: Redkale <8730487+redkale@users.noreply.github.com> Date: Fri, 12 Jul 2019 16:52:46 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dmysql=E4=B8=8Bupdate=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E5=80=BC=E5=B8=A6=E8=BD=AC=E4=B9=89=E5=AD=97=E7=AC=A6?= =?UTF-8?q?=E5=AF=BC=E8=87=B4=E5=A4=B1=E8=B4=A5=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/org/redkale/source/DataJdbcSource.java | 4 +- src/org/redkale/source/DataSqlSource.java | 33 +++++++------ src/org/redkale/source/EntityInfo.java | 57 +++++++++++++++++++--- src/org/redkale/source/FilterNode.java | 2 +- 4 files changed, 71 insertions(+), 25 deletions(-) diff --git a/src/org/redkale/source/DataJdbcSource.java b/src/org/redkale/source/DataJdbcSource.java index 7f09272fb..3aba98f83 100644 --- a/src/org/redkale/source/DataJdbcSource.java +++ b/src/org/redkale/source/DataJdbcSource.java @@ -142,7 +142,7 @@ public class DataJdbcSource extends DataSqlSource { if (obj != null && obj.getClass().isArray()) { sb.append("'[length=").append(java.lang.reflect.Array.getLength(obj)).append("]'"); } else { - sb.append(FilterNode.formatToString(obj)); + sb.append(info.formatSQLValue(obj, sqlFormatter)); } } else { sb.append(ch); @@ -290,7 +290,7 @@ public class DataJdbcSource extends DataSqlSource { if (obj != null && obj.getClass().isArray()) { sb.append("'[length=").append(java.lang.reflect.Array.getLength(obj)).append("]'"); } else { - sb.append(FilterNode.formatToString(obj)); + sb.append(info.formatSQLValue(obj, sqlFormatter)); } } else { sb.append(ch); diff --git a/src/org/redkale/source/DataSqlSource.java b/src/org/redkale/source/DataSqlSource.java index b3cc27e90..2c7795df9 100644 --- a/src/org/redkale/source/DataSqlSource.java +++ b/src/org/redkale/source/DataSqlSource.java @@ -59,6 +59,8 @@ public abstract class DataSqlSource extends AbstractService implement @Resource(name = "$") protected DataCacheListener cacheListener; + protected final BiFunction sqlFormatter; + protected final BiConsumer futureCompleteConsumer = (r, t) -> { if (t != null) logger.log(Level.SEVERE, "CompletableFuture complete error", (Throwable) t); }; @@ -107,6 +109,7 @@ public abstract class DataSqlSource extends AbstractService implement Semaphore semaphore = maxconns > 0 ? new Semaphore(maxconns) : null; this.readPool = createPoolSource(this, "read", queue, semaphore, readprop); this.writePool = createPoolSource(this, "write", queue, semaphore, writeprop); + this.sqlFormatter = (info, val) -> formatValueToString(info, val); } @Local @@ -284,7 +287,7 @@ public abstract class DataSqlSource extends AbstractService implement return null; } - protected String formatValueToString(final EntityInfo info, Object value) { + protected CharSequence formatValueToString(final EntityInfo info, Object value) { final String dbtype = this.readPool.getDbtype(); if ("mysql".equals(dbtype)) { if (value == null) return null; @@ -296,7 +299,7 @@ public abstract class DataSqlSource extends AbstractService implement } return String.valueOf(value); } - return info.formatToString(value); + return info.formatSQLValue(value, null); } //----------------------------- insert ----------------------------- @@ -506,13 +509,13 @@ public abstract class DataSqlSource extends AbstractService implement protected CompletableFuture deleteCompose(final EntityInfo info, final Serializable... pks) { if (pks.length == 1) { - String sql = "DELETE FROM " + info.getTable(pks[0]) + " WHERE " + info.getPrimarySQLColumn() + " = " + FilterNode.formatToString(info.getSQLValue(info.getPrimarySQLColumn(), pks[0])); + String sql = "DELETE FROM " + info.getTable(pks[0]) + " WHERE " + info.getPrimarySQLColumn() + " = " + info.formatSQLValue(info.getPrimarySQLColumn(), pks[0], sqlFormatter); return deleteDB(info, null, sql); } String sql = "DELETE FROM " + info.getTable(pks[0]) + " WHERE " + info.getPrimarySQLColumn() + " IN ("; for (int i = 0; i < pks.length; i++) { if (i > 0) sql += ','; - sql += FilterNode.formatToString(info.getSQLValue(info.getPrimarySQLColumn(), pks[i])); + sql += info.formatSQLValue(info.getPrimarySQLColumn(), pks[i], sqlFormatter); } sql += ")"; if (info.isLoggable(logger, Level.FINEST, sql)) logger.finest(info.getType().getSimpleName() + " delete sql=" + sql); @@ -795,11 +798,11 @@ public abstract class DataSqlSource extends AbstractService implement protected CompletableFuture updateColumnCompose(final EntityInfo info, Serializable pk, String column, final Serializable colval) { if (colval instanceof byte[]) { - String sql = "UPDATE " + info.getTable(pk) + " SET " + info.getSQLColumn(null, column) + " = " + prepareParamSign(1) + " WHERE " + info.getPrimarySQLColumn() + " = " + FilterNode.formatToString(info.getSQLValue(info.getPrimarySQLColumn(), pk)); + String sql = "UPDATE " + info.getTable(pk) + " SET " + info.getSQLColumn(null, column) + " = " + prepareParamSign(1) + " WHERE " + info.getPrimarySQLColumn() + " = " + info.formatSQLValue(info.getPrimarySQLColumn(), pk, sqlFormatter); return updateDB(info, null, sql, true, colval); } else { String sql = "UPDATE " + info.getTable(pk) + " SET " + info.getSQLColumn(null, column) + " = " - + formatValueToString(info, info.getSQLValue(column, colval)) + " WHERE " + info.getPrimarySQLColumn() + " = " + FilterNode.formatToString(info.getSQLValue(info.getPrimarySQLColumn(), pk)); + + info.formatSQLValue(column, colval, sqlFormatter) + " WHERE " + info.getPrimarySQLColumn() + " = " + info.formatSQLValue(info.getPrimarySQLColumn(), pk, sqlFormatter); return updateDB(info, null, sql, false); } } @@ -871,7 +874,7 @@ public abstract class DataSqlSource extends AbstractService implement return updateDB(info, null, sql, true, colval); } else { String sql = "UPDATE " + info.getTable(node) + " a " + (join1 == null ? "" : (", " + join1)) - + " SET " + info.getSQLColumn(alias, column) + " = " + formatValueToString(info, colval) + + " SET " + info.getSQLColumn(alias, column) + " = " + info.formatSQLValue(colval, sqlFormatter) + ((where == null || where.length() == 0) ? (join2 == null ? "" : (" WHERE " + join2)) : (" WHERE " + where + (join2 == null ? "" : (" AND " + join2)))); return updateDB(info, null, sql, false); @@ -940,11 +943,11 @@ public abstract class DataSqlSource extends AbstractService implement blobs.add((byte[]) col.getValue()); setsql.append(c).append(" = ").append(prepareParamSign(++index)); } else { - setsql.append(c).append(" = ").append(info.formatSQLValue(c, attr, col)); + setsql.append(c).append(" = ").append(info.formatSQLValue(c, attr, col, sqlFormatter)); } } if (setsql.length() < 1) return CompletableFuture.completedFuture(0); - String sql = "UPDATE " + info.getTable(pk) + " SET " + setsql + " WHERE " + info.getPrimarySQLColumn() + " = " + FilterNode.formatToString(info.getSQLValue(info.getPrimarySQLColumn(), pk)); + String sql = "UPDATE " + info.getTable(pk) + " SET " + setsql + " WHERE " + info.getPrimarySQLColumn() + " = " + info.formatSQLValue(info.getPrimarySQLColumn(), pk, sqlFormatter); if (blobs == null) return updateDB(info, null, sql, false); return updateDB(info, null, sql, true, blobs.toArray()); } @@ -1022,7 +1025,7 @@ public abstract class DataSqlSource extends AbstractService implement blobs.add((byte[]) col.getValue()); setsql.append(c).append(" = ").append(prepareParamSign(++index)); } else { - setsql.append(c).append(" = ").append(info.formatSQLValue(c, attr, col)); + setsql.append(c).append(" = ").append(info.formatSQLValue(c, attr, col, sqlFormatter)); } } if (setsql.length() < 1) return CompletableFuture.completedFuture(0); @@ -1157,7 +1160,7 @@ public abstract class DataSqlSource extends AbstractService implement blobs.add((byte[]) val); setsql.append(" = ").append(prepareParamSign(++index)); } else { - setsql.append(" = ").append(formatValueToString(info, val)); + setsql.append(" = ").append(info.formatSQLValue(val, sqlFormatter)); } } if (neednode) { @@ -1178,7 +1181,7 @@ public abstract class DataSqlSource extends AbstractService implement return updateDB(info, null, sql, true, blobs.toArray()); } else { final Serializable id = (Serializable) info.getSQLValue(info.getPrimary(), entity); - String sql = "UPDATE " + info.getTable(id) + " a SET " + setsql + " WHERE " + info.getPrimarySQLColumn() + " = " + FilterNode.formatToString(id); + String sql = "UPDATE " + info.getTable(id) + " a SET " + setsql + " WHERE " + info.getPrimarySQLColumn() + " = " + info.formatSQLValue(id, sqlFormatter); if (blobs == null) return updateDB(info, null, sql, false); return updateDB(info, null, sql, true, blobs.toArray()); } @@ -1557,7 +1560,7 @@ public abstract class DataSqlSource extends AbstractService implement protected CompletableFuture findCompose(final EntityInfo info, final SelectColumn selects, Serializable pk) { String column = info.getPrimarySQLColumn(); - final String sql = "SELECT " + info.getQueryColumns(null, selects) + " FROM " + info.getTable(pk) + " WHERE " + column + " = " + FilterNode.formatToString(info.getSQLValue(column, pk)); + final String sql = "SELECT " + info.getQueryColumns(null, selects) + " FROM " + info.getTable(pk) + " WHERE " + column + " = " + info.formatSQLValue(column, pk, sqlFormatter); if (info.isLoggable(logger, Level.FINEST, sql)) logger.finest(info.getType().getSimpleName() + " find sql=" + sql); return findDB(info, sql, true, selects); } @@ -1694,7 +1697,7 @@ public abstract class DataSqlSource extends AbstractService implement } protected CompletableFuture findColumnCompose(final EntityInfo info, String column, final Serializable defValue, final Serializable pk) { - final String sql = "SELECT " + info.getSQLColumn(null, column) + " FROM " + info.getTable(pk) + " WHERE " + info.getPrimarySQLColumn() + " = " + FilterNode.formatToString(info.getSQLValue(info.getPrimarySQLColumn(), pk)); + final String sql = "SELECT " + info.getSQLColumn(null, column) + " FROM " + info.getTable(pk) + " WHERE " + info.getPrimarySQLColumn() + " = " + info.formatSQLValue(info.getPrimarySQLColumn(), pk, sqlFormatter); if (info.isLoggable(logger, Level.FINEST, sql)) logger.finest(info.getType().getSimpleName() + " find sql=" + sql); return findColumnDB(info, sql, true, column, defValue); } @@ -1756,7 +1759,7 @@ public abstract class DataSqlSource extends AbstractService implement } protected CompletableFuture existsCompose(final EntityInfo info, Serializable pk) { - final String sql = "SELECT COUNT(*) FROM " + info.getTable(pk) + " WHERE " + info.getPrimarySQLColumn() + " = " + FilterNode.formatToString(info.getSQLValue(info.getPrimarySQLColumn(), pk)); + final String sql = "SELECT COUNT(*) FROM " + info.getTable(pk) + " WHERE " + info.getPrimarySQLColumn() + " = " + info.formatSQLValue(info.getPrimarySQLColumn(), pk, sqlFormatter); if (info.isLoggable(logger, Level.FINEST, sql)) logger.finest(info.getType().getSimpleName() + " exists sql=" + sql); return existsDB(info, sql, true); } diff --git a/src/org/redkale/source/EntityInfo.java b/src/org/redkale/source/EntityInfo.java index e237bbdc5..8b7b70ba1 100644 --- a/src/org/redkale/source/EntityInfo.java +++ b/src/org/redkale/source/EntityInfo.java @@ -894,9 +894,36 @@ public final class EntityInfo { return handler.encrypt(fieldvalue); } + /** + * 字段值转换成带转义的数据库的值 + * + * @param fieldname 字段名 + * @param fieldvalue 字段值 + * @param sqlFormatter 转义器 + * + * @return CharSequence + */ + public CharSequence formatSQLValue(String fieldname, Serializable fieldvalue, BiFunction sqlFormatter) { + Object val = getSQLValue(fieldname, fieldvalue); + return sqlFormatter == null ? formatToString(val) : sqlFormatter.apply(this, val); + } + + /** + * 字段值转换成带转义的数据库的值 + * + * @param value 字段值 + * @param sqlFormatter 转义器 + * + * @return CharSequence + */ + public CharSequence formatSQLValue(Object value, BiFunction sqlFormatter) { + return sqlFormatter == null ? formatToString(value) : sqlFormatter.apply(this, value); + } + /** * 字段值转换成数据库的值 * + * @param 泛型 * @param attr Attribute * @param entity 记录对象 * @@ -909,6 +936,21 @@ public final class EntityInfo { return val; } + /** + * 字段值转换成带转义的数据库的值 + * + * @param 泛型 + * @param attr Attribute + * @param entity 记录对象 + * @param sqlFormatter 转义器 + * + * @return CharSequence + */ + public CharSequence formatSQLValue(Attribute attr, T entity, BiFunction sqlFormatter) { + Object val = getSQLValue(attr, entity); + return sqlFormatter == null ? formatToString(val) : sqlFormatter.apply(this, val); + } + /** * 数据库的值转换成数字段值 * @@ -947,13 +989,14 @@ public final class EntityInfo { /** * 拼接UPDATE给字段赋值的SQL片段 * - * @param col 表字段名 - * @param attr Attribute - * @param cv ColumnValue + * @param col 表字段名 + * @param attr Attribute + * @param cv ColumnValue + * @param formatter 转义器 * * @return CharSequence */ - protected CharSequence formatSQLValue(String col, Attribute attr, final ColumnValue cv) { + protected CharSequence formatSQLValue(String col, Attribute attr, final ColumnValue cv, BiFunction formatter) { if (cv == null) return null; Object val = cv.getValue(); CryptHandler handler = attr.attach(); @@ -968,9 +1011,9 @@ public final class EntityInfo { case ORR: return new StringBuilder().append(col).append(" | ").append(val); case MOV: - return formatToString(val); + return formatter == null ? formatToString(val) : formatter.apply(this, val); } - return formatToString(val); + return formatter == null ? formatToString(val) : formatter.apply(this, val); } /** @@ -1021,7 +1064,7 @@ public final class EntityInfo { * * @return String */ - protected String formatToString(Object value) { + private String formatToString(Object value) { if (value == null) return null; if (value instanceof CharSequence) { return new StringBuilder().append('\'').append(value.toString().replace("'", "\\'")).append('\'').toString(); diff --git a/src/org/redkale/source/FilterNode.java b/src/org/redkale/source/FilterNode.java index c837d9129..a988f118a 100644 --- a/src/org/redkale/source/FilterNode.java +++ b/src/org/redkale/source/FilterNode.java @@ -1811,7 +1811,7 @@ public class FilterNode { //FilterNode 不能实现Serializable接口, 否则 return sb; } - protected static CharSequence formatToString(Object value) { + private static CharSequence formatToString(Object value) { CharSequence sb = formatToString(null, value); return sb == null ? null : sb.toString(); }