【问题标题】:java resultset.getstring("col_name") queryjava resultset.getstring("col_name") 查询
【发布时间】:2013-03-27 12:04:16
【问题描述】:

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

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

s 包含`\n'时:

System.out.println(s)

输出:

\n

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

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

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

【问题讨论】:

  • 看起来 JDBC 正在转义所有特殊字符以确保文本以存储在 DB 中的方式显示。因此,如果您在 DB 中有 hello\nworld,则在获取时它将变为 hello\\nworld。看起来应该是这样。
  • @svz JDBC 不会转义 ResultSet 中的任何内容。 是应该的。否则,许多应用程序将无法了解数据库中的真正内容以及某些任意层发生了哪些变化。

标签: java escaping resultset getstring


【解决方案1】:

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

数据库表x 确实包含一列value。有两行:一行包含两个字符串('\''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 进行显式反转义。然后会发生这种情况:

  • 只有一个字符的行将从 DB 原封不动地传递到屏幕上。
  • 有两个字符的行将被StringEscapeUtils 更改为一个包含一个字符的字符串。之后,这两行对您来说看起来都一样。

总结

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

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

【讨论】:

  • 需要取消转义,因为对于我的情况,我希望它充当 \n 而不是文字。
  • @Anubhab 可能是这样,但它与问题相关吗?问题是关于 JDBC 的。如果您的 显示逻辑 的行为与您的 编辑逻辑 不同,则它超出了 Q 的范围。
  • 很好..我的最后一个问题是,如果结果集返回 \` and n` 那么为什么 Syso 将其打印为 \n 为什么不作为换行符呢??
  • 如前所述:only 进行 '\n' 转换的是编译时的编译器,并且仅适用于字符串文字。其他人都不会接触数据。因此在运行时也不是System.out.println
【解决方案2】:

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

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

如果您有一个\ 字符后跟一个n 字符(因此在Java 字符串文字中将写为"\\n",但只会导致字符串中有两个字符\ 和@ 987654328@),然后getString() 将返回一个包含这两个字符的字符串。打印此字符串将导致打印\n

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

【讨论】:

  • 已修复。 StackOverflow 似乎将双反斜杠转换为单反斜杠。
  • 我明白你的意思,但我的问题是谁在添加额外的 `\` 呢??
  • @Anubhab 或者数据库确实包含两个字符 '\' 和 'n',StringEscapeUtils 尽职尽责地翻译成换行符。
猜你喜欢
  • 2015-04-07
  • 2020-05-23
  • 2023-01-20
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多