繁体   English   中英

在 Java 中转义 MySQL 字符串......没有准备好的语句

[英]Escape MySQL strings in Java... without prepared statements

我正在寻找一种使用 Java 为 MySQL 查询转义字符串的方法。

但是等等,在你们中的一些人直接跳到“准备好的陈述”的结论之前,我想再解释一下。

问题是,我没有 MySQL 连接。 我没有直接从 Java 执行任何 MySQL 查询。 我对准备好的语句了解不多,但是AFAIK,准备好的语句需要实时连接才能工作。

我想让我的代码读入一堆 CSV/XLS 文件,获取数据,然后为 MySQL 生成一个巨大的 INSERT 查询。 但是这个查询现在将存储在一个文本文件中。 它不会执行,直到有人开绿灯并将此文本文件转储到数据库中。

有没有一种简单的方法可以在不使用矫枉过正的框架/库的情况下做到这一点? 谢谢你们。

似乎没有任何现有的库/框架可以做这样的事情。 所以我猜一个简单的String操纵器可以吗?

class xxx {

    private String escapeStringForMySQL(String s) {
        return s.replaceAll("\\", "\\\\")
                .replaceAll("\b","\\b")
                .replaceAll("\n","\\n")
                .replaceAll("\r", "\\r")
                .replaceAll("\t", "\\t")
                .replaceAll("\\x1A", "\\Z")
                .replaceAll("\\x00", "\\0")
                .replaceAll("'", "\\'")
                .replaceAll("\"", "\\\"");
    }

    private String escapeWildcardsForMySQL(String s) {
        return escapeStringForMySQL(s)
                .replaceAll("%", "\\%")
                .replaceAll("_","\\_");
    }

}

您可以为 MySQL 使用指定的特殊字符转义序列

Escape Sequence Character Represented by Sequence
\0  An ASCII NUL (X'00') character
\'  A single quote (') character
\"  A double quote (") character
\b  A backspace character
\n  A newline (linefeed) character
\r  A carriage return character
\t  A tab character
\Z  ASCII 26 (Control+Z); see note following the table
\\  A backslash (\) character
\%  A % character; see note following the table
\_  A _ character; see note following the table

您可能正在使用专为此目的而设计的OWASP 的 ESAPI 它有 MySQL 编解码器。

试试StringEscapeUtils.escapeSql()这会做你所期望的。

我使用了 org.apache.commons.lang3.StringEscapeUtils.escapeHtml4(input);

您可以在此处查看文档String Escape Util (Commons Lang 3.1 API)

public static final String escapeHtml4(String input) 使用 HTML 实体对字符串中的字符进行转义。

例如:

“面包”和“黄油”

变成: "bread" & "butter". "bread" & "butter".

支持所有已知的 HTML 4.0 实体,包括时髦的口音。 请注意,常用的撇号转义字符 (') 不是法律实体,因此不受支持。

参数: input - 要转义的字符串,可能为 null 返回:一个新的转义字符串,如果为 null 字符串输入则为 null 自:3.0

package io.github.sinri.Keel.test.mysql;

public class MySQLTest {
    public static void main(String[] args) {
        StringBuilder sb=new StringBuilder();
        sb.append('\0').append('\'').append('"').append('\b').append('\n').append('\t').append('\r')
                .append(Character.toChars(26)).append('\\').append('_').append('%');

        String raw=sb.toString();
        System.out.println("raw: "+raw);
        System.out.println("escapeStringForMySQL: "+escapeStringForMySQL(raw));
        System.out.println("escapeWildcardsForMySQL: "+escapeWildcardsForMySQL(raw));

    }

    private static String escapeStringForMySQL(String s) {
        return s.replace("\\", "\\\\")
                .replace("\b","\\b")
                .replace("\n","\\n")
                .replace("\r", "\\r")
                .replace("\t", "\\t")
                .replace(new String(Character.toChars(26)), "\\Z")
                .replace(new String(Character.toChars(0)), "\\0")
                .replace("'", "\\'")
                .replace("\"", "\\\"");
    }

    private static String escapeWildcardsForMySQL(String s) {
        return escapeStringForMySQL(s)
                .replace("%", "\\%")
                .replace("_","\\_");
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM