转义 Java 变量以将 SQL 语句序列化为字符串

问题描述

我们有一个事件系统,可以生成数据库事件以捕获变更数据。

系统发送一个事件,其中包含带有 ? 占位符的 INSERT 或 UPDATE 语句以及与每个问号匹配的有序值数组。

我想将它用于每小时备份文件,所以如果我得到如下语句:

insert into T0(a,b,c) VALUES(?,?,?)

使用一组值 12it's his 然后我将一行写入该小时的备份文件

insert into T0(a,c) VALUES(1,2,'it\'s his');

一些事情:

  1. 是否只有字符串需要转义?我们没有或不允许使用二进制列
  2. 是否已经有一个 Java 库可以做到这一点(来自 Spring 生态系统、Apache 或其他)?
  3. 我已经看到了用于转义 https://github.com/pgjdbc/pgjdbc/blob/master/pgjdbc/src/main/java/org/postgresql/core/Utils.java 的 Postgres JDBC 代码 - 这是否足够?

我还想每小时创建一个 sqlite 数据库,写入 sqlite,然后将其转储到 hr.sql 文本文件。这具有利用 sqlite 处理转义的所有辛勤工作和思想的优势,但如果有一种方法可以在 Java 中执行 toString 然后在文件中附加一行,则感觉有点矫枉过正。

在使用 sqlite 时有一个性能方面的考虑,这也让我对那条路线犹豫不决。

解决方法

找到了一些选项。

Postgres JDBC 驱动程序是这个 https://github.com/pgjdbc/pgjdbc/blob/master/pgjdbc/src/main/java/org/postgresql/core/Utils.java 和其他实现。甚至更简单https://github.com/p6spy/p6spy/blob/master/src/main/java/com/p6spy/engine/common/Value.java#L172 字面上做

ESPECIAL_CHARACTER_PATTERN.matcher(stringValue).replaceAll("''")

哪里private static final Pattern ESPECIAL_CHARACTER_PATTERN = Pattern.compile("'");

在这两种情况下,我认为只有字符串需要这个,二进制是单独处理的,但我们没有/需要二进制。

进一步挖掘,我重新发现了 ESAPI https://github.com/ESAPI/esapi-java-legacy 他们有一个用于转义 SQL https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html#defense-option-4-escaping-all-user-supplied-input

的库

https://github.com/ESAPI/esapi-java-legacy/blob/develop/src/main/java/org/owasp/esapi/codecs/MySQLCodec.java