Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Программирование на Java часть 2

.pdf
Скачиваний:
134
Добавлен:
16.03.2016
Размер:
3.07 Mб
Скачать

Тема 2.3 Класс ResultSet

Этот класс представляет результирующий набор базы данных. Он обеспечивает приложению построчный доступ к результатам запросов в базе данных. Во время обработки запроса ResultSet поддерживает указатель на текущую обрабатываемую строку. Приложение последовательно перемещается по результатам, пока они не будут все обработаны или не будет закрыт ResultSet.

Основные методы:

public boolean absolute(int row) throws SQLException

Метод перемещает курсор на заданное число строк от начала, если число положительно, и от конца - если отрицательно.

public void afterLast() throws SQLException

Этот метод перемещает курсор в конец результирующего набора за последнюю строку.

public void beforeFirst() throws SQLException

Этот метод перемещает курсор в начало результирующего набора перед первой строкой.

public void deleteRow() throws SQLException

Удаляет текущую строку из результирующего набора и базы данных. public ResultSetMetaData getMetaData() throws SQLException

Предоставляет объект метаданных для данного ResultSet. Класс ResultSetMetaData содержит информацию о результирующие таблице, такую как количество столбцов, их заголовок и т.д.

public int getRow() throws SQLException

Возвращает номер текущей строки.

public Statement getStatement() throws SQLException

Возвращает экземпляр Statement, который произвел данный результирующий набор.

public boolean next() throws SQLException public boolean previous() throws SQLException

Эти методы позволяют переместиться в результирующем наборе на одну строку вперед или назад. Во вновь созданном результирующем наборе курсор устанавливается перед первой строкой, поэтому первое обращение к методу next() влечет позиционирование на первую строку. Эти методы возвращают true, если остается строка для дальнейшего перемещения. Если строк для обработки больше нет, возвращается false. Если открыт поток InputStream для предыдущей строки, он закрывается. Также очищается цепочка предупреждений SQLWarning.

public void close() throws SQLException

Осуществляет немедленное закрытие ResultSet вручную. Обычно этого не требуется, так как закрытие Statement, связанного с ResultSet, автоматически закрывает ResultSet. К сожалению, не все разработчики JDBCдрайверов придерживаются этих конвенций, например, драйвер Oracle

51

самостоятельно не закрывает ResultSet'ы, так что настоятельно советую закрывать вручную.

Листинг 2.3 import java.sql.*; public class DB {

private Connection cn; private Statement st; private ResultSet rs;

public DB(String path, String nameDB, String login, String pass) { try {

Class.forName("com.mysql.jdbc.Driver"); try {

cn = DriverManager.getConnection(path + nameDB, login, pass); try {

st = cn.createStatement(); } catch (SQLException ex) {

System.out.println("Error in Statement " + ex);

}

} catch (SQLException ex) {

System.out.println("Error in create Connection " + ex);

}

} catch (ClassNotFoundException ex) { System.out.println("Error in download Driver " + ex);

}

}

public void update(String sql) { try {

st.executeUpdate(sql);

}catch (SQLException ex) { System.out.println("Error in update " + ex);

}

}

public ResultSet query(String sql) { try {

rs = st.executeQuery(sql);

}catch (SQLException ex) { System.out.println("Error in query " + ex);

}

return rs;

}

public void close() { try {

st.close();

cn.close();

} catch (SQLException ex) {

52

System.out.println("Error in close " + ex);

}

}

}

import java.sql.*; public class Main {

public static void main(String[] args) {

DB db = new DB("jdbc:mysql://localhost/", "my_db", "root", ""); ResultSet rs = db.query("SELECT * FROM user ");

try {

while (rs.next()) {

System.out.println("ib = " + rs.getInt(1) + "\tname = " + rs.getString(2));

}

} catch (SQLException ex) { System.out.println("Error in rs " + ex);

}

db.close();

}

}

В результате выполнения данной программы получим: ib = 1 name = user1

ib = 2 name = user2 ib = 3 name = user3

Тема 2.4 Метаданные

Существует целый ряд методов интерфейсов ResultSetMetaData и DatabaseMetaData для интроспекции объектов. С помощью этих методов можно получить список таблиц, определить типы, свойства и количество столбцов БД. Для строк подобных методов нет.

Получить объект ResultSetMetaData можно следующим образом:

ResultSetMetaData rsMetaData = rs.getMetaData();

Некоторые методы интерфейса ResultSetMetaData:

int getColumnCount() – возвращает число столбцов набора результатов объекта ResultSet;

String getColumnName(int column) – возвращает имя указанного столбца объекта ResultSet;

int getColumnType(int column) – возвращает тип данных указанного столбца объекта ResultSet и т.д.

Получить объект DatabaseMetaData можно следующим образом:

DatabaseMetaData dbMetaData = cn.getMetaData();

Некоторые методы весьма обширного интерфейса DatabaseMetaData:

53

String getDatabaseProductName() – возвращает название СУБД;

String getDatabaseProductVersion() – возвращает номер версии СУБД; String getDriverName() – возвращает имя драйвера JDBC;

String getUserName() – возвращает имя пользователя БД;

String getURL() – возвращает местонахождение источника данных; ResultSet getTables() – возвращает набор типов таблиц, доступных для

данной БД, и т.д.

Добавим в класс DB метод showDatabaseMetaData() демонстрирующий работу некоторых методов из класса DatabaseMetaData и метод showResultSet() выводящий все данные из объекта класса ResultSet.

Листинг 2.4 import java.sql.*; public class DB {

private Connection cn; private Statement st; private ResultSet rs;

public DB(String path, String nameDB, String login, String pass) { try {

Class.forName("com.mysql.jdbc.Driver"); try {

cn = DriverManager.getConnection(path + nameDB, login, pass); try {

st = cn.createStatement();

}catch (SQLException ex) { System.out.println("Error in Statement " + ex);

}

} catch (SQLException ex) {

System.out.println("Error in create Connection " + ex);

}

}catch (ClassNotFoundException ex) { System.out.println("Error in download Driver " + ex);

}

}

public void update(String sql) { try {

st.executeUpdate(sql);

}catch (SQLException ex) { System.out.println("Error in update " + ex);

}

}

public ResultSet query(String sql) { try {

rs = st.executeQuery(sql); } catch (SQLException ex) {

54

System.out.println("Error in query " + ex);

}

return rs;

}

public void close() { try {

st.close();

cn.close();

}catch (SQLException ex) { System.out.println("Error in close " + ex);

}

}

public void showDatabaseMetaData() { try {

//получаем метаданные

DatabaseMetaData dbmd = cn.getMetaData(); //выводим информацию про БД

System.out.println(dbmd.getDatabaseProductName());

System.out.println(dbmd.getDatabaseProductVersion());

System.out.println(dbmd.getDriverName());

System.out.println(dbmd.getDriverVersion()); } catch (SQLException ex) {

System.out.println("Error in showDatabaseMetaData " + ex);

}

}

public void showResultSet(ResultSet rs) { try {

//получаем метаданные

ResultSetMetaData rsmd = rs.getMetaData(); //выводим названия столбцов

for (int i = 1; i <= rsmd.getColumnCount(); i++) { System.out.print(rsmd.getColumnName(i) + "\t");

}

// выводим строки while (rs.next()) {

System.out.println();

for (int i = 1; i <= rsmd.getColumnCount(); i++) { System.out.print(rs.getString(i) + "\t");

}

}

}catch (SQLException ex) { System.out.println("Error in showResultSet " + ex);

}

}

55

}

public class Main {

public static void main(String[] args) {

DB db = new DB("jdbc:mysql://localhost/", "my_db", "root", ""); db.showDatabaseMetaData(); db.showResultSet(db.query("SELECT * FROM user ")); db.close();

}

}

В результате работы данной программы получили:

MySQL 5.1.53-community MySQL-AB JDBC Driver

mysql-connector-java-5.1.18 id name

1user1

2user2

3user3

Тема 2.5 Подготовленные запросы

Для представления запросов существуют еще объекты PreparedStatement. Объекты этого класса используются при выполнении часто повторяющихся запросов SQL. Такой оператор предварительно готовится и хранится в объекте, что ускоряет обмен информацией с базой данных.

Одно из важных свойств метода prepareStatement – возможность обработки входных параметров. Они помечаются в операторе SQL символом "?" на месте фактического значения. В программе Java проводится соответствие между параметрами и методами setXXXX() – setInt, setFloat, setString и т.д., в соответствии с типами входных параметров. Все методы setXXXX() принимают в качестве параметров значение параметра и указатель parameterIndex, который равен 1 для первого "?", 2 – для второго и т.д. Выполнение sql-оператора обеспечивается методами объекта

PreparedStatement:

executeQuery() – для выполнения запроса выборки SELECT ;

executeUpdate() – для выполнения запроса модификации данных

INSERT, UPDATE или DELETE.

Объект PreparedStatement обеспечивает более быстрое выполнение оператора SQL. Оценить преимущества во времени можно, выполнив большое число повторяемых запросов с предварительной подготовкой запроса и без нее.

56

PreparedStatement ps = null;

String sql = "INSERT INTO user (id, name) VALUES(?,?)";

//компиляция (подготовка) запроса

ps = (PreparedStatement) cn.prepareStatement(sql); ps.setInt(1, id);

ps.setString(2, name);

//выполнение подготовленного запроса ps.executeUpdate();

Втаблице каждая строка содержит данные об одном объекте и, прежде чем создавать таблицу, удобно создать класс-сущность, имя которого будет совпадать с названием таблицы, а поля – с названиями столбцов.

Влистинге 6.5 приведен пример использования подготовленного запроса

икласса сущности.

Листинг 2.5 public class User {

private int id; private String name; public User() {

}

public User(int id, String name) { this.id = id;

this.name = name;

}

public int getId() { return id;

}

public void setId(int id) { this.id = id;

}

public String getName() { return name;

}

public void setName(String name) { this.name = name;

}

@Override

public String toString() {

return super.toString(); //To change body of generated methods, choose Tools | Templates.

}

}

import java.sql.*; public class DB {

private Connection cn; private Statement st;

57

private ResultSet rs;

public DB(String path, String nameDB, String login, String pass) { try {

Class.forName("com.mysql.jdbc.Driver"); try {

cn = DriverManager.getConnection(path + nameDB, login, pass); try {

st = cn.createStatement();

}catch (SQLException ex) { System.out.println("Error in Statement " + ex);

}

} catch (SQLException ex) {

System.out.println("Error in create Connection " + ex);

}

}catch (ClassNotFoundException ex) { System.out.println("Error in download Driver " + ex);

}

}

public void update(String sql) { try {

st.executeUpdate(sql);

} catch (SQLException ex) { System.out.println("Error in update " + ex);

}

}

public ResultSet query(String sql) { try {

rs = st.executeQuery(sql);

}catch (SQLException ex) { System.out.println("Error in query " + ex);

}

return rs;

}

public void close() { try {

st.close();

cn.close();

}catch (SQLException ex) { System.out.println("Error in close " + ex);

}

}

public void showDatabaseMetaData() { try {

//получаем метаданные

DatabaseMetaData dbmd = cn.getMetaData();

58

//выводим информацию про БД

System.out.println(dbmd.getDatabaseProductName());

System.out.println(dbmd.getDatabaseProductVersion());

System.out.println(dbmd.getDriverName());

System.out.println(dbmd.getDriverVersion()); } catch (SQLException ex) {

System.out.println("Error in showDatabaseMetaData " + ex);

}

}

public void showResultSet(ResultSet rs) { try {

//получаем метаданные

ResultSetMetaData rsmd = rs.getMetaData();

//выводим названия столбцов

for (int i = 1; i <= rsmd.getColumnCount(); i++) { System.out.print(rsmd.getColumnName(i) + "\t");

}

// выводим строки while (rs.next()) {

System.out.println();

for (int i = 1; i <= rsmd.getColumnCount(); i++) { System.out.print(rs.getString(i) + "\t");

}

}

System.out.println();

} catch (SQLException ex) { System.out.println("Error in showResultSet " + ex);

}

}

public void addUser(User user) { try {

PreparedStatement ps = null;

String sql = "INSERT INTO " + user.getClass().getSimpleName() + " (id, name) VALUES(?,?)";

//компиляция (подготовка) запроса

ps = (PreparedStatement) cn.prepareStatement(sql); ps.setInt(1, user.getId());

ps.setString(2, user.getName()); //выполнение подготовленного запроса ps.executeUpdate();

} catch (SQLException ex) { System.out.println("Error in addUser " + ex);

}

}

public void changeNameUser(User user) {

59

try {

PreparedStatement ps = null;

String sql = "UPDATE " + user.getClass().getSimpleName() + " SET name=? WHERE id=" + user.getId();

ps = (PreparedStatement) cn.prepareStatement(sql); ps.setString(1, user.getName()); ps.executeUpdate();

} catch (SQLException ex) {

System.out.println("Error in changeNameUser " + ex);

}

}

public void deleteUser(User user) {

String sql = "DELETE FROM " + user.getClass().getSimpleName() + " WHERE id=" + user.getId();

update(sql);

}

}

public class Main {

public static void main(String[] args) {

DB db = new DB("jdbc:mysql://localhost/", "my_db", "root", ""); System.out.println("Вывод текущего состояния таблицы"); db.showResultSet(db.query("SELECT * FROM user")); db.addUser(new User(4, "user4"));

db.addUser(new User(5, "user5")); db.addUser(new User(6, "user6"));

System.out.println("Вывод таблицы после добавления нескольких объектов");

db.showResultSet(db.query("SELECT * FROM user")); db.changeNameUser(new User(6, "new_user6"));

User mas[] = {new User(7, "user7"), new User(8, "user8"), new User(9, "user9")};

for (int i = 0; i < mas.length; i++) { db.addUser(mas[i]);

}

System.out.println("Вывод таблицы после добавления массива объектов");

db.showResultSet(db.query("SELECT * FROM user")); for (int i = 0; i < mas.length; i++) {

db.deleteUser(mas[i]);

}

System.out.println("Вывод таблицы после удаления массива объектов");

db.showResultSet(db.query("SELECT * FROM user")); db.close();

60