Как избежать потери пунктуации при извлечении данных из базы данных MySQL с помощью JDBC? - PullRequest
4 голосов
/ 30 декабря 2011

Перво-наперво, я использую:

Java 1.7.0_02
MySQL 5.1.50
ZendServer CE (if that matters)

Драйвер JDBC, который я использую для подключения к MySQL из Java, - com.mysql.jdbc.Driver. Подключение к базе данных работает нормально.

Моя строка подключения:

jdbc:mysql://localhost:3306/table

И в попытках решить проблему, которую я имею, я добавил

?useUnicode=true&characterEncoding=UTF-8 

к строке подключения.

Я работаю с дампом Википедии, весь текст в формате MediaWiki, и я анализирую контент с JWPL, который прекрасно работает для меня, и в процессе извлечения из базы данных, анализа и отображения через HTML я теряю такие символы, как '-' и одинарные кавычки, и вместо этого получаю Earth���s вместо Earth's.

После некоторого тестирования я свелся к тому, что символы не кодируются / декодируются должным образом где-то между запросом MySQL и обработкой строки в Java, я пришел к такому выводу, потому что текст в базе данных (хранится как MEDIUMBLOB) содержит правильные символы, как и должно быть, и немедленный вывод String в Java после того, как в вызове БД были сломаны / пропущены символы («?????» вместо японских символов и т. Д.).

Я проверил, что System.getProperty("file.encoding"); - это UTF-8, поэтому JVM должна правильно кодировать строку при печати (если только что-то не так с преобразованием UTF-8> UTF-16> UTF-8 в JVM.

Я также создал таблицу UTF-8 со столбцами UTF-8 и переместил данные в нее в базе данных для тестирования, которое ничего не решало. Другая попытка исправить была заменить:

return result.getString("old_text");

, который извлекает текст из Result, установленного в:

return new String(result.getString("old_text").getBytes("utf8"), "utf8");

, который дал мне те же результаты, что и предыдущий оператор.

Можно ли избежать такой потери символьных данных при доступе к MySQL с помощью JDBC, если нет, то есть ли способ обработки символов и восстановления правильного символа для отображения? Два и три блока случайных символов вместо стандартных знаков препинания мешают работе пользователя.

EDIT

Небольшое примечание, данные в базе данных в порядке - символы присутствуют, все они и видимы. Доступ к дате через phpMyAdmin возвращает данные с правильно закодированными символами. Проблема возникает где-то между MySQL и Java, возможно, с JDBC. Я ищу настройку или обходной путь (который работает, поскольку те, которые я пробовал, не работают для меня), которые предотвратят потерю этих кодов символов.

Ответы [ 2 ]

1 голос
/ 30 декабря 2011

После некоторого исследования и чтения я пришел, чтобы найти решение, которое решило бы проблемы, которые у меня были. Я не могу сказать, почему, но похоже, что в Java MEDIUMBLOB был преобразован тип String.

Вот как я возвращал текст из результата:

if (result.next())
    return result.getString("old_text");
else
    return null;

В прошлом я мало что делал с JDBC и не знал, что существует класс Blob, поэтому я изменил код на:

if (result.next()) {
    Blob blob = result.getBlob("old_text");
    InputStream is = blob.getBinaryStream();
    byte[] bytes = new byte[is.available()];
    is.read(bytes);
    is.close();

    return new String(bytes, "UTF-8");
}
else
    return null;

И это прекрасно работает.

0 голосов
/ 30 декабря 2011

Я думаю, что проблема заключается в том, как вы кодируете и декодируете байты в BLOB-объекте.И это, вероятно, потому, что кодировка по умолчанию не соответствует вашим ожиданиям.

Я бы порекомендовал вам получить и поместить байтовые массивы и явно указывать кодировку UTF-8 при преобразовании строк в байтовые массивы.и обратноНе полагайтесь на предположения о кодировке по умолчанию.

FWIW, правильный способ узнать, что такое кодировка по умолчанию JVM - это посмотреть на объект, возвращаемый Charset.defaultCharset().

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