Работа с базами данных с использованием JDBC и Hibernate.

Настройка среды 💪

📣 Перед началом убедитесь, что вы выполнили следующее:

  1. Сервер базы данных (XAMPP, WAMP, MySQL и т. Д.)
  2. Файлы 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 заключается в следующем:

  1. Настройте bean-компонент DataSource в конфигурации Spring.
  2. Внедрение зависимости, что bean-компонент DataSource в классе реализует DAO.
  3. Создайте новый экземпляр 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();

Спасибо за чтение! Если вам понравилось, пожалуйста, похлопайте 👏 в ладоши.