2013-04-05 2 views
3

У меня есть простой запрос относительно метода ResultSet.getString() в java для JDBC.
Предположим, что значение в столбце База данных содержит \, который является символом escape javas, например. \n или \t и т. Д.
Когда я получаю значение как getString(), я вижу, что еще один символ перехода добавляется, а фактическое значение этого \n теперь является строковым литералом.
Так что мне пришлось unescape java, а затем использовать его правильно.java resultset.getstring ("col_name") query

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

Когда s содержит `\ N ':

System.out.println(s) 

выхода:

\n 

После неэкранированной Java с помощью Apache общего StringEscapeUtils
выхода:

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

Мой вопрос: кто добавляет это дополнительно \ до unescaping ?? Извините, если это немой вопрос.

+1

Похоже, что JDBC избегает всех специальных характеристик, чтобы текст отображался так, как он хранится в БД. Итак, если у вас есть * hello \ nworld * в БД, он станет «hello \\ nworld», когда он будет извлечен. Выглядит так, как должно быть. – svz

+0

@svz JDBC ничего не скрывает в 'ResultSet'. __That__ так оно и должно быть. В противном случае многие приложения будут иметь проблемы, чтобы знать, что действительно находится в БД, и что изменил какой-то произвольный уровень. –

ответ

2

Драйвер 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 компилятор переводится двумя символами «\ п» в один символ новой строки. Следовательно, драйвер JDBC и база данных видят только один символ.

Но если бы вы прочитали некоторый пользовательский ввод, и пользователь набрал бы \ и n, тогда никто не уклонился от этого, и строка содержала бы два символа.

Следующий шаг

Вы говорите, вы явно де-спасаясь с помощью StringEscapeUtils. Тогда это произойдет:

  • Строка с одним символом будет передаваться без изменений из БД на экран.
  • Строка с двумя символами будет изменена на StringEscapeUtils в строку, содержащую один символ. После этого обе строки выглядят одинаково для вас.

Резюме

Не путайте Стринг-Буквальное избежать компилятором вытекания от JDBC (который не будет).

Не добавляйте лишние экранирующие слои.

+0

unescaping требуется, потому что для моего случая я хочу, чтобы он действовал как ** \ n **, а не как литерал. – Anubhab

+1

@Anubhab Это может быть, но актуально ли оно для вопроса? Речь идет о JDBC. Если ваша логика _display_ действует иначе, чем ваша логика _edit_, тогда она выходит за рамки Q. –

+0

Fine..My последний вопрос: если Resultset имеет return '\\' и 'n', то почему Syso печатает его как' \ n 'почему не как новая линия? – Anubhab

1

getString() не избегает ничего.

Если у вас есть оконечный символ (записывается в виде "\n" в Java Строка буквального, но будучи один символ в строке, чье числовое значение 10) в строке, хранящейся в базе данных, то getString() будет возвращать Строка, содержащая этот символ. Печать этой строки приведет к двум строкам.

Если у вас есть \ символа, за которым следует n символа (который, таким образом, можно записать в виде "\\n" в Ява строкового литерала, но приведут лишь два символа в строке, \ и n), то getString() вернет Строка, содержащая эти два символа. Печать этой строки приведет к печати \n.

Короче говоря, \n используется, чтобы добавить символ новой строки в строковый литерал, в исходный код Java. Но это переводится компилятором в строку, содержащую только один символ новой строки. Не для строки, содержащей обратную косую черту, за которой следует n. Во время выполнения эти escape-последовательности больше не существуют.

+0

Исправлено. StackOverflow, похоже, преобразует двойную обратную косую черту в одну. –

+0

У меня есть ваш вопрос, но мой вопрос в том, кто добавляет дополнительные '\\' then ?? – Anubhab

+0

Ваш код, вероятно, делает это. –