Персонаж преобразуется в JDBC - PullRequest
3 голосов
/ 05 апреля 2011

Я пытаюсь прочитать строку UTF-8 из моей базы данных MySql, которую я создаю, используя:

CREATE DATABASE april
  DEFAULT CHARACTER SET utf8
  DEFAULT COLLATE utf8_general_ci;

Я составляю таблицу интереса, используя:

DROP TABLE IF EXISTS `article`;
CREATE TABLE `article` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `text` longtext NOT NULL,
  `date_created` timestamp DEFAULT NOW(),
  PRIMARY KEY (`id`)
) CHARACTER SET utf8;

Если я select * from article в утилите командной строки MySql, я получу:

OIL sands output at Nexen’s Long Lake project dropped in February.

Однако, когда я делаю

ResultSet rs = st.executeQuery(QUERY);

long id = -1;
String text = null;
Timestamp date = null;
while (rs.next()) {
    text = rs.getString("text");
    LOGGER.debug("text=" text);
}

вывод, который я получаю:

text=OIL sands output at Nexen’s Long Lake project dropped in February.

Я получаю соединение через:

DriverManager.getConnection("jdbc:" + this.dbms + "://" + this.serverHost + ":" + this.serverPort + "/" + this.dbName + "?useUnicode&user=" + this.username + "&password=" + this.password);

Я также пробовал вместо параметра useUnicode:

characterEncoding=UTF-8
and
characterEncoding=utf8

Я тоже попробовал вместо строки text = rs.getString("text")

rs.getBytes("text");
String[] encodings = new String[]{"US-ASCII", "ISO-8859-1", "UTF-8", "UTF-16BE", "UTF-16LE", "UTF-16", "Latin1"};
for (String encoding : encodings) {
    text = new String(temp, encoding);
    LOGGER.debug(encoding + ": " + text);
}
// Which outputted:
US-ASCII: OIL sands output at Nexen��������s Long Lake project dropped in February.
ISO-8859-1: OIL sands output at Nexenââ¬â¢s Long Lake project dropped in February.
UTF-8: OIL sands output at Nexen’s Long Lake project dropped in February.
UTF-16BE: 佉䰠獡湤猠潵瑰畴⁡琠乥硥滃ꋢ芬ꉳ⁌潮朠䱡步⁰牯橥捴⁤牯灰敤⁩渠䙥扲畡特�
UTF-16LE: 䥏⁌慳摮⁳畯灴瑵愠⁴敎數썮겂蓢玢䰠湯⁧慌敫瀠潲敪瑣搠潲灰摥椠敆牢慵祲�
UTF-16: 佉䰠獡湤猠潵瑰畴⁡琠乥硥滃ꋢ芬ꉳ⁌潮朠䱡步⁰牯橥捴⁤牯灰敤⁩渠䙥扲畡特�
Latin1: OIL sands output at Nexenââ¬â¢s Long Lake project dropped in February.

Я загружаю строки в БД с помощью некоторого предопределенного sql в файле. Этот файл в кодировке UTF-8.

mysql -u april -p -D april < insert_articles.sql

Этот файл содержит строку:

 INSERT INTO article (text) value ("OIL sands output at Nexen’s Long Lake project dropped in February.");

Когда я распечатываю этот файл в приложении, используя:

BufferedReader reader = new BufferedReader(new FileReader(new File("/home/path/to/file/sql_article_inserts.sql")));
 String str;
 while((str = reader.readLine()) != null) {
     LOGGER.debug("LINE: " + str);
 }

Я получаю правильный ожидаемый результат:

LINE: INSERT INTO article (text) value ("OIL sands output at Nexen’s Long Lake project dropped in February.");

Любая помощь будет принята с благодарностью.

Некоторые сведения о системе: Я работаю на Linux (Ubuntu)

Редактирование:
* Отредактировано для указания ОС
* Отредактировано для детального вывода чтения файла ввода SQL.
* Отредактировано, чтобы указать больше о том, как данные вставляются в БД.
* Исправлено, чтобы исправить опечатку в коде и уточнить пример.

Ответы [ 4 ]

2 голосов
/ 05 апреля 2011

Возможно ли, что вы читаете файл журнала, используя неправильную кодировку? windows-1252, наверное.

UTF-8: OIL sands output at Nexen’s Long Lake project dropped in February.

Если это появляется в журнале, сделайте шестнадцатеричный дамп файла журнала. Если данные UTF-8, можно ожидать, что последовательность Nexen’s станет 4E 65 78 65 6E E2 80 99 73. Если какое-либо другое приложение считывает это как собственную кодировку ANSI, оно будет декодировать его как Nexen’s.

Для подтверждения вы также можете сбросить отдельные символы возвращаемого значения, чтобы увидеть, верны ли они в UTF-16:

//untested
for(char ch : text.toCharArray()) {
   System.out.printf("%04x%n", (int) ch);
}

Я предполагаю, что все данные находятся в BMP , поэтому вы можете просто посмотреть результаты в Unicode-диаграммах .

1 голос
/ 05 апреля 2011

Попробуйте установить саму базу данных в UTF-8.При создании БД:

CREATE DATABASE mydb
  DEFAULT CHARACTER SET utf8
  DEFAULT COLLATE utf8_general_ci;

Также см. Справочник MySQL по кодировкам соединений и Справочник MySQL по настройке кодировок для приложений

0 голосов
/ 05 апреля 2011

Используется несколько кодировок символов.

  • Окно терминала / cmd, в котором запущен инструмент командной строки mysql.(putty?)
  • окружение в оболочке (bash), где вы запускаете свои вещи.(LC_CTYPE)
  • Mysql внутренний (используется в таблицах): вы определили это для UTF-8
  • Внутренняя JVM (всегда UTF16)
  • Символ, используемый авторамирегистратор используй.По умолчанию (системное свойство) или, возможно, определено в конфигурации каркасов ведения журналов.
  • Terminal / cmd / editor, с которым вы читаете журналы.(putty / bash?)

Если настройки терминала неверны, возможно, вы вставили поврежденные данные в mysql.(Если ваш терминал iso-8859-1 и вы читаете файл, например, UTF-8) Предполагая, что linux, mysql должен посмотреть env LC_CTYPE (но я не уверен на 100%, что это так.)

Драйвер JDBCD отвечает за преобразование кодировки символов базы данных во внутренний формат JVM (UTF16), так что это не должно быть проблемой.Но вы можете проверить это с помощью Java-программы simpel, которая вставляет жестко закодированную строку и читает ее обратно.Напечатайте оригинал и полученную строку - они должны быть идентичны.Но; Если оба неверны, у вас есть проблема с определением набора символов терминала.

Используйте строку типа "HejÅÄÖ" для некоторой драмы ...

Так же, напишите небольшую программу, которая печатает ту же строку в файл, используя принтер печати, конвертирующий в UTF-8, и убедитесь, что инструмент, который вы используете для чтения журнала, правильно печатает этот файл.Если нет, то настройки терминала должны быть заподозрены, опять же.

String test = "Test HEJ \u00C5\u00C4\u00D6 ÅÄÖ";
 // here's how to define what character set to use when writing to a fileOutputStream
PrintWriter pw = new PrintWriter("test.txt","UTF8");
pw.println(test);
pw.flush();
pw.close();
System.out.println(test);

output -> Test HEJ ÅÄÖ ÅÄÖ

Содержимое файла test.txt должно выглядеть одинаково.

0 голосов
/ 05 апреля 2011

Параметры в URL-адресе JDBC определяют только то, как драйвер должен взаимодействовать с сервером. Если сервер по умолчанию не использует UTF8, эти параметры также не изменят его.

Вы пытались выполнить следующий запрос SQL после подключения? (Это должно переключить текущее соединение на UTF8 на стороне сервера):

SET names utf8
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...