HEAD>
Содержание | Предыдущий | следующий | Руководство по JDBCTM для начинающих |
Connection
представляет собой соединение с
БД. Сессия соединения включает в себя выполняемые SQL-запросы и возвращаемые
через соединение результаты. Приложение может открыть одно или более соединений
с одной или несколькими БД.
DriverManager.getConnection
. Этому методу передается
строка, содержащая т.н. "URL". Класс DriverManager
, представляющий
собой уровень управления в JDBC, пытается найти драйвер, который может
соединиться к БД с помощью данного URL. Класс DriverManager
содержит список зарегистрированных классов Driver
, и при вызове
метода getConnection
он проверяет каждый драйвер и ищет среди них
тот, который "умеет" соединятся с БД, указанной в URL. Метод
connect
драйвера использует этот URL для установления соединения.
Пользователь может пропустить этот управляющий уровень JDBC и вызывать
непосредственно методы класса Driver
для открытия соединения. Это
может быть нужным в тех редких случаях, когда два или более драйвера могут
обслужить заданный URL, но пользователь хочет выбрать конкретный из них. Тем не
менее, намного проще возложить эту работу на класс DriverManager
.
Следующий код демонстрирует открытие соединенияс БД, находящейся по URL
"jdbc:odbc:wombat"
, с именем пользователя "oboy"
и
паролем "12Java"
:
String url = "jdbc:odbc:wombat"; Connection con = DriverManager.getConnection(url, "oboy", "12Java");
URL (Uniform Resource Locator) представляет собой информацию для адресации ресурса в Интернет. Другими словами, это адрес ресурса.
Первая часть URL задает протокол, используемый для доступа к информации, и всегда заканчивается знаком ":". Среди протоколов наиболее популярны "ftp" ("file transfer protocol" - протокол передачи файлов), и "http" ("hypertext transfer protocol" - протокол передачи гипертекста). Протокол "file" означает, что ресурс находится в локальной файловой системе, а не в Интернет. Примеры URL:
ftp://javasoft.com/docs/JDK-1_apidocs.zip http://java.sun.com/products/JDK/CurrentRelease file:/home/haroldw/docs/tutorial.htmlОстальная часть URL, - то, что после первого двоеточия, - это то место, где находится источник данных. В случае протокола "
file
"
оставшаяся часть URL - это путь к файлу. Для протоколов ftp
и
http
оставшаяся часть URL идентифицирует хост (имя сервера) и
необязательный путь к конкретном сайту или файлу. Например, ниже приведен URL
домашней страницы фирмы JavaSoft. Этот URL указывает только имя хоста:
http://www.javasoft.com
Так как JDBC-URL используются с различными драйверами, то они должны
неизбежно быть очень гибкими. Во-первых, они допускают использование различными
драйверами различных схем именования баз данных. Например, подпротокол
odbc
позволяет использовать значения атрибутов в URL.
Во-вторых, JDBC-URL дают возможность разработчикам jdbc-драйверов кодировать всю нужную для соединения информацию в URL.
В-третьих, с помощью JDBC-URL принципиально возможно осуществить "перенаправление": JDBC-URL может ссылаться на логический хост или имя БД, которое динамически транслируется в настоящее имя с помощью сетевой службы имен. Таким образом можно избежать непосредственного назначения хоста в JDBC URL. Существует несколько сетевых сервисов имен (DNS, NIS, and DCE).
Стандартный синтаксис JDBC URL показан ниже. Он имеет три части, разделенных двоеточием:
jdbc:<subprotocol>:<subname>JDBC URL состоит из:
jdbc
- протокола. Протокол, используемый в JDBC URL - всегда
jdbc
.
<subprotocol> (подпротокола)
- это имя драйвера или имя
механизма соединения с БД. Подпротокол может поддерживаться одним или
несколькими драйверами. Лежащий на поверхности пример подпротокола - это
"odbc", отведенный для URL, обозначающих имя источника данных ODBC. Например,
для доступа к БД через мост JDBC-ODBC нужно использовать URL такого вида: jdbc:odbc:fredВ этом примере подпротокол задан как "odbc", а подимя "fred" является локальным источником данных.
Если кому-то захочется использовать сервис имен (т.е. имя БД в JDBC-URL не будет действительным именем БД), то подпротоколом может быть сервис имен:
jdbc:dcenaming:accounts-payableВ этом примере URL указывает локальный сервис имен DCE, который должен разрешить имя БД "accounts-payable" в более определенное имя, которое далее будет использоваться для подключения к БД.
<subname> (подимени)
- это идентификатор БД. Значение
подимени может менятся в зависимости от подпротокола, и может также иметь
подподимя с синтаксисом, определяемым разработчиком драйвера. Назначение
подимени - это предоставление всей информации, необходимой для поиска БД. В
предыдущем примере достаточно строки "fred", так как оставшуюся часть
информации предоставляет ODBC. Однако удаленная БД требует дополнительную
информацию. Например, если БД находится в Интернет, то в состав подимени
JDBC-URL должен быть включен сетевой адрес, подчиняющийся следующим
соглашениям: //hostname:port/subsubnameПредполагая, что "dbnet" - это протокол соединения к хосту в Интернет, JDBC-URL может выглядеть так:
jdbc:dbnet://wombat:356/fred
odbc
зарезервирован для URL, которые определяют имена источников данных (DSN) ODBC и
имеют специальную возможность задавать некоторое количество значений атрибутов
после подимени (имени источника данных, DSN). Полный синтаксис подпротокола ODBC
- следующий:
jdbc:odbc:<data-source-name
>[;<attribute-name>
=<attribute-value
>]*
Примеры корректных JDBC-URL для подпротокола odbc приведены ниже:
jdbc:odbc:qeor7 jdbc:odbc:wombat jdbc:odbc:wombat;CacheSize=20;ExtensionCase=LOWER jdbc:odbc:qeora;UID=kgh;PWD=fooey
DriverManager
"показывает" это имя своему списку зарегистрированных
драйверов, и тот драйвер, который отвечает за этот подпротокол, должен
"откликнуться" и установит соединение с БД. Например, odbc
зарезервирован за рассмотренным выше мостом JDBC-ODBC. Кто-нибудь другой,
например, Miracle Corporation, может зарегистрировать в качестве подпротокола
"miracle" для jdbc-драйвера, который соединяется с СУБД Miracle. При этом никто
другой уже не сможет использовать это имя.
Организация JavaSoft служит в качестве информационного реестра имен JDBC-подпротоколов. Чтобы зарегистрировать подпротокол, надо послать письмо по адресу:
jdbc@wombat.eng.sun.com
В JDBC есть три класса для посылки SQL-запросов в БД и три метода в
интерфейсе Connection
создают экземпляры этих классов. Эти классы и
методы, которые их создают, перечислены ниже:
Statement
- создается методом createStatement
.
Объект Statement
используется при простых SQL-запросах.
PreparedStatement
- создается методом
prepareStatement
. Объект PreparedStatement
используется в SQL-запросах с одним или более входными параметрами (IN
parameters). PreparedStatement
содержит группу методов,
устанавливающих значения входных параметров, которые отсылаются в БД при
выполнении запроса. Экземпляры класса PreparedStatement
расширяют
(наследуются от) Statement
и, таким образом, включают методы
Statement
. Объект PreparedStatement
потенциально
может быть более эффективным, чем Statement
, так как он
прекомпилируется и сохраняется для будущего использования.
CallableStatement
- создается методом
prepareCall
. Объекты CallableStatement
используются
для выполнения т.н. хранимых процедур - именованных групп SQL-запросов,
наподобие вызова подпрограммы. Объект CallableStatement
наследует
методы обработки входных (IN) параметров из PreparedStatement
, а
также добавляет методы для обработки выходных (OUT) и входных-выходных (INOUT)
параметров. Connection
лучше использовать для
создания различных SQL-запросов:
Метод createStatement
используется для
Метод prepareStatement
используется для
Метод prepareCall
используется для
commit
или
rollback
текущая транзацкия заканчивается и начинается другая.
Каждое новое соединение по умолчанию находится в режиме автофиксации
(auto-commit), что означает автоматическую фиксацию (commit) транзакции после
каждого запроса. В этом случае транзакция состоит из одного запроса. Если
auto-commit запрещен, транзакция не заканчивается вплоть до явного вызова
commit
или rollback
, включая, таким образом, все
выражения, выполненные с момента последнего вызова commit
или
rollback
. В этом случае все SQL-запросы в транзакции фиксируются
или откатываются группой.
Метод фиксации commit
делает окончательными все изменения в БД,
проделанные SQL-выражением, и снимает также все блокировки, установленные
транзакцией. Метод rollback
проигнорирует, "отбракует" эти
изменения.
Иногда пользователю нужно, чтобы какое-либо изменение не вступило в силу до
тех пор, пока не вступит в силу предыдущее изменение. Этого можно достичь
запрещением auto-commit и группировкой обоих запросов в одну транзакцию. Если
оба изменения произошли успешно, то вызывается метод commit
,
который переносит эффект от этих изменений в БД; если одно или оба запроса не
прошли, то вызывается метод rollback
, который возвращает прежнее
состояние БД.
Большинство JDBC-драйверов поддерживают транзакции. На самом деле драйвер,
соответствующий спецификации JDBC, обязан поддерживать их. Интерфейс
DatabaseMetaData
предоставляет информацию об уровнях
изолированности транзакций, которые поддерживаются данной СУБД.
con.setTransactionIsolation(TRANSACTION_READ_UNCOMMITTED);Чем выше уровень изолированности транзакций, тем больше внимания СУБД уделяет устранению конфликтов. Интерфейс
Connection
определяет пять
таких уровней. Минимальный из них соответствует случаю, когда транзакции не
поддерживаются вовсе, а максимальный - невозможности существования более одной
транзакции в любой момент времени. Обычно, чем выше уровень изолированности, тем
медленнее выполняется приложение (из-за избыточной блокировки и уменьшенной
конкурентности пользователей). При выборе конкретного уровня изолированности
разработчик должен найти золотую середину между потребностями в
производительности и требованиями к целостности данных. Очевидно, что реально
поддерживаемые уровни зависят от возможностей используемой СУБД.
При создании объекта Connection
его уровень изолированности
зависит от драйвера или БД. Пользователь может вызвать метод
setIsolationLevel
, чтобы изменить уровень изолированности
транзакций, и новое значение уровня будет установлено до конца сессии. Чтобы
установить уровень изолированности только для одной транзакции, надо установить
его перед выполнением транзакции и восстановить прежнее значение после ее
завершения. Изменение уровня изолированности во время самой транзакции
нежелательно, так как произойдет автоматический вызов commit
, что
повлечет за собой фиксацию изменений.