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, что повлечет за собой фиксацию изменений.