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驅動程序和數據庫只能看到一個字符。
但是,如果你會看到一些userinput和用戶將鍵入\
和n
然後沒有人會避免這種情況,該行將包含兩個字符。
下一步
你說,你做明確的使用StringEscapeUtils
去逃避。然後這會發生:
- 有一個字符的行將從數據庫一直傳遞到屏幕。
- 具有兩個字符的行將被
StringEscapeUtils
更改爲包含一個字符的字符串。之後,這兩行對你來說看起來都一樣。
摘要
不要混淆字符串文本逃逸編譯器與JDBC轉義(不會發生)。
請勿添加不必要的轉義層。
看起來JDBC正在逃避所有特殊的功能,以確保文本以存儲在數據庫中的方式顯示。因此,如果你在數據庫中有* hello \ nworld *,當它被提取時它將變成'hello \\ nworld'。看起來應該是這樣。 – svz 2013-04-05 07:05:21
@svz JDBC不會在「ResultSet」中轉義任何內容。 __那是它應該的方式。否則,很多應用程序都會遇到問題,無法知道數據庫中的真實內容以及某些任意層發生了什麼變化。 – 2013-04-05 09:34:48