Пример создания простого приложения.
//Шаг первый: Импорт
пакетов
import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.Date;
import java.sql.SQLException;
public class FirstQuery
{
public static void
main(String[] args) {
Connection conn
= null;
try {
//Шаг второй:
Регистрация JDBC драйвера
String driver
= "oracle.jdbc.OracleDriver";
Class.forName(driver);
//Шаг третий: Создание соединения
System.out.println("Connecting
to database ...");
String jdbcUrl
= "jdbc:oracle:thin:@localhost:1521:orbis";
String user
= "stud";
String pass
= "stud";
conn = DriverManager.getConnection(jdbcUrl,
user, pass);
//Шаг четвертый: Выполнение
запроса
Statement
st = conn.createStatement();
String sql;
sql = "SELECT
COUNT(*) FROM all_tables";
ResultSet
rs = st.executeQuery(sql);
//Шаг пятый:
Извлечение данных из "Результата запроса"
while(rs.next())
{
//
int count
= rs.getInt(1);
System.out.println("Result
set is: "+count);
}
//Шаг шестой: Освобождение
ресурсов
rs.close();
st.close();
conn.close();
//Шаг седьмой:
Обработка исключений
}catch(SQLException
se) {
//Обработка ошибок для JDBC
se.printStackTrace();
}catch(Exception
e) {
//Обработка
ошибок для Class.forName
e.printStackTrace();
}finally {
//finally
block used to close resourses
try{
if (conn!=null)
conn.close();
}catch(SQLException
se) {
se.printStackTrace();
}//end finally
try
}//end try
System.out.println("GoodBye!");
}//end main
}//end FirstQuery
Шаг 1: Импортирование
классов и интерфейсов.
Как и во всех Java-приложениях необходимо импортировать пакеты, которые
содержат необходимые для работы программы классы. Все JDBC
интерфейсы и классы находятся в пакетах java.sql и javax.sql. Пакет java.sql содержит основные интерфейсы и классы, которые используются
в любых JDBC-приложениях. Пакет javax.sql содержит классы и
интерфейсы, необходимые для написания приложений корпоративного уровня. Он
является стандартным расширением и применяется при создании и использовании
"пула соединений", работы с "наборами строк", распределенными транзакциями
и т.д.
В приведенном выше примере
импортированы следующие классы и интерфейсы:
- java.sql.DriverManager – Поддерживает совокупность драйверов-объектов
и предоставляет их, при необходимости, для осуществления взаимодействия с
СУБД.
- java.sql.Connection – Предоставляет физическое соединение с СУБД.
Объекты данного класса управляют уровнями транзакций и типами результатов
(ResultSet), возвращаемых выполняемыми запросами.
- java.sql.Statement – Пересылает SQL-предложение
(запрос) в СУБД. Этот интерфейс позволяет отправлять только статические
запросы без параметров. Для передачи в СУБД запроса с параметрами используются
методы интерфейса java.sql.PreparedStatement.
- java.sql.ResultSet – Получает результат обработанного СУБД запроса
и предусматривают методы для построчного извлечения данных результата запроса
из объекта.
- java.sql.Date – Отображает тип данных JDBC
на SQL DATE тип данных.
- java.sql.SQLException – Обрабатывает ошибки, возвращаемые СУБД,
и исключения, возникающие в JDBC программах.
Шаг 2: Регистрация
JDBC драйвера.
Драйвер JDBC является зависимой от конкретной СУБД частью программного
интерфейса между Java-приложением и базой данных.
Процедура добавления его к общим java.sql-классам называется регистрацией, которая может быть
выполнена следующими методами соответствующий классов:
- DriverManager.registerDriver(Driver “объект класса драйвера”);
- Class.forName(String “имя класса драйвера”).
Метод DriverManager.registerDriver() требует указания параметра
типа Driver. Регистрация драйвера этим методом производится
на этапе компиляции программы и в случае проблемы с регистрацией возникает
исключение типа SQLException. Ниже приведен пример
программного кода, создающего с помощью конструктора oracle.jdbc.OracleDriver()
новый объект типа oracle.jdbc.OracleDriver и передающего его в качестве параметра
методу DriverManager.registerDriver():
try {
DriverManager.registerDriver(new
oracle.jdbc.OracleDriver());
} catch (SQLException
se) {
se.printStackTrace();
}
Метод Class.forName() является более
гибким методом регистрации драйвера, т.к. получает его имя в виде параметра
типа String. Это позволяет задавать имя драйвера
в командной стоке запуска Java-приложения на выполнение
или в файле свойств, читаемым Java-приложением в
момент исполнения программы. В приведенном выше примере переменной driver типа String присваивается
полное имя класса JDBC драйвера. Данный метод выдает
исключение ClassNotFoundException если указанный
в качестве параметра драйвер не был найден в момент выполнения программы.
Использование Class.forName(String
“имя класса драйвера”).newInstance() является наиболее распространенным способом
регистрации драйвера. Созданный таким образом новый объект драйвера саморегистрируется
с помощью статического инициализатора, который вызывает метод DriverManager.registerDriver().
Этот механизм позволяет динамически регистрировать драйвера в процессе выполнения
программы. В случае регистрации ORACLE драйвера программный код может выглядеть
следующим образом:
try {
String driver = “oracle.jdbc.OracleDriver”;
Class.forName(driver).newInstance();
} catch (ClassNotFoundException
e) {
//Возникает, если
класс драйвера не найден в CLASSPATH
e.print.StackTrace();
}
Для указания имени
класса драйвера в качестве системного свойства в командной строке запуска
программы на выполнение используется ключ -D. В этом случае JVM будет пытаться
загрузить драйвер как часть процесса инициализации. По завершению инициализации
будет запущено на выполнение само приложение. При этом регистрации драйвера
в самом приложении уже не требуется. Ниже приведен пример командной строки:
java -Djdbc.drivers=oracle.jdbc.OracleDriver
FirstQuery
В случае чтения имени класса драйвера из файла свойств, последний должен
содержать строчку следующего вида:
jdbc.drivers=oracle.jdbc.OracleDriver
Ниже приведен пример
программного кода, читающего имя класса драйвера из файла свойств по имени
database.properties:
Properties props = new
Properties();
FileInputStream in =
new FileInputStream("database.properties");
props.load(in);
in.close();
String drivers = props.getProperty("jdbc.drivers");
System.setProperty("jdbc.drivers",
drivers);
Драйверов может быть
зарегистрировано несколько. Например, такая необходимость возникает при разработке
приложений, обращающихся сразу к нескольким СУБД. В процессе выполнения приложения
выбор нужного драйвера можно осуществить следующими методами:
- DriverManager.getDriver();
- DriverManager.getDrivers().
Первый метод возвращает
соответствующий объект драйвера. Второй метод возвращает объект типа Enumeration,
содержащий список зарегистрированных драйверов. Ниже приведен пример программного
кода, демонстрирующий использование второго метода:
Enumeration drEnum =
DriverManager.getDrivers();
while(drEnum.hasMoreElements())
{
Driver dr = (Driver)drEnum.nextElement();
String str =
"Driver class name is: "+dr.getClass().getName();
System.out.println(str);
}
Если по какой либо
причине возникла необходимость исключить возможность обращения к той или иной
или базе данных, то можно воспользоваться методом DriverManager.deregisterDriver(),
которому в качестве параметра указывается объект ранее зарегистрированного
драйвера, например:
DriverManager.deregisterDriver(dr)
Шаг 3: Создание соединения
с СУБД.
Для того чтобы открыть
соединение с базой данных можно использовать один из трех перегруженных методов
DriverManager.getConnection():
DriverManager.getConnection(String
url)
DriverManager.getConnection(String
url, Properties prop)
DriverManager.getConnection(String
url, String username, String password)
Перед вызовом метода
необходимо установить необходимые для создания соединения параметры:
- url – указывает на местоположение базы данных и тип
драйвера.
- username – имя пользователя, который будет использовать
соединение.
- password – пароль пользователя.
- prop – объект
типа Properties.
В примере FirstQuery
первая часть строки URL (jdbc:oracle:thin) указывает на тип
драйвера, а вторая часть(@localhost:1521:orbis) указывает на местоположение базы, порт и ее название,
под которым она известна СУБД. В случае использования метода с одним параметром
во второй части строки URL может быть указано имя пользователя и его пароль
(stud/stud@localhost:1521:orbis).
Ниже приведен пример программного кода с использованием в качестве параметра
объект типа Properties
и файла свойств по имени database.properties:
//Usage: java DBConnProp.
//Contents of file database.properties
is:
//jdbc.drivers=oracle.jdbc.OracleDriver
//jdbc.url=jdbc:oracle:thin:@localhost:1521:orbis
//user=stud
//password=stud
//
import java.io.*;
import java.sql.*;
import java.util.*;
//
public class DBConnProp
{
public static void
main(String[] args) throws Exception {
Connection db
= getConnection();
Statement st
= db.createStatement();
ResultSet rs
= st.executeQuery("SELECT
COUNT(*) FROM all_tables");
while (rs.next())
{
System.out.println(rs.getInt(1));
}
rs.close();
st.close();
db.close();
}
public static Connection
getConnection() throws Exception {
Properties props
= new Properties();
FileInputStream
in = new FileInputStream("ad.database.properties");
props.load(in);
in.close();
props.list(System.out);
String drivers
= props.getProperty("jdbc.drivers");
if (drivers !=
null) {
System.setProperty("jdbc.drivers",
drivers);
System.out.println("Property
\"jdbc.drivers\" = " +
System.getProperty("jdbc.drivers"));
}
String url =
props.getProperty("jdbc.url");
return DriverManager.getConnection(url,
props);
}
}
Если попытка установки
соединения окончится неудачей, то будет создан экземпляр исключения типа SQLException. В случае удачи, вновь созданный объект
типа Connection будет представлять физическое соединение
с базой данных.
Шаг. 4: Выполнение SQL запроса.
Для выполнения запроса
к базе данных необходимы два объекта. Первый объект необходим для применения
интерфейсов Statement, PreparedStatement
или CallableStatement. Эти три интерфейса имеют
разное назначение. Интерфейс java.sql.Statement используется
для выполнения статических запросов без параметров. Интерфейс java.sql.PreparedStatement используется для выполнения запросов
с изменяемыми параметрами параметрами. И, наконец, java.sql.CallableStatement используется
для выполнения хранимых в базе данных процедур.
Второй необходимый
для выполнения запроса объект имеет тип ResultSet.
Этот объект содержит результат выполнения запроса и предусматривает ряд
итераторов, с помощью которых данные результата можно построчно извлекать
из объекта.
В приведенном выше
примере инициализируется объект типа Statement
с помощью метода createStatement() объекта типа
Connection. Далее переменной типа String присваивается SQL-предложение,
которое используется в качестве параметра при выполнении метода executeQuery() объекта типа Statement.
Данный метод возвращает объект типа ResultSet,
содержащий результат выполнения запроса. В случае возникновения какой либо
ошибки возникает исключение типа SQLException.
Шаг. 5: Просмотр результата
запроса.
Данные результата
запроса сохраняются в объекте типа ResultSet в
виде таблицы из строк и столбцов. Количество строк определяется критерием
выборки, указанном во фразе WHERE SQL-предложения. Порядок следования столбцов результата
запроса соответствует порядку их перечисления в SQL-предложении.
Тип данных столбцов результата запроса соответствует типу данных столбцов
таблицы базы данных.
Для извлечения данных
результата запроса из объекта типа ResultSet используются
методы getXXX() этого объекта, где XXX соответствует извлекаемому типу данных (например:
getInt(), getString(),
getDate()), а в скобках указывается в качестве
параметра номер (начиная с 1) или символьное имя столбца. Объект типа ResultSet использует курсор, указывающий на текущую строку
результата запроса. Перемещение курсора по строкам результата запроса осуществляется
с помощью метода next() объекта типа ResultSet, содержащего этот результат. При этом существует
два специальных положения курсора, указывающие на положение перед первой
строкой результата запроса и на положение после последней строки результата
запроса. Эти положения ничего не содержат и попытка получить из них данные
приведет к возникновению исключения типа SQLException.
В первоначальный момент сразу после заполнения объекта данными результата
запроса курсор установлен в крайнем верхнем положении – перед первой строкой
данных. По этому перед выполнением метода getXXX()
необходимо переместить курсор на первую строку результата запроса. Обычно
это делается с помощью уже упомянутого метода next(),
который возвращает значение TRUE, если курсор после
его выполнения указывает на строку с данными результата запроса, и FALSE, если курсор указывает на пустое положение после
последней строки данных результата запроса. Это позволяет использовать метод
в качестве условия при организации цикла перемещения курсора по строкам данных
результата запроса.
Шаг. 6: Освобождение
ресурсов.
Освобождение ресурсов
осуществляется методом close() объекта, представляющего
собой тот или иной ресурс, например: результат запроса, соединение с базой
и т.д.