logo search
5 модуль

Пример: база данных студентов

Рассмотрим небольшой пример работы с базой данных о студентах, схему которой мы определили в начале раздела. Задача — получить из базы данных студентов.

  1. Создадим класс для получения соединения с базой:

import java.sql.*;

public class DbUtil {

// строка соединения с базой

private static String URL = "jdbc:mysql://localhost:3306/test";

// имя пользователя для соединения с базой

private static String USER = "test";

// пароль для соединения с базой

private static String PASSWORD = "test";

public static Connection getConnection() throws ClassNotFoundException, DatabaseException {

Class.forName("com.mysql.jdbc.Driver"); // загружаем драйвер

try {

// создаем соединение: указываем строку соединения, имя и пароль

return DriverManager.getConnection(URL, USER, PASSWORD);

} catch (SQLException e) {

throw new DatabaseException(e);

}

}

public static void close(Connection con) {

try { con.close(); }

catch(SQLException e) { }

}

public static void close(Statement st){

try { st.close(); }

catch(SQLException e) { }

}

}

Класс DbUtil инкапсулирует логику получения соединения с базой, содержит метод getConnection, возвращающий объект-соединение и внутренние поля, хранящие параметры соединения. Таким образом, в остальных частях приложения логика получения соединения не дублируется и остальное приложение не имеет доступа к параметрам соединения.

Метод getConnection может выбросить исключение DatabaseException (исходный код исключения не приведен, это простой потомок Exception), которое проинформирует, что по некоторой причине соединение с базой установить не удалось. Приложение в таком случае может, например, предложить пользователю обратиться в службу поддержки.

В классе определены вспомогательные методы close для того, чтобы не дублировать каждый раз код обработки исключительной ситуации.

  1. Создадим отдельный класс StudentDAO, инкапсулирующий логику доступа к таблице STUDENT:

import java.util.*;

import java.sql.*;

public class StudentDAO {

// запрос для получения списка студентов

private static String GET_STUDENTS_SQL = "SELECT * from STUDENT";

public Collection<Student> getStudents()

throws ClassNotFoundException, DatabaseException {

// изначально список пуст

Collection<Student> students = new LinkedList<Student>();

Connection con = DbUtil.getConnection(); //получаем соединение

Statement st = null;

try {

st = con.createStatement(); // создаем объект-запрос

// выполняем запрос

ResultSet rs = st.executeQuery(GET_STUDENTS_SQL);

while (rs.next()) { // в цикле пополняем список студентов

Student student = new Student();

student.setId(rs.getInt("id"));

student.setFirstName(rs.getString("first_name"));

student.setLastName(rs.getString("last_name"));

students.add(student);

}

} catch (SQLException e) {

throw new DatabaseException(e);

} finally {

DbUtil.close(st);

DbUtil.close(con);

}

return students;

}

}

Класс StudentDAO инкапсулирует логику работы с базой данных для объектов класса Student.

Объект доступа к данным (Data Access Object, DAO) — общепринятый шаблон проектирования (паттерн): весь код взаимодействия с базой выносится в специализированный класс (в нашем случае StudentDAO), для передачи и хранения данных используется отдельный класс (в нашем случае Student). При этом реализация бизнес-логики приложения исключает непосредственный (без использования DAO) вызов методов низлежащих библиотек доступа к базам данных.

Это делается для того, чтобы упростить поддержку кода, если возникнет необходимость заменить библиотеку доступа к базе. Например, вместо использования JDBC может потребоваться использовать более функциональные надстройки над ней (например, Hibernate). Хотя обычно уже на стадии проектирования приложения известно, какие библиотеки будут использованы, вынесение логики работы с базой в отдельный слой все-таки полезно, так как это помогает быстрее ориентироваться в коде, позволяет сделать код бизнес-логики более «чистым», содержащим непосредственно бизнес-логику.

  1. Созданные классы можно использовать, например, в веб-приложении следующим образом:

//создаем объект StudentDAO

StudentDAO studentDAO = new StudentDAO();

// получаем список студентов

Collection<Student> students = studentDAO.getStudents();

for(Student student:students){

// что-то делаем

}