На главную страницу
Форум txt.version   




Статья :: PostgreSQL Использование JDBC

Использование JDBC

В этом разделе рассматриваются основные принципы использования JDBC, некоторые технические аспекты, потенциальные проблемы и т. д. За дополнительными сведениями обращайтесь на сайт JDBC (http://java.sun.com/products/jdbc/), на котором всегда приводится самая свежая информация и имеются ссылки на множество полезных ресурсов. Подробные описания конкретных классов, методов и полей приведены в документации API, входящей в комплект поставки JDK. Обращайтесь к пакету java.sql.

Классы JDBC представляют основные компоненты взаимодействия программы с SQL. У всех основных классов JDBC - Connection, Statement, ResultSet, Blob и Clob - имеются прямые аналоги в SQL. Кроме того, в JDBC включены вспомогательные классы - например, классы ResultsSetMetaData и DatabaseMetaData предназначены для работы с метаданными. В частности, они используются для получения информации о возможностях базы данных, для проверки типа результата запроса, в процессе отладки и просто в ситуациях, когда вы не располагаете информацией о данных, с которыми работаете.

Интерфейс JDBC в PostgreSQL также содержит классы для работы с нестандартными расширениями PostgreSQL. К их числу относятся Fastpath, геометрические типы, большие объекты и классы, упрощающие сериализацию объектов Java в базе данных.

Принципы использования JDBC

В листинге 12.2 приведен пример использования объекта Connection, представляющего физическое подключение к базе данных. Объект Connection требуется для создания объектов Statement, при помощи которых в JDBC базе данных передаются команды SQL.

Существует три разновидности объектов Statement: базовый класс Statement, классы PreparedStatement и CallableStatement.

Объект Statement создается методом createStatement (листинг 12.3).

Листинг 12.3. Создание объекта Statement

Statement s = c.createStatement():

В листинге 12.3 создается объект класса Statement с именем s для объекта Connecti on с именем с. Далее созданный объект Statement может использоваться для выполнения запросов и обновлений базы данных.

В классе Statement особенно важны два метода. Первый, executeQuery, получает один аргумент (код выполняемой команды SQL) и возвращает объект класса ResultSet, о котором речь пойдет ниже. Метод executeQuery предназначен для выполнения команд, возвращающих наборы данных, например запросов SELECT. Возвращаемый объект ResultSet представляет данные, полученные в ходе запроса.

Пример выборки данных из базы booktown приведен в листинге 12.4.

Листинг 12.4. Простая выборка в JDBC

Statement s = nul 1: try

{

s = c.createStatementO;

} catch (SQLException se) {

System.out.printlnC'We got an exception while creating a statement:" +

"that probably means we're no longer connected."):

se.printStackTrace();

System, exit(l);

}

ResultSet rs = null:

try {

rs = s.executeQuery("SELECT * FROM books");

} catch (SQLException se)

{

System.out.printlnC'We got an exception while executing our query:" +

"that probably means our SQL is invalid"):

se.pnntStackTrace():

System.exit(l):

}

int index = 0:

try { while (rs.nextO)

{

System.out.printlnC'Here's the result of row " + index++ + ":"):

System.out.pri ntln(rs.getStri ng(1)):

}

} catch (SQLException se) {

System.out.pnntlnC'We got an exception while getting a result:this " +

"shouldn't happen: we've done something really bad.");

se.pnntStackTrace();

System.exit(l):

}

Сначала мы создаем объект Statement, а затем используем метод executeQuery этого объекта для выполнения запроса SELECT * FROM books. Возвращенный запросом объект ResultSet используется для вывода полученной информации.

Объект Resul tSet предоставляет основной интерфейс выборки из базы данных. Он обладает двумя основными возможностями: возможностью последовательного перебора полученных записей и возможностью возвращения значения заданного поля текущей записи. Принцип перебора такой же, как в стандартных перечислениях Java: вы начинаете перебор в позиции перед первым элементом и последовательно переходите к следующему элементу методом next.

Метод next возвращает true в том случае, если объект ResultSet успешно перешел к следующей записи (то есть в итоговом наборе еще остались необработанные записи). Цикл whi I e в листинге 12.4 выводит значение первого поля каждой из возвращаемых записей. Если итоговый набор не содержит ни одной записи, первый же вызов next вернет fal se и программа ничего не выведет.

Класс ResultSet может возвращать значения различных типов; в листинге 12.4 первое поле интерпретируется как строка (Stri ng). К счастью, все стандартные типы данных SQL могут быть представлены в строковом виде, поэтому независимо от типа данных вы всегда сможете получить значение первого поля и вывести его. Класс ResultSet содержит множество других методов, включая методы выборки для всех типов данных SQL и преобразования их к типам Java. За дополнительной информацией обращайтесь к описанию ResultSet в документации API.

Другой важный метод, executeUpdate, тоже вызывается с одним аргументом - выполняемой командой SQL Различие между executeQuery и executeUpdate состоит в том, что метод executeUpdate предназначен для выполнения команд, изменяющих состояние данных в базе. Например, при вызове executeUpdate для команды CREATE, INSERT или UPDATE возвращается число типа int, определяющее количество модифицированных записей.

В листинге 12.5 метод executeUpdate используется для вставки новой записи в таблицу books.

Листинг 12.5. Простая вставка в JDBC

Statement s - null: try {

s = c.createStatement():

} catch (SQLException se) {

System.out.printlnC'We got an exception while creating a statement:" +

"that probably means we're no longer connected."):

se.printStackTrace();

System.exlt(1):

}

int m = 0;

try {

m = s.executeUpdateC1 INSERT INTO books VALUES " +

"(41472. 'Practical PostgreSGl'. 1212. 4)"): >

} catch (SQLException se) {

System.out.println("We got an exception while executing our query:" +

"that probably means our SQL is invalid"): >

se.printStackTrace():

System.exit(l):

}

System.out.println("Successfully modified " + m + " rows.\n"):

Нетривиальные возможности JDBC

Как упоминалось выше , кроме базового объекта Statement в JDBC существует два других типа объектов для представления команд: PreparedStatement и Cal lableStatement. Они будут описаны ниже.

В данном подразделе также будет рассказано об объектах ResultsSetMetaData и DatabaseMetaData. С их помощью можно запросить у JDBC описание результатов запроса или базы данных. Возможность получения такой информации на стадии выполнения программы позволяет динамически выполнять команды SQL - даже такие, параметры которых были неизвестны на момент написания программы.

Объект CallableStatement

Объект CallableStatement позволяет выполнять хранимые процедуры в JDBC-co-вместимых базах данных. Лучшим источником информации по этому вопросу является сайт Sun Javasoft (http://java.sun.com/products/jdbc/), поскольку стандарт вызываемых команд (callable statements) изменяется и развивается и его практические применения зависят от версии Java и JDBC.

Объект PreparedStatement

Объект PreparedStatement представляет подготовленные (prepared) команды SQL, многократно выполняемые с разными исходными данными - например, если вам потребовалось вставить в таблицу несколько записей, одну за другой. Главное преимущество PreparedStatement заключается в том, что команда проходит предварительную компиляцию, что избавляет от затрат на повторную обработку команд SQL при каждом выполнении. Пример использования объекта PreparedStatement приведен в листинге 12.6.

Листинг 12.6. Использование подготовленных команд в JDBC

PreparedStatement ps = null:

try {

ps = c.prepareStatementC'INSERT INTO authors VALUES (?. ?. ?)");

ps.setlntd. 495):

ps.setString(2. "Light-Williams"):

ps.setStringO. "Corwin"): } catch (SQLException se) {

System.out.printlnC"We got an exception while preparing a statement:" +

"Probably bad SQL."):

se.printStackTrace();

System.exit(l);

}

try {

ps.executeUpdate():

} catch (SQLException se) {

System.out.printlnC'We got an exception while executing an update:" +

"possibly bad SQL. or check the connection."):

se.pnntStackTrace():

System.exit(l):

}

Как видно из листинга, подготовленная команда выглядит вполне привычно, разве что все переменные величины заменяются в ней вопросительными знаками (?). Присваивание выполняется методами класса PreparedStatement (setlnt, setString и т. д.). Выбор метода для каждого поля зависит от типа данных этого поля.

Объекты PreparedStatement удобны тем, что они обеспечивают автоматическое преобразование типов данных Java в типы SQL. Например, при переходе к типу text вам не нужно беспокоиться об экранировании символов или кавычках.

Обратите внимание: первый аргумент метода set идентифицирует номер позиции переменной (вопросительного знака), которой присваивается значение. Единица означает первый вопросительный знак, двойка - второй и т. д.

Другая сильная сторона PreparedStatement связана с тем, что объект можно снова и снова использовать с новыми данными, не создавая нового объекта Statement для каждого набора параметров. Конечно, такой подход более эффективен, поскольку он ограничивается созданием одного объекта, а новые значения переменных задаются методами set.

ResultSetMetaData

У JDBC можно запросить подробную информацию об итоговом наборе запроса. Класс Resul tsSetMetaData возвращает описание объекта Resul tSet, полученного при вызове executeQuery. В нем содержится информация о количестве полей, типе данных, именах полей и т. д.

Из всех методов класса ResultSetMetaData чаще всего используются методы getCol umnName и getCol umnTypeName. Они возвращают соответственно имя поля и имя его типа данных в виде значения типа String.

ПРИМЕЧАНИЕ

Не путайте метод getCol umnType с методом getCol umnTypeName. Метод getCol umnType возвращает значение типа int, соответствующее внутреннему идентификатору типа данных в JDBC, тогда как getCol umnTypeName возвращает имя типа в формате String.

Использование JDBC 363

В листинге 12.7 класс ResultSetMetaData используется для получения имени и типа данных первого поля объекта ResultSet с именем rs. Программа является логическим продолжением листинга 12.4, в котором был создан объект rs.

Даже если отвлечься от соображений эффективности, механизм PreparedStatement гораздо надежнее подготовки нескольких команд в объектах Statement.

Листинг 12.7. Использование объекта ResultSetMetaData

ResultSetMetaData rsmd - null:

try {

rsmd = rs.getMetaData():

} catch (SQLException se) {

System.out.printlnC'We got an exception while getting the metadata:" +

"check the connection."):

se.printStackTrace();

System.exit(l):

}

String columnName = null.

columnType = null:

try {

columnName = rsmd.getColumnName(1):

columnType - rsmd.getColumnTypeName(l):

} catch (SQLException se) {

System.out.printlnC'We got an exception while getting the column name:" +

"check the connection."):

se.printStackTrace():

System.exit(l):

}

System.out.printC'The name of the first column is: '"):

System.out.print(columnName);

System.out.printlrK.....):

System.out.printC'The data type of the first column is: "):

System.out.println(columnType):

Класс ResultSetMetaData содержит много других полезных методов. Описания приведены в документации JDK API.

DatabaseMetaData

Наконец, класс DatabaseMetaData предназначен для получения информации о базе данных, с которой вы работаете. В частности, он позволяет получить ответ па перечисленные ниже вопросы.

  • Какие каталоги присутствуют в базе данных?
  • С каким типом базы я работаю?
  • Под каким именем пользователя я работаю с базой данных?

В листинге 12.8 объект DatabaseMetaData используется для получения у драйвера JDBC имени пользователя, с которым было создано подключение, и URL-адреса базы данных.

Листинг 12.8. Использование объекта DatabaseMetaData

DatabaseMetaData dbmd = null:

try {

dbmd = c.getMetaData():

} catch (SQLException se) {

System.out.printlnC'We got an exception while getting the metadata:" +

" check the connection."):

se.printStackTrace():

System.exit(l): }

String username = null:

try {

username = dbmd.getUserName():

} catch (SQLException se) {

System.out.printlnC'We got an exception while getting the username:" +

"check the connection."); se.printStackTraceO;

System.exit(l):

}

String url = null;

try {

url = dbmd.getURLO;

} catch (SQLException se) {

System.out.printlnC'We got an exception while getting the URL:" +

"check the connection.");

se.printStackTrace();

System.exit(l):

}

System.out.printlnC'You are connected to '" + url +

'" with user name '" + username + .....);

Как было сказано выше, лучшим источником информации о других методах DatabaseMetaData является документация JDK API.



PostgreSQL Использование JDBC

страницы в данном разделе 
 PostgreSQL Глава 12. JDBC  PostgreSQL JDBC
 PostgreSQL Построение драйвера JDBC  PostgreSQL Использование драйвера
 PostgreSQL Использование JDBC  PostgreSQL Специфика использования JDBC


Разделы
Околокомпьютерная литература (375)
Программирование (102)
Программы (75)
ОС и Сети (49)
Интернет (29)
Аппаратное обеспечение (16)
Базы данных (6)

Содержание сайта (выборка)
Apache
Протоколы TCP/IP (принципы, протоколы и архитектура)

PHP, PELR, JSP
PHP
JavaServer Pages (JSP)

Базы данных
Основы mysql
СУБД INFORMIX
СУБД POSTGRES
Основы проектирования реляционных баз данных

HTML, javascript
Спецификация HTML 4.01
Каскадные Таблицы Стилей, Уровень 2
Клиентский JavaScript. Справочник.
JavaScript руководство пользователя
Серверный JavaScript 1.4. Руководство по Использованию.

Паскаль, C, C++, C#
GCC (примеры)
FAQ Валентинa Озеровa DELPHI
C





 
©  programming-lang.com  справочник программиста