3

我有一个关于ResultSet.getString()JDBC 的 java 方法的简单查询。
假设 Database 列中的值具有一个\javas 转义字符,例如\n\t
当我检索该值时,getString()我看到又添加了一个转义字符,而它的实际含义\n现在只是一个字符串文字。
所以我不得不取消转义java,然后正确使用它。

String s= rs.getString("col_name");

s包含 `\n' 时:

System.out.println(s)

输出:

\n

使用 apache 公共StringEscapeUtils
输出对 java 进行转义后:

System.out.println("hi"+s+"hello");
hi
hello

我的问题是谁\在取消转义之前添加了这个额外的?对不起,如果这是一个愚蠢的问题。

4

2 回答 2

2

JDBC 驱动程序在ResultSet. 如果真的发生了,那就太糟糕了。看这个简单的例子:

数据库表x确实包含一列value。有两行:一行带有两个字符串('\'and 'n'),另一行带有一个字符串(换行符)。我在输出中添加了一个字符串长度以进行澄清。

select *, length(value) from x;
 value | length 
-------+--------
 \n    |      2
      +|      1
       | 

使用 JDBC 读取此表:

    Connection db = DriverManager.getConnection( /* these parameters are up to you */ );

    Statement st = db.createStatement();
    ResultSet rs = st.executeQuery("select value, length(value) from x");
    while(rs.next()){
        String value = rs.getString(1);
        int length = rs.getInt(2);

        System.out.println("length="+length+", value='"+value+"'");
    }

您会看到:到目前为止,代码中的任何地方都没有显式转义。输出是:

length=2, value='\n'
length=1, value='
'

你看:仍然没有任何东西被转义——代码和 JDBC 都没有。

如果你混合使用 Java 文字,事情会变得有点模糊:如果你做这样的事情:

st.execute("insert into x values ('\n')");

然后猜猜发生了什么?您还有一个字符的另一行!

length=2, value='\n'
length=1, value='
'
length=1, value='
'

这是因为 Java编译器将两个字符 '\n' 翻译成一个换行符。因此 JDBC 驱动程序和数据库只能看到一个字符。

但是,如果您已经阅读了一些用户输入并且用户已经键入\n那么没有人会对此进行转义,并且该行将包含两个字符。

下一步

您说,您使用StringEscapeUtils. 然后会发生这种情况:

  • 带有一个字符的行将从数据库中原封不动地传递到屏幕上。
  • 包含两个字符的行将被更改StringEscapeUtils为包含一个字符的字符串。在那之后,这两行对你来说看起来都一样。

概括

不要将编译器的字符串文字转义与 JDBC 的转义混淆(这不会发生)。

不要添加不必要的转义层。

于 2013-04-05T09:20:44.550 回答
1

getString()不会逃避任何事情。

如果您在存储在数据库中的字符串中有一个 EOL 字符(写成"\n"Java 字符串文字,但它是字符串中的单个字符,其数值为 10),那么getString()将返回一个包含该字符的字符串。打印此字符串将产生两行。

如果您有一个\字符后跟一个n字符(因此可以写成"\\n"Java 字符串文字,但只会导致字符串中有两个字符\n),那么getString()将返回一个包含这两个字符的字符串。打印此字符串将导致\n被打印。

简而言之,\n用于能够在 Java 源代码中的 String 文字中添加换行符。但是编译器会将其转换为仅包含一个换行符的字符串。不是包含反斜杠后跟n. 在运行时,这些转义序列不再存在。

于 2013-04-05T07:35:16.120 回答