17.5. Объектно-реляционная проекция
В приведенном выше примере, для того, чтобы получить конкретный объект Student, соответсвующий строке таблицы STUDENT, нам требовалось сначала выполнить запрос, создать объект и выполнить его инициализацию. А для того, чтобы сохранить измененное состояние объекта, необходимо сначала создать запрос, заполнить соответсвующие параметры, запрос выполнить. Аналогичные действия требуются для работы с объектами Faculty, соответствующими сущности «факультет».
Усложнение модели предметной области (в контексте приложения) ведет к усложнению кода взаимодействия с базой данных. Сохранение состояния набора объектов в таблицах базы данных и наоборот, восстановление состояния набора объектов из записей в базе данных, с одной стороны, является достаточно однотипной задачей, с другой стороны, требует немалых трудозатрат. Эта задачу называют объектно-реляционной проекцией (Object-Relational Mapping, ORM).
На данный момент существуют ORM-решения (Hibernate, EJB и др.), которые позволяют абстрагироваться от понятия базы данных, настроив отображение между объектами и базой данных в конфигурационных файлах или иным способом, и оперировать исключительно моделью предметной области в Java (или другом языке).
Модель предметной области в базе данных и в Java, в общем случае, не имеют однозначного соответствия. Например, то, что студент слушает несколько курсов, в базе данных моделируется отдельной таблицей STUDENT_COURSE, а на стороне Java этот факт можно представить как коллекцию объектов Course, связанную с объектом Student.
В следующем небольшом примере показано, как с использованием библиотеки Hibernate настроить отображение класса Student на таблицу STUDENT в конфигурационном XML-файле, как получить объект по его идентификатору и как сохранить новый объект.
Конфигурационный файл Student.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping >
<class name="Student" table="STUDENT">
<id name="id" type="integer" column="id" unsaved-value="null">
<generator class="increment"/>
</id>
<property name="firstName" column="first_name" />
<property name="lastName" column="last_name"/>
</class>
</hibernate-mapping>
Получаем объект с идентификатором 1:
Integer id = 1;
Student student = (Student) session.get(Student.class, 1);
Здесь session — вспомогательный объект класса org.hibernate.Session из библиотеки Hibernate.
Сравним с JDBC-аналогом:
int id = 1;
PreparedStatement st = con.prepareStatement(
"SELECT * FROM STUDENT WHERE id=?");
st.setInt(1, id);
ResultSet rs =st.executeQuery();
if(rs.next()){
student = new Student();
student.setId(rs.getInt("id"));
student.setFirstName(rs.getString("first_name"));
student.setLastName(rs.getString("last_name"));
}
st.close();
Сохраняем объект:
session.save(student);
Сравним с JDBC-аналогом:
PreparedStatement st = con.prepareStatement(
"INSERT INTO STUDENT (id, first_name, last_name) VALUES (?,?,?)");
st.setInt(1, student.getId());
st.setString(2, student.getFirstName());
st.setString(3, student.getLastName());
st.executeUpdate();
st.close();
Объект, связанный с сессией Hibernate (посредством вызова метода save(), get() и др.) считается сохраненным (persistent), и в случае, если состояние его изменяется, оно автоматически синхронизируется с базой данных, т. е. явно вызывать метод update() не нужно. Это поведение установлено по умолчанию и его при необходимости можно изменить. Но благодаря такой реализации, понятие базы данных вытесняется, т. е. как говорилось выше, в Java-программе мы начинаем оперировать исключительно моделью предметной области.
Подробное изучение Hibernate выходит за рамки курса.
- Раздел 16. Многоуровневые и многослойные приложения. Шаблон проектирования Модель-Представление-Контроллер
- 16.1. Многоуровневые приложения
- 16.2. Многослойные приложения
- 16.3. Шаблон проектирования Модель-Представление-Контроллер
- 16.4. Реализация шаблона Модель-Представление-Контроллер в веб-приложениях
- Раздел 17. Базы данных в веб-приложениях
- 17.1. Основные понятия баз данных
- 17.2. Системы управления базами данных
- 17.3. Язык запросов sql
- Транзакции
- 17.4. Доступ к базам данных из Java
- Пример: база данных студентов
- Поддержка транзакций
- 17.5. Объектно-реляционная проекция
- Лекция 18. Безопасность Интернет-приложений
- 18.1. Аутентификация и авторизация
- 18.2. Понятие безопасности Интернет-приложений
- 18.3. Классы атак сетевого уровня Сниффинг пакетов
- Подмена ip-адреса
- Отказ в обслуживании
- Сетевая разведка
- 18.4. Криптографические технологии
- 18.5. Уязвимости уровня приложений
- Уязвимости системы аутентификации
- Уязвимости системы авторизации
- Атаки на стороне клиента
- Выполнение кода на сервере
- Разглашение информации
- Злоупотребление функциональными возможностями
- Наиболее распространенные уязвимости
- 18.6. Резюме