Главная Случайная страница


Полезное:

Как сделать разговор полезным и приятным Как сделать объемную звезду своими руками Как сделать то, что делать не хочется? Как сделать погремушку Как сделать так чтобы женщины сами знакомились с вами Как сделать идею коммерческой Как сделать хорошую растяжку ног? Как сделать наш разум здоровым? Как сделать, чтобы люди обманывали меньше Вопрос 4. Как сделать так, чтобы вас уважали и ценили? Как сделать лучше себе и другим людям Как сделать свидание интересным?


Категории:

АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника






Базы данных





Для того, чтобы прочитать корректно символы из БД, обычно достаточно указать JDBC-драйверу на нужную кодировку символов в БД. Как именно - это зависит от конкретного драйвера. Сейчас уже многие драйвера поддерживают подобную настройку, в отличии от недавнего прошлого. Далее приведены несколько известных мне примеров.

Мост JDBC-ODBC

Это один из самых часто используемых драйверов. Мост из JDK 1.2 и старше можно легко настроить на нужную кодировку. Это делается добавлением дополнительного свойства charSet в набор параметров, передаваемых для открытия соединения с базой. По умолчанию используется file.encoding. Делается это примерно так:

// Параметры соединения с базой

Properties connInfo = new Properties();

connInfo.put("user", username);

connInfo.put("password", password);

connInfo.put("charSet", "Cp1251");

// Устанавливаем соединение

Connection db = DriverManager.getConnection(dataurl, connInfo);

Драйвер JDBC-OCI от Oracle 8.0.5 под Linux

При получении данных из БД, данный драйвер определяет "свою" кодировку при помощи переменной окружения NLS_LANG. Если эта переменная не найдена, то он считает что кодировка - ISO-8859-1. Весь фокус в том, что NLS_LANG должна быть именно переменной окружения (устанавливаемой командой set), а не системное свойство Java (типа file.encoding). В случае использования драйвера внутри servlet engine Apache+Jserv, переменную окружения можно задать в файле jserv.properties:

wrapper.env=NLS_LANG=American_America.CL8KOI8R

Информацию об этом прислал Сергей Безруков, за что ему отдельное спасибо.

Драйвер JDBC-thin от Oracle

Сей драйвер вроде как не требует особой настройки. По крайней мере в документации об этом ни слова. По всей видимости у Oracle в протоколе обмена ходит нормальный Unicode, правда за исключением составных типов (типы Object и Collection). Если Вы пользуетесь сложными типами, то не забудьте про отдельный zip с поддержкой кодировок (с именем типа nls_charset12.zip), который скачивается отдельно. В противном случае драйвер будет поддерживать только минимум (US7ASCII, WE8DEC, WE8ISO8859P1 и UTF8) и, если БД была создана в другой кодировке, то при получении строковых значений из составных типов будет сплошной 16-ричный мусор (если включён log у DriverManager, то при этом будет видна ругань на неизвестную кодировку).

Самая большая проблема, с которой многие сталкиваются - некорректная кодировка сообщений об ошибках. Дело в том, что оригинальные драйвера от Oracle 8.1.7 и 9.0.1 содержат некорректно сформированные файлы ресурсов с текстами русских сообщений. Драйвера от 9.0.2 и 9.2.x уже нормальные. Эти файлы ресурсов можно довольно легко пропатчить при помощи утилиты native2ascii. Готовый скрипт патча можно найти здесь: http://java.ksu.ru/sources/oracle/ (или здесь - oracle_jdbc_repair.bat). Можно также поменять текущий язык сессии выполнив команду "ALTER SESSION SET NLS_LANGUAGE=English". При этом сообщения станут выдаваться на английском. Ну а самый правильный путь - использовать последние версии драйверов от 9.2.x, благо что они совместимы со старыми версиями Oracle и к тому же содержат исправления других ошибок.

Драйвер JDBC для работы с DBF (com.hxtt.sql.dbf.DBFDriver, бывший zyh.sql.dbf.DBFDriver)

Данный драйвер только недавно научился работать с русскими буквами. Настройка выполняется немного по разному в зависимости от версии драйвера Версии Beta 5.4 (от 02.04.2002) и более поздние уже нормально воспринимают настройку charSet. В версиях Beta 5.2 (от 30.07.2001) и Beta 5.3 (30.11.2001), хоть он и сообщает по getPropertyInfo() что он понимает свойство charSet - это фикция. Реально же настроить кодировку можно установкой свойства CODEPAGEID. Для русских символов там доступны два значения - "66" для Cp866 и "C9" для Cp1251. Пример:

// Параметры соединения с базой

Properties connInfo = new Properties();

// Кодировка Cp866

connInfo.put("charSet", "Cp866");

connInfo.put("CODEPAGEID", "66");

// Устанавливаем соединение

Connection db = DriverManager.getConnection("jdbc:DBF:/C:/MyDBFFiles", connInfo);

Если у Вас DBF-файлы формата FoxPro, то у них своя специфика. Дело в том, что FoxPro сохраняет в заголовке файла ID кодовой страницы (байт со смещением 0x1D), которая использовалась при создании DBF-ки. При открытии таблицы драйвер использует значение из заголовка, а не параметр "CODEPAGEID" (параметр в этом случае используется только при создании новых таблиц). Соответственно, чтобы всё работало нормально, DBF-файл должен быть создан с правильной кодировкой - иначе будут проблемы.

MySQL (org.gjt.mm.mysql.Driver)

С этим драйвером тоже всё довольно просто:

// Параметры соединения с базой

Properties connInfo = new Properties();

connInfo.put("user",user);

connInfo.put("password",pass);

connInfo.put("useUnicode","true");

connInfo.put("characterEncoding","KOI8_R");

Connection conn = DriverManager.getConnection(dbURL, props);

InterBase (interbase.interclient.Driver)

Для этого драйвера работает параметр "charSet":

// Параметры соединения с базой

Properties connInfo = new Properties();

connInfo.put("user", username);

connInfo.put("password", password);

connInfo.put("charSet", "Cp1251");

// Устанавливаем соединение

Connection db = DriverManager.getConnection(dataurl, connInfo);

Однако не забудьте при создании БД и таблиц указать кодировку символов. Для русского языка можно использовать значения "UNICODE_FSS" или "WIN1251". Пример:

CREATE DATABASE 'E:\ProjectHolding\DataBase\HOLDING.GDB' PAGE_SIZE 4096

DEFAULT CHARACTER SET UNICODE_FSS;

CREATE TABLE RUSSIAN_WORD

(

"NAME1" VARCHAR(40) CHARACTER SET UNICODE_FSS NOT NULL,

"NAME2" VARCHAR(40) CHARACTER SET WIN1251 NOT NULL,

PRIMARY KEY ("NAME1")

);

В версии 2.01 InterClient присутствует ошибка - классы ресурсов с сообщениями для русского языка там неправильно скомпилированы. Скорей всего разработчики просто забыли указать кодировку исходников при компиляции. Есть два пути исправления этой ошибки:

Использовать interclient-core.jar вместо interclient.jar. При этом русских ресурсов просто не будет, и автоматом подхватятся английские.

Перекомпилировать файлы в нормальный Unicode. Разбор class-файлов - дело неблагодарное, поэтому лучше воспользоваться JAD-ом. К сожалению JAD, если встречает символы из набора ISO-8859-1, выводит их в 8-иричной кодировке, так что воспользоваться стандартным перекодировщиком native2ascii не удастся - придётся написать свой (программа Decode). Если Вам не хочется заморачиваться с этими проблемами - можете просто взять готовый файл с ресурсами (пропатченый jar с драйвером - interclient.jar, отдельные классы ресурсов - interclient-rus.jar).

JayBird (org.firebirdsql.jdbc.FBDriver)

Для этого драйвера указание кодировки отличается от InterClient:

// Параметры соединения с базой

Properties connInfo = new Properties();

connInfo.put("user", username);

connInfo.put("password", password);

connInfo.put("lc_ctype","WIN1251");

// Устанавливаем соединение

Connection db = DriverManager.getConnection(dataurl, connInfo);

SAP DB (com.sap.dbtech.jdbc.DriverSapDB)

Для этого драйвера можно включить использование Unicode задав параметр unicode в true. В противном случае будет использованна жёстко зашитая ISO-8859-1, с вытекающими отсюда осточертевшими "??????". Кроме того существует доработанная напильником версия (sapdbc.zip), которая позволяет задавать параметр charSet.

DataSource (javax.sql.DataSource)

Если получение соединение производится через использование DataSource, то поддержку настройки используемой кодировки должна содержать конкретная реализация, которая регистрируется в JNDI. Для примера можно взять реализацию от InterClient (interbase.interclient.DataSource). В этом классе есть метод setCharSet(), используя который можно указать необходимую кодировку. Пример:

interbase.interclient.DataSource dataSource = new interbase.interclient.DataSource();

dataSource.setServerName("pongo");

dataSource.setDatabaseName("/databases/employee.gdb");

dataSource.setCharSet("Cp1251");

javax.naming.Context context = new javax.naming.InitialContext();

context.bind("jdbc/EmployeeDB", dataSource);

Другой пример - реализация от DBF-драйвера (com.hxtt.sql.HxttDataSource):

Properties prop=new Properties();

prop.setProperty("urlPrefix","jdbc:DBF:");

prop.setProperty("user","aaaaa");

prop.setProperty("password","vvvvccc");

prop.setProperty("database","dbffiles");//Change it to yourdbfdir

prop.setProperty("charSet","Cp866");

DataSource dataSource=new com.hxtt.sql.HxttDataSource(prop);

context.bind(name, dataSource);

Но даже настроив JDBC-драйвер на нужную кодировку в некоторых случаях можно нарваться на неприятности. Например, при попытке использования новых замечательных скролируемых курсоров стандарта JDBC 2 в мосте JDBC-ODBC из JDK 1.3.x довольно быстро можно обнаружить, что русские буквы там просто не работают (метод updateString()).

С этой ошибкой связанна небольшая история. Когда я впервые её обнаружил (под JDK 1.3 rc2), я зарегистрил её на BugParade (4335564). Когда вышла первая бета JDK 1.3.1, эту ошибку пометили как пофиксеную. Обрадованный, я скачал эту бету, запустил тест - не работает. Написал Sun-овцам об этом - в ответ мне написали, что фикс будет включён в последующие релизы. Ну ладно, подумал я, подождём. Время шло, вышел релиз 1.3.1, а потом и бета 1.4. Наконец я нашёл время проверить - опять не работает. Мать, мать, мать... - привычно откликнулось эхо. После гневного письма в Sun они завели новую ошибку (4486195), которую отдали на растерзание индийскому филиалу. Индусы пошаманили над кодом, и заявили, что в 1.4 beta3 всё исправлено. Скачал я эту версию, запустил под ним тестовый пример, вот результат - 4546083. Как оказалось, та beta3, которую раздают на сайте (build 84) это не та beta3, куда был включён окончательный фикс (build 87). Теперь обещают, что исправление войдёт в 1.4 rc1... Ну, в общем, Вы понимаете:-)

Date: 2015-10-18; view: 320; Нарушение авторских прав; Помощь в написании работы --> СЮДА...



mydocx.ru - 2015-2024 year. (0.006 sec.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав - Пожаловаться на публикацию