MySQL & mSQL

Простой доступ к базе данных


В примере Connect делалось не много. В нем было просто показано, как соединиться с базой данных. В соединении с базой данных нет пользы, пока вы не начинаете действительно обмениваться с ней данными. Простейшие виды доступа к базе данных - команды SELECT, INSERT, UPDATE и DELETE. В JDBC API вы используете экземпляр Connection для создания экземпляров класса Statement. Класс Statement представляет SQL-команду любого типа. В примере 14-4 показано, как вставить строку в базу данных, используя Statement.

Пример 14-4. Вставка строки в mSQL с помощью объекта JDBC Statement

import Java, sql.*;

import Java, util.*;

public class Insert {

// Делаем вставку в таблицу, имеющую две колонки: test_id (int)

// и test_val (char(55))

// args[0] - это test_id, a args[1] - test_val

public static void main(String argv[]) {

Connection con = null;

ResourceBundle bundle = ResourceBundle.getBundle("SelectResource");

try {

String url = bundle.getString("URL");



Statement stmt;

Class.forName(bundle.getString("Driver"));

// здесь осуществляется соединение

con = DriverManager.getConnection(url, "borg", "");

stmt = con.createStatement();

stmt.executeUpdate("INSERT INTO test (test_id, test_val) " +

"VALUES(" + args[0] + ", '," + args[1] + ")");

}

catch( SQLException e )

{

e. printStackTrace();

}

finally

{

if( con != null )

{

try { con.close();

}

catch( Exception e ) { }

}

}

}

}

В реальном приложении мы бы, конечно, проверили, что пользователь ввел значение типа INT для test_id, что оно уникально, и что длина введенного значения test_val не превышает 55 символов. Тем не менее пример показывает, как просто осуществлять вставку данных. Метод createStatement() делает то, о чем говорит его название: создает пустую SQL-команду, связанную с рассматриваемым соединением - объектом Connection. Затем метод executeUpdate() передает заданную строку SQL базе данных для выполнения. Как подсказывает название, executeUp-date() ожидает команды SQL, которая некоторым образом модифицирует базу данных. Вы можете использовать ее, чтобы вставлять новые строки, как показано выше, либо удалять строки, обновлять строки, создавать новые таблицы или производить любые другие изменения в базе данных.


Запросы выполнять немного сложнее, чем обновления, поскольку они возвращают информацию из базы данных в виде объекта ResultSet. ResultSet является интерфейсом, представляющим 0 или более строк, являющихся результатом запроса, обращенного к базе данных. В классе JDBC Statement имеется метод executeQuery(), работающий подобно executeUpdate(), за исключением того, что он возвращает из базы данных ResultSet. Метод executeQuery() возвращает ровно один ResultSet, тем не менее имейте в виду, что JDBC поддерживает извлечение множественных результирующих наборов для тех баз данных, которые это позволяют. Ни MySQL, ни mSQL не поддерживают множественные результирующие наборы. Однако важно помнить о такой возможности, когда вы изучаете код для работы с иным ядром базы данных, написанный кем-то другим. В примере 14-5 показан простой запрос. На рис. 14-2 изображена модель данных з таблице test.

Пример 14-5. Простой запрос

import Java, sql.*;

import Java, util.*;

public class Select {

public static void main(String argv[]) {

Connection con = null;

ResourceBundle bundle =ResourceBundle.getBundle("SelectResource");

try {

String url = bundle.getString("URL"); Statement stmt;

ResultSet rs;

Class.forName(bundle.getString("Driver")); // здесь осуществляется соединение

con = DriverManager,getConnection(url, "borg", "");

stmt = con.createStatement();

rs = stmt .executeQuery("SFI FCT* from test ORDER BY test_id");

System, out.print In("Полученные результаты:");

while(rs. next()) {

int a= rs.getInt("test_icT);

String str = rs.getString("test_val");

System.out.print(" ключ= " + a);

System.out.print(" строка= " + str);

System.out.print("\n");

}

stmt.close();

}

catch( SQLException e )

{

e. printStackTrace();

}

finally {

if( con != null ) {

try { con.close(); }

catch( Exception e ) { }

}

}

}

}

Приложение Select выполняет запрос и затем проходит по всем строкам ResultSet с помощью метода next(). До первого обращения к next() ResultSet не указывает ни на какую строку. Каждый вызов next () настраивает ResultSet на следующую строку. JDBC 2:0 вводит понятие результирующего набора с перемещением (scrollable). Если ваш экземпляр ResultSet позволяет перемещение, можно также обращаться к методу previous() для перемещения по результирующему набору в обратном направлении. Обработка строк заканчивается, когда next () возвращает false.





Рис. 14-2. Таблица test из учебной базы данных

Работа со строкой означает получение значений для каждой колонки. Каково бы ни было значение в базе данных, можно использовать методы ResultSet для получения значения колонки с любым типом данных Java, который вас устраивает. В приложении Select вызов метода gе tInt() возвращал колонку test_id как int, а вызов getString() возвращал значение колонки test_val как String. Эти методы получения значения колонки принимают либо номер колонки, начиная с 1, либо ее имя. Следует, однако, всеми силами избегать извлечения значений с помощью имен колонок, поскольку такой способ значительно медленнее, чем получение их с помощью номеров колонок.

Обработка ошибок и освобождение ресурсов

Все методы JDBC могут возбуждать SQLException или один из подклассов этого класса, если что-то происходит при обращении к базе данных. Ваш код должен уметь перехватывать исключительную ситуацию, обрабатывать ее и освобождать все размещенные в памяти ресурсы базы данных. Все перечисленные до сих пор классы JDBC имеют метод close(). Однако на практике вы должны обеспечить закрытие только тех объектов, которые вызваны процессами, продолжающими оставаться открытыми. В приведенных до сих пор примерах практически требовалось закрыть только соединение с базой данных. При закрытии соединения автоматически закрываются все связанные с ним команды и результирующие наборы. Однако если вы намерены сохранить соединение открытым в течение некоторого времени, будет правильным поспешить закрыть все объекты statement, которые вы создали с использованием этого соединения, когда они вам больше не нужны. В примерах JDBC, которые вы видели, это освобождение ресурсов производится в предложении finally. Это делается для того, чтобы обеспечить закрытие соединения независимо от того, что произойдет.




Содержание раздела