Помните проект из третьего модуля по фронтенду, где нужно было реализовать админку для rpg для серверного API? Если кто помнит – там на сервере в качестве хранилища использовалась мапа. Естественно, в реальной жизни такие хранилища не используют, а используют базы данных. Целью этого проекта будет написать альтернативную реализацию слоя репозитория с использованием Hibernate.

Для этого нужно:

  1. Сделать fork из репозитория
  2. Скачать свою версию проекта к себе на компьютер.
  3. Добавить зависимости в pom.xml:
    • mysql: mysql-connector-java: 8.0.30
    • org.hibernate: hibernate-core-jakarta: 5.6.11.Final
  4. Сделать maven билд (mvn clean install). Для разнообразия используем Java версии 1.8.
  5. Добавить конфигурацию запуска через Идею. Реализацию этого пункта можно посмотреть в лекции https://javarush.com/quests/lectures/jru.module3.lecture02 (пункт 4). Единственное отличие – другое название артефакта. Если все сделал правильно и запустил приложение – увидишь примерно такую картину:
  6. В Workbench выполнить скрипт создания схемы rpg:
    CREATE SCHEMA `rpg` ;
    
  7. Опционально. Если хочешь посмотреть какое ожидается поведение, можешь в классе com.game.service.PlayerService в параметре конструктора значение аннотации @Qualifier изменить с «db» на «memory». В этом случае Spring будет использовать в качестве реализации интерфейса IPlayerRepository класс PlayerRepositoryMemory. После теста не забудь изменить значение аннотации @Qualifier обратно на «db».
  8. Расставить все необходимые аннотации в ентити-классе com.game.entity.Player. Таблица должна называться «player», схема «rpg». Для енамов используй @Enumerated(EnumType.ORDINAL) кроме аннотации @Column. Напомню, что длина поля name должна быть до 12 символов, поля title – до 30 символов. Абсолютно все поля не должны быть null.
  9. В классе PlayerRepositoryDB добавь private final поле SessionFactory sessionFactory, в конструкторе класса инициализируй это поле. Проперти используй как в обычных задачах (работать будем с БД MySQL версии 8). Из интересного – добавь
    properties.put(Environment.HBM2DDL_AUTO, "update");
    
    Это позволит не создавать таблицу вручную (или через выполнения sql скрипта).
  10. Реализуй все методы класса. Для разнообразия давай поступим так:
    • Метод getAll реализуй через NativeQuery — этот метод должен получать всех игроков  с учетов параметров: pageNumber - номер страницы, pageSize - количество записей на страницу
    • Метод getAllCount реализуй через NamedQuery. Должен возвращать общее количество игроков в базе данных.
    • В методе beforeStop вызови у sessionFactory метод close. За счет наличия аннотации над методом @PreDestroy, Spring вызовет этот метод перед остановкой приложения, и это позволит валидно освободить все ресурсы системы.
    • Реализация остальных методов на твое усмотрение. Но не забывай о транзакциях и коммитах для методов, которые как либо изменяют содержимое БД.
  11. Запусти приложение. Если все сделал правильно – ты получишь рабочее приложение. Вот только данных там никаких нет, так что выполни через Workbench скрипт init.sql (из ресурсов), чтоб они появились. После этого в браузере нажми F5 и проверяй, что все методы ты реализовал правильно.
  12. Было бы интересно посмотреть, какие именно запросы выполняет Hibernate, поэтому добавим логирование запросов. Для этого добавь в pom.xml зависимость p6spy:p6spy:3.9.1. В папке ресурсов создай файл spy.properties, в котором укажи:
    driverlist=com.mysql.cj.jdbc.Driver
    dateformat=yyyy-MM-dd hh:mm:ss a
    appender=com.p6spy.engine.spy.appender.StdoutLogger
    logMessageFormat=com.p6spy.engine.spy.appender.MultiLineFormat
    
    И в конструкторе класса PlayerRepositoryDB измени две опции:
    properties.put(Environment.DRIVER, "com.p6spy.engine.spy.P6SpyDriver");
    properties.put(Environment.URL, "jdbc:p6spy:mysql://localhost:3306/rpg");
    
    Теперь в выводе сервера по каждому запросу ты будешь видеть 2 строки. Первая – какой стейтмент подготовлен, второй – запрос с вставленными параметрами.

Вот и все, проект готов, поздравляю тебя!

На самом деле, для работы с Hibernate из Spring используется другой подход, о котором мы расскажем в пятом модуле.


Разбор проекта.