Соединение с базой данных


Было посчитано, что половина всего разрабатываемого программного обеспечения использует клиент/серверные операции. Огромная перспектива Java была в способности строить платформо-независимые клиент/серверные приложения для баз данных. Это осуществляется с помощью Java DataBase Connectivity (JDBC).

Одна из главных проблем баз данных была в особенностях, которые имеют разные базы данных от разных компаний. Есть "стандартный" язык баз данных, Структурированный Язык Запросов - Structured Query Language (SQL-92), но вы должны обычно знать, с базой данных какого производителя вы работаете, не смотря на стандарт. JDBC разработана так, чтобы быть платформо-независимой, так что вам нет необходимости беспокоиться во время программирования о базе данных. Однако все равно есть возможность делать специфичные для производителя вызовы из JDBC, так что вы не ограничены от выполнения тех задач, которые должны.

Одно место, где программисту может понадобиться использование имен SQL типов - это в SQL выражении TABLE CREATE, когда необходимо создать новую базу данных и определить SQL типы для каждой колонки. К сожалению, есть значительные отличия между SQL типами, поддерживаемыми разными базами данных. Разные базы данных, которые поддерживают SQL типы с одинаковой семантикой и структурой, могут давать этим типам разные имена. Наиболее распространенные базы данных поддерживают SQL типы данных для больших бинарных значений: в Oracle этот тип называется LONG RAW, Sybase называет его IMAGE, а DB2 называет его LONG VARCHAR FOR BIT DATA. Поэтому, если портируемость базы дынных является вашей целью, вы должны попробовать использовать только общие идентификаторы SQL типов.

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

JDBC, как и многое другое API, разработано для упрощения. Вызовы методов, которые вы совершаете, соответствуют логическим операциям, о которых вы думаете при получении данных из базы данных: соединение с базой данных, создание выражения (statement) и выполнение запроса, затем просмотр результирующей выборки.

Чтобы обеспечить независимость от платформы, JDBC предоставляет менеджер драйверов, который динамически поддерживает все объекты-драйверы, необходимые для запроса к вашей базе данных. Так что, если у вас есть три базы данных различных производителей, с которыми вы соединяетесь, вам необходимо три различных объекта драйвера. Объект драйвера регистрирует себя в менеджере драйверов во время загрузки, и вы можете форсировать загрузку, используя Class.forName( ).

Для открытия базы данных вы должны создать "URL базы данных", в котором указывается:

  1. Что вы используете JDBC, с помощью "jdbc".
  2. "Суб протокол": имя драйвера или имя механизма соединения с базой данных. Так как дизайн JDBC инспирирован ODBC, первый из доступных протоколов - это "jdbc-odbc bridge", который указывается, как "odbc".
  3. Идентификатор базы данных. Он различен для различных баз данных, но обычно он предоставляет логическое имя, которое отображается программным обеспечением администрирования базы данных на физический директорий, в котором расположены таблицы базы данных. Для вашей базы данных этом может иметь любое значение, вы должны зарегистрировать имя, используя ваше программное обеспечение администрирования базы данных. (Процесс регистрации различается для разных платформ.)

Вся эта информация комбинируется в одну строку, "URL базы данных". Например, для соединения через ODBC субпроткол к базе данных с идентификатором "people", URL базы данных должен быть таким:

String dbUrl = "jdbc:odbc:people";

Если вы соединяетесь по сети, URL базы данных будет содержать информацию о соединении, идентифицирующую удаленную машину и поэтому может стать немного пугающей. Вот пример базы данных CloudScape, вызываемой из удаленного клиента, использующего RMI:

jdbc:rmi://192.168.170.27:1099/jdbc:cloudscape:db

Этот URL базы данных реально содержит два JDBC вызова в одном. Первая часть "jdbc:rmi://192.168.170.27:1099/" использует RMI для создания соединения с удаленной машиной базы данных, прослушивающей порт 1099 по IP адресу 192.168.170.27. Вторая часть URL, "jdbc:cloudscape:db" выражает более типичные установки используемого субпротокола и имени базы данных, но они обычно проявляются только после первой части, которая устанавливает соединение посредством RMI с удаленной машиной.

Когда вы готовы соединиться с базой данных, вызывайте статический метод DriverManager.getConnection( ) и передавайте ему URL базы данных, имя пользователя и пароль, чтобы получить доступ в базу данных. Назад вы получаете объект Connection, который вы можете затем использовать для запроса и управления базой данных.

Следующий пример открывает контактную информацию базы данных и производит поиск фамилий по заданному в командной строке. В примере выбираются только имена людей, у которых задан EMail адрес, затем происходит печать всех, у кого совпала фамилия:

//: c15:jdbc:Lookup.java
// Поиск email адресов в
// локальной базе данных с использованием JDBC.
// {Broken}
import java.sql.*;

public class Lookup {
  
public static void main(String[] args) throws SQLException,
         ClassNotFoundException
{
     
String dbUrl = "jdbc:odbc:people";
      String user =
"";
      String password =
"";
     
// Загружаем драйвер (регистрирует себя)
     
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
      Connection c = DriverManager.getConnection
(dbUrl, user, password);
      Statement s = c.createStatement
();
     
// SQL код:
     
ResultSet r = s.executeQuery("SELECT FIRST, LAST, EMAIL "
           
+ "FROM people.csv people " + "WHERE " + "(LAST='" + args[0]
           
+ "') " + " AND (EMAIL Is Not Null) " + "ORDER BY FIRST");
     
while (r.next()) {
        
// Регистр не имеет значения:
        
System.out.println(r.getString("Last") + ", "
              
+ r.getString("fIRST") + ": " + r.getString("EMAIL"));
     
}
     
s.close(); // Закрываем ResultSet
  
}
}
// /:~

Вы можете видеть создание URL базы данных, как описано прежде. В этом примере нет пароля защиты для базы данных, так что строки имени пользователя и пароля пустые.

Как только соединение будет установлено с помощью DriverManager.getConnection( ), вы можете использовать полученный объект Connection для создания объекта Statement с помощью метода createStatement( ). С помощью полученного объекта Statement вы можете вызвать метод executeQuery( ), передав в него строку, содержащую SQL выражение в стандарте SQL-92. (Вы увидите, как вы можете сгенерировать это выражение автоматически, так что вам не нужно знать очень много об SQL.)

Метод executeQuery( ) возвращает объект ResultSet, который является итератором: метод next( ) перемещает итератор на следующую запись в выражении, или возвращает false, если достигнут конец результирующего множества. Вы всегда будете получать объект ResultSet из метода executeQuery( ), даже если результатом запроса будет пустое множество (то есть, исключение не выбрасывается). Обратите внимание, что вы должны вызвать метод next( ) один раз, прежде, чем попробуете прочесть любую запись с данными. Если результирующее множество пустое, этот первый вызов next( ) вернет false. Для каждой записи из результирующего множества вы можете выбрать поля, используя (наряду с другими подходами) имя поля, как строку. Также обратите внимание, что регистр букв в имени поля игнорируется - он не имеет значения в базе данных SQL. Вы определяете тип того, что вы получаете назад, вызывая getInt( ), getStrin( ), getFloat( ) и т. п. Таким образом, вы получаете данные из вашей базы данных в родном формате и можете делать с ними все, что хотите, используя обычный код Java.

Получение примера для работы

С использованием JDBC, понимание кода относительно упрощается. Сбивающие с толку части заставляют его работать на вашей определенной системе. Причина, по которой эти части сбивают с толку, состоит в том, что вам требуется показать, как получить правильную загрузку вашего JDBC драйвера и как установить базу данных с помощью вашего программного обеспечения для администрирования базы данных.

Конечно же, этот процесс может радикально отличаться на разных машинах, но процесс, который использовал я, работает на 32-х битной Windows и может дать вам ключ к пониманию, с какой стороны подойти к вашей собственной ситуации.