Работа с базами данных с использованием JDBC и Hibernate.
Настройка среды 💪
📣 Перед началом убедитесь, что вы выполнили следующее:
- Сервер базы данных (XAMPP, WAMP, MySQL и т. Д.)
- Файлы Hibernate JAR (и их зависимости) и драйвер JDBC.
Если вы используете maven, добавьте зависимости драйвера гибернации и JDBC (в нашем примере это MySQL) в файл «pom.xml».
<!-- Hibernate --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.1.7.Final</version> </dependency> <!-- MySQL --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.40</version> </dependency>
Когда вы закончите, создайте таблицу users и сгенерируйте фальшивые данные для тестирования.
CREATE TABLE `users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(60) NOT NULL, `email` varchar(255) NOT NULL, PRIMARY KEY (`id`) )
JDBC
Модуль Spring JDBC заботится обо всех низкоуровневых деталях, начиная с открытия соединения, подготовки и выполнения оператора SQL, обработки исключений, обработки транзакций и, наконец, закрытия соединения.
Все, что нам нужно сделать, это просто определить параметры подключения и указать SQL-оператор, который нужно выполнить.
Но, прежде чем использовать модули доступа к данным Spring, давайте посмотрим, как мы можем сделать простой старый JDBC.
Базовое соединение JDBC
Есть 5 основных шагов для подключения и получения данных из базы данных.
Итак, во-первых, вам необходимо зарегистрировать драйвер JDBC, чтобы файл класса драйвера был загружен и его можно было использовать в качестве реализации интерфейсов JDBC.
Затем мы устанавливаем соединение, предоставляя URL-адрес подключения, имя пользователя и пароль.
💡 URL-адрес базы данных - это адрес, указывающий на вашу базу данных. В нашем примере
localhost
- это имя хоста, аdemoDB
- имя базы данных. У разных драйверов JDBC разные соответствующие URL-адреса.
После этого мы создаем объект типа Statement для выполнения оператора SQL и возврата набора результатов.
Соединение JDBC в Spring MVC
Базовое представление о том, как установить соединение JDBC в Java, необходимо для создания веб-приложения в Spring, которое подключается к базе данных.
Но сначала давайте посмотрим, как мы можем структурировать наше приложение.
- Структура
- Уровень доступа к данным (DAO): обычно используется для взаимодействия с базой данных. Они должны предоставлять эту функциональность через интерфейс, через который остальная часть приложения будет получать к ним доступ. Поддержка DAO в Spring упрощает работу с такими технологиями доступа к данным, как JDBC, Hibernate и т. Д.
- Шаблон JDBC: шаблон JDBC выполняет запросы SQL, обновляет операторы, сохраняет процедуры и т. д. Он также перехватывает исключения JDBC.
- Картографы: они сопоставляют данные строк в таблице и объекты Java. В случае ORM, таких как Hibernate, отображение выполняется с использованием
@Column
в поле объекта (будет рассмотрено позже). - Сущности: они представляют таблицы базы данных. Каждая запись в таблице представляет объект сущности. Итак, поля объектов сущности представляют собой столбцы таблицы.
- Шаблон JDBC и DAO
JDBC, в свою очередь, реализует интерфейс DAO для предоставления фактического кода реализации. Хотя это не обязательно, вы можете напрямую написать код реализации в классе DAO, но это не очень хорошая практика.
- Шаблон и источник данных JDBC (например, соединение)
Обычная практика использования шаблона JDBC заключается в следующем:
- Настройте bean-компонент DataSource в конфигурации Spring.
- Внедрение зависимости, что bean-компонент DataSource в классе реализует DAO.
- Создайте новый экземпляр JdbcTemplate в установщике для DataSource.
JDBC - Процесс
[1] Создание объектов и их картографов
[2] Создание интерфейсов DAO
Перечислите все методы взаимодействия с базой данных.
[3] Создать класс реализации JDBC
Далее идет класс реализации интерфейсов DAO.
💡 Класс реализации JDBC имеет экземпляр JdbcTemplate, который создается с помощью объекта DataSource (в качестве зависимости) для выполнения работы.
💡 Вы можете либо внедрить объект DataSource, используя конфигурации XML (Setter Injection), либо используя аннотацию (Field Injection).
💡 В случае использования аннотации для внедрения источника данных. Используйте аннотацию
@Autowired
в полеjdbcTemplate
и удалите методsetDataSource()
(также из UserDAO).
Компонент DataSource будет внедрен в компонент шаблона JDBC в XML (см. Далее).
[4] Определить конфигурации
Определите конфигурации для класса реализации DataSoruce и JDBC.
💡 В случае использования аннотации для внедрения источника данных.
[5] Работа с классом реализации JDBC в контроллерах
Чтобы использовать класс UserDAOJDBCImpl в нашем контроллере, нам нужно внедрить его в наш контроллер как зависимость, которая может быть подключена автоматически.
⚠ Класс UserDAOJDBCImpl должен быть определен как bean-компонент, чтобы его можно было внедрить.
Затем мы можем использовать его для вызова методов, которые будут взаимодействовать с базой данных и возвращать результат.
Наконец, вы можете создать объект модели на основе возвращенных данных, чтобы его можно было отображать на страницах просмотра.
[6] Страницы просмотра
Одна страница для отображения всех пользователей, а другая - для создания нового пользователя с помощью HTML-формы.
Спящий режим
Hibernate - это структура ORM, которая сопоставляет объекты Java и записи базы данных. Он действует как промежуточный уровень между кодом нашего приложения и базой данных.
Он обрабатывает низкоуровневый код SQL, минимизирует объем кода JDBC и обеспечивает объектно-реляционное сопоставление (ORM). Фактически, Hibernate использует JDBC в фоновом режиме для связи с базой данных. Итак, это просто уровень абстракции поверх JDBC.
Все, что нам нужно сделать, - это сообщить Hibernate, как наш объект Java отображается в таблице базы данных. Это делается внутри класса объекта (или в конфигурации XML). Затем Hibernate получит, сохранит, обновит или удалит этот объект в таблице на основе заданных нами сопоставлений.
Быстрые примеры того, как Hibernate делает его намного проще… 🏃
// Saving an object User newUser = new User(“John”, “Doe”, “myemail.com”); // “session” is a special Hibernate object int thePrimaryId = (Integer) session.save(newUser); // Retrieve an object User user = session.get(User.class, thePrimaryId); // Quering object // We pass what’s called “Hibernate Query Language” (will be discussed later) Query query = session.createQuery(“from user”); List<User> usersList = query.list();
Гибернация - Процесс
[1] Файл конфигурации Hibernate.
Он сообщает спящему режиму, как подключиться к базе данных, которая является конфигурацией JDBC, поскольку она использует JDBC для подключения к базе данных. Итак, создайте файл «hibernate.cfg.xml» в папке «src».
В этом файле есть следующее:
[1] Session Factory
Он считывает файл конфигурации гибернации, устанавливает соединение с базой данных,
и создает объекты сеанса, которые создаются один раз во время работы приложения.
💡 Сеанс - это оболочка для соединения JDBC. Это основной объект для сохранения и извлечения объектов в базу данных.
Это недолговечный объект, поэтому для данного метода вы используете сеанс, а затем отбрасываете его и т. Д. Он создается и извлекается из Session Factory.
[2] Настройки подключения к базе данных JDBC: это настройки для подключений JDBC, такие как драйвер JDBC, URL-адрес подключения, имя пользователя и пароль.
[3] Пул подключений: для простоты оставьте пока 1. Это максимальное количество подключений в пуле подключений.
💡 Hibernate использует пул соединений для подключения к базе данных.
Hibernate предоставляет внутренний диспетчер соединений, который находится в зачаточном состоянии. Для максимальной производительности и стабильности используйте сторонний инструмент (сделаю это позже).
[4] Диалект SQL: это диалект SQL, который использует ваша база данных. Таким образом, он сообщает Hibernate сгенерировать соответствующие операторы SQL для выбранной базы данных.
[5] Показать SQL: чтобы распечатать SQL, используемый для связи с базой данных.
[6] Контекст сеанса: контекст по умолчанию - thread
, что означает, что фабрика сеансов привяжет сеанс к потоку, из которого вызывается openSession()
.
Это полезно, потому что позже вы можете вызвать sessionFactory.getCurrentSession()
, который вернет сеанс, связанный с текущим запущенным потоком.
[2] Аннотирование классов Java (сущностей)
Сущность - это простой Java-класс, сопоставленный с таблицей базы данных. Мы используем аннотации для сопоставления. Это то, что называется объектно-реляционным отображением (ORM).
💡 Существует еще один способ определения сопоставлений с использованием файла конфигурации XML, это старый способ.
Итак, сначала сопоставьте класс с таблицей базы данных. Затем сопоставьте поля со столбцами таблицы базы данных.
⚠ Не забудьте определить конструкторы, геттеры и сеттеры.
[3] Настройка фабрики сеансов и создание объекта сеанса
Фабрика сеанса для создания объекта сеанса, который, в свою очередь, будет использоваться для взаимодействия с базой данных.
Сначала мы загружаем файл конфигурации, имя файла конфигурации по умолчанию - «hibernate.cfg.xml». Затем класс (классы), которые нужно сканировать для сопоставления, и мы создаем объект сеанса.
Наконец, закройте заводскую сессию. Он уничтожает SessionFactory и освобождает все ресурсы (кеши, пулы соединений и т. Д.).
[4] Начать транзакцию
В Hibernate вы всегда используете транзакцию базы данных при взаимодействии с базой данных. Независимо от того, является ли это операцией создания, чтения, обновления или удаления. Транзакции с базой данных никогда не являются необязательными в Hibernate.
// start a transaction session.beginTransaction(); // database operations // ... We can wrap a set of queries inside a transaction // commit transaction session.getTransaction().commit();
Оператор commit()
указывает конец транзакции и фиксирует изменения в базе данных. Никакие изменения не будут применены к базе данных, пока транзакция не будет зафиксирована.
После подтверждения транзакции вы больше не можете использовать объект сеанса. Вам необходимо повторно назначить объект сеанса, чтобы получить новый сеанс, и снова начать транзакцию.
session = factory.getCurrentSession();
[4] Сохранить (создать) объект в базу данных
Для каждой операции не забывайте получать новый объект сеанса с помощью factory.getCurrentSession()
, запускать транзакцию и фиксировать.
// create a user object User newUser = new User(125, "Alex", "[email protected]"); // save the user object session.save(newUser);
[5] Чтение объектов
// retrieve student based on the id: primary key User user = session.get(User.class, newUser.getId());
В Hibernate есть язык запросов под названием HQL, который используется для запросов к базе данных. В HQL мы используем имя класса и имена свойств вместо имен таблиц и столбцов.
// "User" is the name of the class List<User> users = session.createQuery("from User").list(); // "u" is an alias that maps to the actual java object (user), // where u.name is a property of user object List<User> users = session.createQuery("from User AS u where u.name='Alex'").list();
⚠ В Hibernate 5.2 или более поздних версиях метод Query
list()
устарел, используйте вместо негоgetResultList()
.
[6] Обновление объектов
Мы можем обновить объект пользователя с помощью сеттеров.
💡 Поскольку постоянный экземпляр объекта пользователя возвращается методом
get()
(после извлечения из таблицы), обновление значения поля этого объекта пользователя также отразится на значениях таблицы.
// retrieve user based on the id: primary key int userId = 125; User user = session.get(User.class, userId); // update name to "Max" user.setName("Max");
Или мы можем написать запрос для обновления конкретного пользователя (ей).
session.createQuery("update User set name='Max' WHERE id=125").executeUpdate();
[7] Удаление объектов
Здесь применима та же идея, что и в обновлении; Мы можем либо удалить постоянный экземпляр объекта пользователя, возвращаемого методом get()
, либо написать и выполнить запрос для этого.
// retrieve user based on the id: primary key int userId = 125; User user = session.get(User.class, userId); // delete the student session.delete(user); // delete user id=125 (using query) session.createQuery("delete from User WHERE id=125").executeUpdate();
Спасибо за чтение! Если вам понравилось, пожалуйста, похлопайте 👏 в ладоши.