Автор оригинала: Pankaj Kumar.
Программирование источников данных Java и источников данных JDBC-это способ работы с базой данных в наших программах java. Мы уже видели, что JDBC DriverManager можно использовать для подключения к реляционным базам данных. Но когда дело доходит до реального программирования, нам нужно нечто большее, чем просто связи.
Источник данных Java
В большинстве случаев мы ищем слабую связь для подключения, чтобы мы могли легко переключать базы данных, объединять пулы соединений для управления транзакциями и поддержки распределенных систем. Источник данных JDBC является предпочтительным подходом, если вы ищете любую из этих функций в своем приложении. Интерфейс источника данных Java присутствует в javax.sql
пакете и объявляет только два перегруженных метода getConnection()
и getConnection(Строка str1,строка str2)
.
Источник данных JDBC
Различные поставщики баз данных несут ответственность за предоставление различных видов реализации интерфейса источника данных. Например, драйвер MySQL JDBC обеспечивает базовую реализацию интерфейса источника данных с com.mysql.jdbc.jdbc2.необязательно.MysqlDataSource
класс и драйвер базы данных Oracle реализуют его с помощью oracle.jdbc.pool.OracleDataSource
Класс.
Эти классы реализации предоставляют методы, с помощью которых мы можем предоставить сведения о сервере базы данных с учетными данными пользователя. Некоторые из других общих функций, предоставляемых этими классами реализации источников данных JDBC, являются;
- Кэширование подготовленной инструкции для более быстрой обработки
- Настройки тайм-аута подключения
- Функции ведения журнала
- Порог максимального размера результирующего набора
Пример источника данных JDBC
Давайте создадим простой пример проекта источника данных JDBC и узнаем, как использовать базовые классы реализации MySQL и Oracle DataSource для подключения к базе данных. Наш окончательный проект будет выглядеть так, как показано на рисунке ниже.
Источник данных Java JDBC – Настройка базы данных
Прежде чем мы перейдем к нашим примерам программ, нам нужна некоторая настройка базы данных с таблицей и образцами данных. Установка базы данных MySQL или Oracle выходит за рамки этого руководства, поэтому я просто перейду к настройке таблицы с образцами данных.
--Create Employee table CREATE TABLE `Employee` ( `empId` int(10) unsigned NOT NULL, `name` varchar(10) DEFAULT NULL, PRIMARY KEY (`empId`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- insert some sample data INSERT INTO `Employee` (`empId`, `name`) VALUES (1, 'Pankaj'), (2, 'David'); commit;
CREATE TABLE "EMPLOYEE" ( "EMPID" NUMBER NOT NULL ENABLE, "NAME" VARCHAR2(10 BYTE) DEFAULT NULL, PRIMARY KEY ("EMPID") ); Insert into EMPLOYEE (EMPID,NAME) values (10,'Pankaj'); Insert into EMPLOYEE (EMPID,NAME) values (5,'Kumar'); Insert into EMPLOYEE (EMPID,NAME) values (1,'Pankaj'); commit;
Теперь давайте перейдем к нашим программам на java. Для того, чтобы конфигурация базы данных была слабо связана, я прочитаю их из файла свойств.
файл db.properties:
#mysql DB properties MYSQL_DB_DRIVER_CLASS=com.mysql.jdbc.Driver MYSQL_DB_URL=jdbc:mysql://localhost:3306/UserDB MYSQL_DB_USERNAME=pankaj MYSQL_DB_PASSWORD=pankaj123 #Oracle DB Properties ORACLE_DB_DRIVER_CLASS=oracle.jdbc.driver.OracleDriver ORACLE_DB_URL=jdbc:oracle:thin:@localhost:1521:orcl ORACLE_DB_USERNAME=hr ORACLE_DB_PASSWORD=oracle
Убедитесь, что приведенные выше конфигурации соответствуют вашим локальным настройкам. Также убедитесь, что у вас есть JAR-файлы MySQL и Oracle DB JDBC, включенные в путь сборки проекта.
Источник данных Java JDBC – MySQL, пример Oracle
Давайте напишем фабричный класс, который мы можем использовать для получения источника данных MySQL или Oracle.
package com.journaldev.jdbc.datasource; import java.io.FileInputStream; import java.io.IOException; import java.sql.SQLException; import java.util.Properties; import javax.sql.DataSource; import oracle.jdbc.pool.OracleDataSource; import com.mysql.jdbc.jdbc2.optional.MysqlDataSource; public class MyDataSourceFactory { public static DataSource getMySQLDataSource() { Properties props = new Properties(); FileInputStream fis = null; MysqlDataSource mysqlDS = null; try { fis = new FileInputStream("db.properties"); props.load(fis); mysqlDS = new MysqlDataSource(); mysqlDS.setURL(props.getProperty("MYSQL_DB_URL")); mysqlDS.setUser(props.getProperty("MYSQL_DB_USERNAME")); mysqlDS.setPassword(props.getProperty("MYSQL_DB_PASSWORD")); } catch (IOException e) { e.printStackTrace(); } return mysqlDS; } public static DataSource getOracleDataSource(){ Properties props = new Properties(); FileInputStream fis = null; OracleDataSource oracleDS = null; try { fis = new FileInputStream("db.properties"); props.load(fis); oracleDS = new OracleDataSource(); oracleDS.setURL(props.getProperty("ORACLE_DB_URL")); oracleDS.setUser(props.getProperty("ORACLE_DB_USERNAME")); oracleDS.setPassword(props.getProperty("ORACLE_DB_PASSWORD")); } catch (IOException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } return oracleDS; } }
Обратите внимание, что классы реализации источников данных Oracle и MySQL очень похожи, давайте напишем простую тестовую программу для использования этих методов и проведем некоторый тест.
package com.journaldev.jdbc.datasource; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import javax.sql.DataSource; public class DataSourceTest { public static void main(String[] args) { testDataSource("mysql"); System.out.println("**********"); testDataSource("oracle"); } private static void testDataSource(String dbType) { DataSource ds = null; if("mysql".equals(dbType)){ ds = MyDataSourceFactory.getMySQLDataSource(); }else if("oracle".equals(dbType)){ ds = MyDataSourceFactory.getOracleDataSource(); }else{ System.out.println("invalid db type"); return; } Connection con = null; Statement stmt = null; ResultSet rs = null; try { con = ds.getConnection(); stmt = con.createStatement(); rs = stmt.executeQuery("select empid, name from Employee"); while(rs.next()){ System.out.println("Employee ID="+rs.getInt("empid")+", Name="+rs.getString("name")); } } catch (SQLException e) { e.printStackTrace(); }finally{ try { if(rs != null) rs.close(); if(stmt != null) stmt.close(); if(con != null) con.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
Обратите внимание, что класс клиента полностью независим от каких-либо классов, специфичных для базы данных. Это помогает нам скрыть основные детали реализации от клиентской программы и добиться слабой связи и преимуществ абстракции.
Когда мы запустим вышеописанную тестовую программу, мы получим результат ниже.
Employee ID=1, Name=Pankaj Employee ID=2, Name=David ********** Employee ID=10, Name=Pankaj Employee ID=5, Name=Kumar Employee ID=1, Name=Pankaj
Пример DBCP Apache Commons
Если вы посмотрите на приведенный выше класс фабрики источников данных Java, с ним связаны две основные проблемы.
- Методы заводского класса для создания источника данных MySQL и Oracle тесно связаны с соответствующим API драйверов. Если мы хотим удалить поддержку базы данных Oracle в будущем или хотим добавить какую-либо другую поддержку базы данных, это потребует изменения кода.
- Большая часть кода для получения источника данных MySQL и Oracle аналогична, единственное отличие-это класс реализации, который мы используем.
API Apache Commons DBCP помогает нам избавиться от этих проблем, предоставляя реализацию источника данных Java, которая работает как уровень абстракции между нашей программой и различными драйверами JDBC.
Библиотека Apache DBCP зависит от библиотеки общего пула, поэтому убедитесь, что они оба находятся в пути сборки, как показано на рисунке.
Вот класс фабрики источников данных, использующий BasicDataSource, который является простой реализацией источника данных.
package com.journaldev.jdbc.datasource; import java.io.FileInputStream; import java.io.IOException; import java.util.Properties; import javax.sql.DataSource; import org.apache.commons.dbcp.BasicDataSource; public class DBCPDataSourceFactory { public static DataSource getDataSource(String dbType){ Properties props = new Properties(); FileInputStream fis = null; BasicDataSource ds = new BasicDataSource(); try { fis = new FileInputStream("db.properties"); props.load(fis); }catch(IOException e){ e.printStackTrace(); return null; } if("mysql".equals(dbType)){ ds.setDriverClassName(props.getProperty("MYSQL_DB_DRIVER_CLASS")); ds.setUrl(props.getProperty("MYSQL_DB_URL")); ds.setUsername(props.getProperty("MYSQL_DB_USERNAME")); ds.setPassword(props.getProperty("MYSQL_DB_PASSWORD")); }else if("oracle".equals(dbType)){ ds.setDriverClassName(props.getProperty("ORACLE_DB_DRIVER_CLASS")); ds.setUrl(props.getProperty("ORACLE_DB_URL")); ds.setUsername(props.getProperty("ORACLE_DB_USERNAME")); ds.setPassword(props.getProperty("ORACLE_DB_PASSWORD")); }else{ return null; } return ds; } }
Как вы можете видеть, в зависимости от пользовательского ввода создается либо источник данных MySQL, либо Oracle. Если вы поддерживаете только одну базу данных в приложении, то вам даже не нужна эта логика. Просто измените свойства, и вы сможете переключаться с одного сервера базы данных на другой. Ключевым моментом, с помощью которого Apache DBCP обеспечивает абстракцию, является setDriverClassName() метод.
Вот клиентская программа, использующая вышеуказанный заводской метод для получения различных типов соединений.
package com.journaldev.jdbc.datasource; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import javax.sql.DataSource; public class ApacheCommonsDBCPTest { public static void main(String[] args) { testDBCPDataSource("mysql"); System.out.println("**********"); testDBCPDataSource("oracle"); } private static void testDBCPDataSource(String dbType) { DataSource ds = DBCPDataSourceFactory.getDataSource(dbType); Connection con = null; Statement stmt = null; ResultSet rs = null; try { con = ds.getConnection(); stmt = con.createStatement(); rs = stmt.executeQuery("select empid, name from Employee"); while(rs.next()){ System.out.println("Employee ID="+rs.getInt("empid")+", Name="+rs.getString("name")); } } catch (SQLException e) { e.printStackTrace(); }finally{ try { if(rs != null) rs.close(); if(stmt != null) stmt.close(); if(con != null) con.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
Когда вы запустите вышеуказанную программу, результат будет таким же, как и в предыдущей программе.
Если вы посмотрите на источник данных Java JDBC и выше, это можно сделать и с помощью обычного DriverManager. Основное преимущество источника данных Java заключается в том, что он используется в контексте и с JNDI.
С помощью простых конфигураций мы можем создать пул подключений к базе данных, который поддерживается самим контейнером. Большинство контейнеров сервлетов, таких как Tomcat и JBoss, предоставляют собственную реализацию источника данных Java, и все, что нам нужно, – это настроить его с помощью простых конфигураций на основе XML, а затем использовать контекстный поиск JNDI для получения источника данных Java и работы с ним. Это помогает нам, заботясь о пуле соединений и управлении ими со стороны нашего приложения на сторону сервера, и, таким образом, дает нам больше времени для написания бизнес-логики для приложения.
В следующем уроке мы узнаем, как настроить источник данных в контейнере Tomcat и использовать его в веб-приложении.