Datasource oracle что это

Обновлено: 03.07.2024

При разработке WEB-приложения альтернативой применения JDBC-подключения к серверу БД можно выбрать класс DataSource, использующего JNDI (Java Naming and Directory Interface). В статье рассматривается вопрос настройки DataSource в сервере приложений JBoss для подключения к серверу БД Oracle. Более подробную информацию о службе имен и каталогов JNDI можно найти на нашем сайте здесь.

Использование JNDI для получения DataSource в java-приложении

Использование JNDI в программе, как правило, ограничивается всего несколькими строками. Типичным таким примером является подключение к серверу БД с использованием DataSource. Следующий код позволяет подключиться к источнику данных, привязанному к имени "java:jboss/datasources/slon". Этот источник данных определен в JBoss, и ниже будет показано, как его настроить.

Работа с JNDI всегда начинается с создания объекта InitialContext (или InitialDirContext в случае работы со службой каталогов). Конструктор этого объекта может принимать параметры, определяющие, к какой службе и каким образом подключаться. В данном случае параметры в конструктор не передаются, поэтому происходит подключение к службе имен сервера JBoss. Затем вызовом метода lookup() из службы имен извлекается объект DataSource, соответствующий имени "java:jboss/datasources/slon".

Класс DataSource предоставляет соединение с сервером БД в виде класса, реализующего интерфейс java.sql.Connection. То есть, DataSource управляет соединением с базой данных.

Какие преимущества даёт использование DataSource? Основное, что мы видим, так это отсутствие параметров учетной записи (login/password) и сервера БД (host, port). То есть, разработчики могут отлаживаться на тестовом сервере, а на рабочем сервере Заказчика WEB-приложение разместит уже знающий администратор/специалист.

Настройка DataSource в JBoss

Для настройки DataSource в JBOSS необходимо проделать 3 шага :

  1. Разместить JDBC-библиотеку подключения к серверу БД;
  2. Настроить файл конфигурации модуля подключения к серверу БД;
  3. Настроить DataSource в файл конфигурации standalone.xml.

На первом шаге была создана директория $/modules/com/oracle/ojdbc6/main, в котором разместился файл ojdbc6.jar.


В этой же директории $/modules/com/oracle/ojdbc6/main был создан файл module.xml со следующим контентом.

На следующем шаге в раздел <datasources> файла $/standalone/configuration/standalone.xml были внесен следующий код, в котором определялись параметры DataSource :

Параметры настройки DataSource :

  • connection-url — строка подключения к серверу БД;
  • driver-class — класс JDBC драйвера;
  • driver — наименование драйвера;
  • pool — настройки пула соединений
  • min-pool-size — минимальный размер пула
  • max-pool-size — максимальный размер пула
  • security — настройки аутентификации
  • user-name — имя пользователя БД
  • password — пароль

После старта JBoss (сервер Oracle также запущен) в консоли должна появиться следующая информация :


Следуйте за нами на нашей фан-странице, чтобы получать уведомления каждый раз, когда появляются новые статьи. Facebook

1- Database использующийся в данной статье

В этом документе вы узнаете, как использовать Java для соединения с базой данных.
Модель базы данных, используемая в этом документе - "simplehr". Вы можете просмотретьсценарии создания базы данных по ссылке:

2- Что такое JDBC?

Java Database Connectivity (JDBC) - это стандартный API для взаимодействия с реляционными базами данных. JDBC имеет набор классов и интерфейсов, которые могут использоваться для Java-приложения и разговаривать с базой данных,.


Основные компоненты JDBC Api включают:
  1. DriverManager:
    • Это класс, использующийся для управления списком Driver (database drivers).
  2. Driver:
    • Это интерфейс, использующийся для соединения коммуникации с базой данных, управления коммуникации с базой данных. Когда загружается Driver, программисту не нужно конкретно вызывать его.
  3. Connection:
    • Интерфейс со всеми методами связи с базой данных. Он описывает коммуникационный контекст. Вся связь с базой данных осуществляется только через объект соединения (connection).
  4. Statement:
    • Это интерфейс, включающий команду SQL отправленный в базу данных для анализа, обобщения, планирования и выполнения.
    ResultSet :
    • ResultSet представляет набор записей, извлеченных из-за выполнения запроса.


3- На каком принципе подключается Java к базе данных?

Java с использует JDBC для работы с базой данных.


  • Например, с Oracle, класс реализующий интерфейс java.sql.Driver является oracle.jdbc.driver.OracleDriver


  • Способ 1: вы предоставляете Driver управляющий этим видом базы данных, это прямой способ. Если вы используете DB oracle (или другой DB), вам нужно будет загрузить конкретную библиотеку JDBC этой BD.
  • Способ 2: объявите "ODBC Datasource" и используйте мост JDBC-ODBC для соединения с этим "ODBC Datasource". Мост JDBC-ODBC доступен в JDBC API.


Вопрос для нас в том, что такое "ODBC DataSource"?

ODBC - Open Database Connectivity: Это набор открытых библиотек, которые могут подключаться практически ко всем видам различных баз данных, и это бесплатно. Предоставляется Microsoft.

ODBC DataSource: в операционной системе Windows вы можете объявить соединение ODBC с определенным видом BD. В результате у нас есть источник данных (Data Source).

В JDBC API, JDBC-ODBC Bridge (мост) был настроен так, что JDBC может работать с ODBC Data Source.

В современном мире без хранения данных никак. И история работы с базами данных началась уже очень давно, с появления JDBC. Предлагаю вспомнить то, без чего не обходися ни один современный фрэймворк, построенный поверх JDBC. Кроме того, даже работая с ними временами может понадобится возможность "вернуться к корням". Надеюсь, обзор поможет как вступительное слово или поможет что-то освежить в памяти.

Вступление

Одна из основных целей языка программирования - хранение и обработка информации. Чтобы лучше понять работу хранения данных стоит немного времени выделить на теорию и архитектуру приложений. Например, можно ознакомиться с литературой, а именно с книгой "Software Architect's Handbook: Become a successful software architect by implementing effective arch. " авторства Joseph Ingeno. Как сказано, есть некий Data Tier или "Слой данных". Он включает в себя место хранения данных (например, SQL базу данных) и средства для работы с хранилищем данных (например, JDBC, о котором и пойдёт речь). Так же на сайте Microsoft есть статья: "Проектирование уровня сохраняемости инфраструктуры" в которой описывается архитектурное решение выделения из Data Tier дополнительного слоя — Persistence Layer. В таком случае Data Tier — это уровень хранения самих данных, в то время как Persistence Layer - это некоторый уровень абстракции для работы с данными из хранилища с уровня Data Tier. К уровню Persistence Layer можно отнести шаблон "DAO" или различные ORM. Но ORM — это тема отдельного разговора. Как Вы могли уже понять, вначале появился Data Tier. Ещё с времён JDK 1.1 в Java мире появился JDBC (Java DataBase Connectivity — соединение с базами данных на Java). Это стандарт взаимодействия Java-приложений с различными СУБД, реализованный в виде пакетов java.sql и javax.sql, входящих в состав Java SE:

JDBC или с чего всё начинается - 2

Данный стандарт описан специфкицией "JSR 221 JDBC 4.1 API". Данная спецификация рассказывает нам о том, что JDBC API предоставляет программный доступ к реляционным базам данных из программ, написанных на Java. Так же рассказывает о том, что JDBC API является частью платформы Java и входит поэтому в Java SE и Java EE. JDBC API представлен двумя пакетами: java.sql and javax.sql. Давайте тогда с ними и познакомимся.

JDBC или с чего всё начинается - 3

Начало работы

Чтобы понять что такое вообще JDBC API нам понадобится Java приложение. Удобнее всего воспользоваться одной из систем сборки проектов. Например, воспользуемся Gradle. Более подробно про Gradle можно прочитать в небольшом обзоре: "Краткое знакомство с Gradle". Для начала инициализируем новый Gradle проект. Так как функциональность Gradle реализуется через плагины, то для инициализации нам нужно воспользоваться "Gradle Build Init Plugin": Откроем после этого билд скрипт — файл build.gradle, где описывается наш проект и то, как с ним нужно работать. Нас интересует блок "dependencies", где описываются зависимости — то есть те библиотеки/фрэймворки/api, без которых мы не можем работать и от которых мы зависим. По умолчанию мы увидим что-то вроде: Почему мы тут это видим? Это зависимости нашего проекта, которые нам сгенерировал автоматически Gradle при создании проекта. А так же потому что guava - это отдельная библиотека, не входящая в комплект с Java SE. JUnit так же не входит в комплект с Java SE. Но JDBC у нас есть "из коробки", то есть входит в состав Java SE. Получается JDBC у нас есть. Отлично. Что же нам ещё надо? Есть такая замечательная схема:

Как мы видим, и это логично, база данных является внешним компонентом, которого нет изначально в Java SE. Это объясняется просто - существует огромное количество баз данных и работать вы можете захотеть с любой. Например, есть PostgreSQL, Oracle, MySQL, H2. Каждая из этих баз данных поставляется отдельной компанией, которые называются поставщиками баз данных или database vendors. Каждая база данных написана на каком-то своём языке программирования (не обязательно Java). Чтобы с базой данных можно было работать из Java приложения поставщик базы данных пишет особый драйвер, который является своего образа адаптером. Такие JDBC совместимые (то есть у которых есть JDBC драйвер) ещё называют "JDBC-Compliant Database". Тут можно провести аналогию с компьютерными устройствами. Например, в блокноте есть кнопка "Печать". Каждый раз когда вы её нажимаете программа сообщает операционной системе, что приложение блокнот хочет напечатать. И у Вас есть принтер. Чтобы научить разговаривать единообразно вашу операционную систему с принтером Canon или HP понадобятся разные драйверы. Но для Вас, как пользователя, ничего не изменится. Вы по прежнему будете нажимать одну и ту же кнопку. Так и с JDBC. Вы выполняете один и тот же код, просто "под капотом" могут работать разные базы данных. Думаю, тут очень понятный подход. Каждый такой JDBC драйвер — это некоторый артефакт, библиотека, jar файл. Он то и является зависимостью для нашего проекта. Например, мы можем выбрать базу данных "H2 Database" и тогда нам надо добавить зависимость следующим образом: То, как найти зависимость и как её описать указано на официальных сайтах поставщика БД или на "Maven Central". JDBC драйвер не является базой данных, как Вы поняли. А лишь является проводником к ней. Но есть такое понятие, как "In memory databases". Это такие базы данных, которые существуют в памяти на время жизни вашего приложения. Обычно, это часто используют для тестирования или для учебных целей. Это позволяет не ставить отдельный сервер баз данных на машине. Что нам очень даже подойдёт для знакомств с JDBC. Вот и готова наша песочница и мы приступаем.

JDBC или с чего всё начинается - 5

Connection

  • Через DriverManager
  • Через DataSource

Statements

  • Statement: SQL выражение, которое не содержит параметров
  • PreparedStatement : Подготовленное SQL выражение, содержащее входные параметры
  • CallableStatement : SQL выражение с возможностью получить возвращаемое значение из хранимых процедур (SQL Stored Procedures).

ResultSet

Понятие ResultSet описано в спецификации JDBC API в главе "CHAPTER 15 Result Sets". Прежде всего, там сказано, что ResultSet предоставляет методы для получения и манипуляции результатами выполненных запросов. То есть если метод execute вернул нам true, значит мы можем получить и ResultSet. Давайте вынесем вызов метода createCustomerTable() в метод init, который отмечен как @Before. Теперь доработаем наш тест shouldSelectData: Тут стоит отметить, что next — это метод, который двигает так называемый "курсор". Курсор в ResultSet указывает на некоторую строку. Таким образом, чтобы считать строку, на неё нужно этот самый курсор установить. Когда курсор перемещается, то метод перемещения курсора возвращает true, если курсор валидный (правильный, корректный), то есть указывает на данные. Если возвращает false, значит данных нет, то есть курсор не указывает на данные. Если попытаться получить данные с невалидным курсором, то мы получим ошибку: No data is available Ещё интересно, что через ResultSet можно обновлять или даже вставлять строки:

RowSet

JDBC помимо ResultSet вводит такое понятие, как RowSet. Подробнее можно прочитать здесь: "JDBC Basics: Using RowSet Objects". Существуют различные вариации использования. Например, самый простой случай может выглядеть так: Как видно, RowSet похож на симбиоз statement (мы указали через него command) и выполнили command. Через него же мы управляем курсором (вызывая метод next) и из него же получаем данные. Интересен не только такой подход, но и возможные реализации. Например, CachedRowSet. Он является "отключённым" (то есть не использует постоянное подключение к БД) и требует явного выполнения синхронизации с БД: Подробнее можно прочитать в tutorial на сайте Oracle: "Using CachedRowSetObjects".

JDBC или с чего всё начинается - 8

Metadata

Кроме запросов, подключение к БД (т.е. экземпляр класса Connection) предоставляет доступ к метаданным - данным о том, как настроена и как устроена наша база данных. Но для начала озвучим несколько ключевых моментов: URL подключения к нашей БД: "jdbc:h2:mem:test". test - это название нашей базы данных. Для JDBC API это каталог. И название будет в верхнем регистре, то есть TEST. Схема по умолчанию (Default schema) для H2 - PUBLIC. Теперь, напишем тест, который показывает все пользовательские таблицы. Почему пользовательские? Потому что в базах данных есть не только пользовательские (те, которые мы сами создали при помощи create table выражений), но и системные таблицы. Они необходимы, чтобы хранить системную информацию о структуре БД. У каждой БД такие системные таблицы могут храниться по-разному. Например, в H2 они хранятся в схеме "INFORMATION_SCHEMA". Интересно, что INFORMATION SCHEMA является общим подходом, но Oracle пошли иным путём. Подробнее можно прочитать здесь: "INFORMATION_SCHEMA и Oracle". Напишем тест, получающий метаданные по пользовательским таблицам:

JDBC или с чего всё начинается - 9

Пул подключений

Пулу подключений в спецификации JDBC отведен раздел "Chapter 11 Connection Pooling". В нём же и даётся главное обоснование необходимости пула подключений. Каждый Coonection - это физическое подключение к БД. Его создание и закрытие - довольно "дорогая" работа. JDBC предоставляет лишь API для пула соединений. Поэтому, выбор реализации остаётся за нами. Например, к таким реализациям относится HikariCP. Соответственно, нам понадобится добавить пул к нам в зависимости проекта: Теперь надо как-то пул этот задействовать. Для этого нужно выполнить инициализацию источника данных, он же Datasource: И напишем тест на получение подключения из пула:

Изучение интерфейсов DataSource и ConnectionPoolDataSource.

Оба интерфейса входят в пакет javax.sql и должны быть реализованы поставщиками JDBC классов (драйверов). Основное назначение интерфейсов DataSource и ConnectionPoolDataSource состои в предоставлении возможности получения соединения с базой данных абстрагируясь от местоположения сервера СУБД и типа драйвера конкретного производителя. Интерфейсы определяют ряд обязательных для реализации методов, в том числе и метод getConnection(). Объекты, получаемые от реализации данных интерфейсов используются для задания параметров соединения с базой данных и установки соединения в виде объекта типа Connection.

JDBC DataSource объекты используются для получения физического соединения с базой данных и являются альтернативой DriverManager. При этом нет необходимости регистрировать драйвер. Необходимо только установить соответствующие параметры для установки соединения и выполнить метод getConnection(). При создании объекта типа DataSource локально (прямо в приложении) параметры соединения задаются соответствующими методами, предусмотренными поставщиком драйвера. Эти методы не определены интерфейсом DataSource, т.к. параметры для соединения с СУБД разных производителей могут отличаться как по типу, так и по количеству (например, не для всех СУБД необходимо указывать тип драйвера или сетевой протокол). Так при работе с СУБД Oracle для использования соответствующих set и get методов необходимо получить объект типа OracleDataSource, который является экземпляром одноименного класса, реализующего интерфейс DataSource. В следствии этого такой способ создания объектов типа DataSource делает программный код менее мобильным и зависимым от конкретной реализации драйвера. Ниже приведен пример программного кода, иллюстрирующий локальное использование объектов типа DataSource.

Полностью возможности объектов типа DataSource проявляются в сочетании с использованием интерфейса JNDI. Использование службы имен и каталогов позволяет хранить заранее созданные системным администратором объекты типа DataSource с предустановленными параметрами соединения. Ниже приведены некоторые стандартные имена свойств (параметров), разработанные компанией Sun:

Комбинирование интерфейсов DataSource и JNDI играет ключевую роль в разработке многоуровневых корпоративных приложений, основанных на компонентной технологии J2EE. В случае использования комбинации интерфейсов DataSource и JNDI в программном коде приложения необходимо только затребовать объект типа DataSource у службы имен и каталогов. При этом детали соединения и зависимый от конкретной реализации драйвера программный код оказывается скрытым от приложения в хранящемся в службе имен и каталогов объекте.

Таким образом, совместное использование объектов типа DataSource и JNDI предполагает наличие двух выполняемых независимо друг от друга шагов:

1. Необходимо сохранить именованный объект типа DataSource в службе имен и каталогов, используя метод Context.bind() пакета javax.naming.

2. Затребовать в приложении объект типа DataSource у службы имен и каталогов, использую метод Context.lookup(). После чего можно использовать его метод DataSource.getConnection() для получения соединения с базой данных.

Ниже приведен пример совместного использования интерфейса JNDI и объекта типа OracleDataSource. В качестве службы имен и каталогов используется файловая система и необходимый для этого SPI (fscontext.jar и providerutil.jar).

Приложение начинается с инициализации объекта типа InitialContext, который открывает соединение со службой имен и каталогов, задает начальный контекст (начальный каталог дерева хранения объектов) и используется для загрузки объекта типа DataSource. Далее используется метод bindDataSource() для сохранения объекта типа DataSource в службе имен и каталогов.

Для демонстрации работы с сохраненным объектом создается переменная ds типа DataSource. Полиморфизм позволяет назначать ей экземпляры любых классов, реализующих интерфейс DataSource, в нашем случае это объект типа OracleDataSource. Метод lookup() запрашивает сохраненный объект типа OracleDataSource и возвращает результат типа Object, по этому его надо преобразовать в тип DataSource. Получив требуемый объект типа DataSource можно использовать его метод getConnection() для получения соединения с базой данных.

Объекты типа ConnectionPoolDataSource используются для получения объектов типа PooledConnection, которые представляют физическое соединение с базой данных и являются поставщиками объектов типа Connection. Сам по себе интерфейс PooledConnection не предусматривает методов для создания объектов типа Statement, по этому необходимо использовать объекты типа Connection.

Объекты типа Connection, получаемые с помощью объектов типа PooledConnection представляют логическое соединение с базой данных. Они выполняют те же функции, что и объекты типа Connection, получаемые с использованием интерфейса DriverManager. Они используюся для создания объектов типа Statement, PrepareStatement или CollableStatement, и управляют уровнем транзакций. Однако, метод close() таких объектов не закрывает соединение с базой данных, а возвращает объект логического соединения обратно в пул для повторного использования его другими клиентами.

Ниже приведен пример использования локального объекта типа ConnectionPoolDataSource, требующего установки параметров соединения в программном коде приложения.

В примере создается объект pc_1 типа PooledConnection для поставки объектов типа Connection. Далее создаются два логических соединения conn_1 и conn_2. После их создания выводится количество физических соединения. Физическое соединение одно, не смотря на наличие двух открытых логических соединений. При создании второго объекта pc_2 типа PooledConnection физических соединений становится два.

Изучение использования объекта типа ConnectionPool DataSource с предустановленными параметрами в комбинации с интерфейсом JNDI выносится на самостоятельную проработку.

Читайте также: