JavaRush /Java блог /Random UA /SpringBoot + Flyway - "Java-проект від А до Я"
Roman Beekeeper
35 рівень

SpringBoot + Flyway - "Java-проект від А до Я"

Стаття з групи Random UA
Стаття із серії про створення Java-проекту (посилання на інші матеріали – наприкінці). Її мета — аналіз ключових технологій, результат — написання телеграм-бота. У цій частині пробуємо запустити SpringBoot і до нього – Flyway. Мінімальна кількість теорії, як ви любите))) Підсумкове порівняння Flyway/Liquibase опускаємо на невизначений час і переходимо до суті. А то й так він уже затягнувся. Щоб двічі не описувати Flyway, вирішив його одразу додавати до нашого майбутнього проекту JRTB."Java-проект від А до Я": SpringBoot + Flyway - 1

Що в рамках цього потрібно зробити?

  1. Запустити SpringBoot додаток на базі Maven.
  2. Додати туди Flyway: добре, що вони легко інтегруються.
  3. Додати схему таблиць, які у нас у прикладі бази даних.
Таким чином ми навчимося працювати з Flyway. Чому окремим проектом, а не одразу в наш JRTB? Тому що пізніше будь-хто, хто захоче зрозуміти, як це зробити, матиме проект із прикладом та статтю, яка описує роботу з нею. Ну, що ж, поїхали!

Що таке flyway

Щоб щось використати, потрібно спочатку з'ясувати, що це таке і навіщо. Flyway — інструмент для контролю версії бази даних. Слова відомі, але якось розуміння не додалося, так? Спробуємо описати проблему, яку вирішує flyway. Допустимо, у нас є проект. Як і все у нашому світі, він не досконалий, тому спланувати та скласти остаточну версію проекту не вийшло. Щоразу з'являються ті чи інші невраховані нюанси. Проект у своїй роботі використовує БД. Зрозуміло, за зміни проекту може змінитися і структура бази даних. Допустимо, ми додаємо нове поле для однієї з сутностей нашого проекту. Як це зробити?
  1. Додати це поле до нашої сутності, оновити все, щоб бізнес логіка працювала.
  2. Оновити базу даних. Єдиний можливий спосіб зробити це вручну. Для цього потрібно зайти та прописати необхідний SQL скрипт.
З другого пункту виникає багато питань:
  1. а якщо у нас не одне місце, де ми розгортаємо наш проект, то це у кожному з них треба робити?
  2. а якщо ми захочемо повернутися назад, як ми дізнаємося, в якому стані зараз знаходиться структура БД?
  3. як ми будемо впевнені, що зміна БД пройшла успішно?
  4. Як отримати можливість відстежити всі зміни БД, які пройшли на проекті?
Якщо робити руками, то відповіді будуть не найкращі. Щоб уникнути всіх цих труднощів, можна скористатися інструментом для міграції БД. Одним із таких і є Flyway. У чому полягає його робота? У рамках проекту ми зберігаємо окремі SQL файли (так звані міграції), які зберігають у собі все те, що ми робимо з БД за один раз. Всі міграції йдуть строго в певному порядку, що дозволяє відстежити зміни в структурі та даних БД (часто за допомогою міграції додають тестові дані до проекту, щоб при розгортанні його на якийсь сервер він уже мав якісь значення, за допомогою яких можна тестувати проект). Після того, як пройдуть тести, під час складання проекту запускаються міграції. Вони з'єднуються з базою даних та проводять міграції. Якщо міграції вже були проведені на цій базі даних, то flyway їх просто пропустить (у нього в БД в окремій таблиці зберігаються дані про міграції, про їхній стан, що допомагає керувати ними), а якщо якась міграція пройшла неуспішно, то складання проекту та його монтування (деплою) на сервер зупиняться. Я постарався описати якнайдокладніше. Якщо все ще не до кінця зрозуміло — не біда: на практиці прийде і розуміння.

Запускаємо SpringBoot + Flyway

Що таке Spring Boot

А що ж таке запускаємо? Щоб зрозуміти, що і навіщо ми робимо, потрібно визначитися з тим, що таке SpringBoot. Спочатку швидко поговоримо (ну дуже швидко) про Spring . На даний момент це де-факто промисловий стандарт у розробці серверних програм на Java. Стандарт чого? Як вам це пояснити. Spring - це скелет програми, на який ми потім накидаємо "м'ясо" - нашу бізнес-логіку. За допомогою спрингу (тут і далі використовуватиму цю кальку, щоб не витрачати час на перемикання мови :D )) Спрінг дає нам старт, з якого ми починаємо все робити. Він багатоликий багатомодульний:
  1. Хочеш працювати з базою даних? Хочеш із реляційною? Хочеш із нереляційною? Ось, будь ласка, у нас є Spring Data.
  2. Хочеш працювати з http запитами? Ось тобі, будь ласка, Spring Web (Spring MVC).
  3. Тобі потрібний контейнер для всіх об'єктів в одному місці? Ось Spring Core.
  4. Потрібно налаштувати безпеку на проекті та так, щоб були різні ролі та субординація? Spring Security.
  5. Ти тільки подумав про те, що добре мати таку штуку, так виявиться, що у Спрінга вже є те, що тобі потрібно, і воно швидко і легко інтегрується.
Тому можна сказати, що це не просто фреймворк (така велика бібліотека), а вже ціла екосистема, яка розвивається шаленими темпами. Щоб зрозуміти, що являє собою Spring Core, тобто база, до якої підключаються модулі, раджу подивитися живе демо зі створення власного фреймворку. Веде його Євген Борисов, дуже крутий чувак в області Java та спрингу. Виконайте все те, що він зробив, і робота спрингу вам стане більш зрозумілою. SpringBoot, у свою чергу, це вершина всього того, що у них є. Магія чистої води. Мінімум налаштувань для того, щоб зробити перший запуск програми. Зрозуміло, це не дасть вам розуміння, як ним користуватися та що потрібно робити. Але перед тим, як кидатися в глибину розробки, потрібно подивитися на все з висоти пташиного польоту.

Запускаємо SpringBoot

Оскільки ми вже зналися на тому, що таке мавен, давайте створимо новий проект для наших потреб. Для цього просто потрібно перейти на сайт, спеціально створений для цієї справи. Називається він Spring Initializr . "Java-проект від А до Я": SpringBoot + Flyway - 2Тут потрібно заповнити та вибрати необхідне:
  1. Інструмент зі збирання проекту - gradle або maven. Як бачите, про Ant вже й не згадують. Це хороша підказка про те, яким засобам складання варто приділити час.
  2. Мова, якою можна писати - java, kotlin, groovy. Тут все просто: всі вони JVM подібні та спокійно запускають Java код. До речі, варто подивитись і на Котлін. Груві вже відверто став нецікавим (був час, коли на груві переходабо, але він швидко пройшов).
  3. Версію спрингу… Тут треба розуміти, що версії головної частини спрингу та його модулів узгоджені.
  4. Дані щодо проекту. Я вже описував ці речі.
  5. Вибираємо, в який архів буде збиратися - Jar чи War.
  6. Ну і версію джави нашої коханої. А то останнім часом розлучилося цих версій... багато) То чекали роками, а тепер по дві на рік.
У нашому випадку будемо публікувати цей проект в організації JavaRush Community , тому дані про проект будуть відповідні:
  1. Maven - не дарма ж ми говорабо з вами про це раніше.
  2. Java - наша рідна :D
  3. Версію візьмемо 2.2.11. Чому не найновішу? Тому що чим новіший, тим більше шансів, що там можуть бути якісь косяки. Для нас не принципово, яка саме версія, а більш стара буде надійнішою. Тому обираємо 2.2.11.
  4. Group: com.github.codegymcommunity
  5. Artifact: springboot-flyway-demo
  6. Name: SpringBoot + Flyway Demo
  7. Description: Project demonstrates integration між SpringBoot and Flyway . (Так, вміння писати документацію – це важлива частина розробки:))
  8. Package name: com.github.codegymcommunity.springbootflywaydemo . Тут за нас відразу ж створять базовий пакет із класом, який запустить наш додаток.
  9. Packaging: Jar
  10. Java: 8. Не будемо йти попереду паровоза і візьмемо стару добру вісімку. Чому не 11? А навіщо? Для нашого прикладу не бачу сенсу.
"Java-проект від А до Я": SpringBoot + Flyway - 3А тепер додамо модулі. Нам потрібно знайти інтеграцію із Flyway. Можна ще додати щось пов'язане з MySQL та Spring Data. Додамо ще ломбок (це дуже потрібна річ, просто повірте поки що :D)) Для цієї справи натискаємо на ADD DEPENDENCIES … і виберемо все, що потрібно: "Java-проект від А до Я": SpringBoot + Flyway - 4Ось так додамо Flyway. "Java-проект від А до Я": SpringBoot + Flyway - 5Ломбок... І так далі. У підсумку отримаємо: "Java-проект від А до Я": SpringBoot + Flyway - 6Хух… заповнабо все)) Тепер тиснемо GENERATE… і все — архів зі згенерованим проектом готовий:) Там ще є така крута штука як SHARE… , яка дає вам посилання на сторінку, яку ви щойно заповнабо. Тобто ось та, яку я генерував. І навіть якщо у вас щось піде не так, завжди можна буде перевірити на засланні. Далі нам потрібно прив'язати створений проект до репозиторію гіт, тому клонуємо створений проект springboot-flyway-demo і качаємо його через IDEA. Для цього потрібно відкрити ідею і вибрати File -> New -> Project from Existing Sources… : "Java-проект від А до Я": SpringBoot + Flyway - 7Тепер додаємо URL і натискаємо Clone . Наступним кроком потрібно перенести нутрощі згенерованого проекту всередину того, що ми клонували. Заплутав? Зараз покажу. Розархівував і отримав такий набір файлів: "Java-проект від А до Я": SpringBoot + Flyway - 8Ось їх потрібно перенести в клонований проект. Як і в минулій статті, додамо pom.xml як проект:"Java-проект від А до Я": SpringBoot + Flyway - 9Тепер нам цікаво подивитися, що нам згенерували. Якщо відкрити всі папки в src і далі, то буде видно звичайну ієрархію в рамках проектів, яку ми розбирали в попередній статті . Хто не читав – почитайте! "Java-проект від А до Я": SpringBoot + Flyway - 10Видно, що у нас є Application клас, і за допомогою нього запуститься наш SpringBoot додаток. Завдяки плагіну в мавені для SpringBoot, у нас з'явився потрібний нам таск для мавену, а саме spring-boot:run. Де ми можемо знайти цю інформацію? Праворуч, відкривши плашку Maven і наш проект: "Java-проект від А до Я": SpringBoot + Flyway - 11Буде помилка, і її так ми не зможемо прочитати, побачимо щось таке: "Java-проект від А до Я": SpringBoot + Flyway - 12Щоб отримати більше інформації, для швидкості ми можемо запустити main метод Application класі: "Java-проект від А до Я": SpringBoot + Flyway - 13І тоді вже побачимо реальну причину:"Java-проект від А до Я": SpringBoot + Flyway - 14Тут уже інформації більше і можна з нею щось робити. Що не так? У нас є залежності, пов'язані з БД, і тому потрібно надати налаштування для підключення до неї. Для цієї справи гугли, знаходимо, що потрібно додати наступні конфігурації в application.properties:
spring.datasource.url=jdbc:mysql://localhost:3306/flyway_demo_db
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
Запускаємо ще раз main метод і отримуємо: "Java-проект від А до Я": SpringBoot + Flyway - 15Тепер потрібно додати хоча б одну міграцію. Щоб правильно скласти міграцію, потрібно взяти наступний шаблон: V<VERSION>__<NAME>.sql Керуючись ним, створимо файл міграції з ім'ям V00001__Create_country_table.sql у відповідній папці: /src/main/resources/db.migration/ . У ньому створимо таблицю country. Скрипт візьмемо з другої статті про БД . "Java-проект від А до Я": SpringBoot + Flyway - 16Перед запуском зайдемо та створимо БД для роботи: flyway_demo_db. Зробимо це через MysqlWorkbench: "Java-проект від А до Я": SpringBoot + Flyway - 17Тепер можна запустити ще раз main метод: "Java-проект від А до Я": SpringBoot + Flyway - 18Все вийшло, але так як у нас нічого ще немає в проекті, він закінчив роботу. Однак видно з логів (що таке логи — ось почитайте), що:
  1. Успішно підключабося до БД.
  2. Пройшла валідація міграції і з нею все прибл.
  3. Flyway створив таблицю для керування міграціями.
  4. І те, що розпочала міграція 00001 — створення country пройшло успішно.
Щоб це перевірити, можна сходити і подивитися, що робиться у БД. Так що зайдемо на наш MySQL сервер і подивимося, що там із таблицями в бд flyway_demo_db: $USE flyway_demo_db; $ SHOW TABLES; "Java-проект від А до Я": SpringBoot + Flyway - 19Як і очікував, пройшла міграція, під час якої створилася таблиця country і з'явилася таблиця flyway_schema_history, яка зберігає інформацію про міграціям. Підемо далі і подивимося які там є записи (і чи взагалі вони є). $SELECT * FROM flyway_schema_history; "Java-проект від А до Я": SpringBoot + Flyway - 20Ось і запис, один-єдиний. У ній багато цікавих даних. Версія, опис міграції, який тип SQL (і, можливо, ще XML), ім'я самого скрипта, чексума (це щось типу hashcode, з якого перевіряється, змінилася чи ні міграція. Робиться це на випадок, якщо ми провели міграцію в БД і потім її поправабо: робити цього не можна, всі редагування вносяться тільки за допомогою нової міграції і щоб цього не було, чек сума стежить за цим), ім'я sql користувача, дата обробки міграції, час на виконання та результат (успішно чи не успішно). Міграція, написана один раз, не повинна бути змінена у майбутньому. Навіть якщо у ній є дефект. Усі зміни відбуваються лише за допомогою нової міграції. Це дуже важливо. Щоб показати, що буде, давайте трохи змінимо наш скрипт і спробуємо запустити його знову. Додамо до нашої міграції один запис у таблицю country: "Java-проект від А до Я": SpringBoot + Flyway - 21і запустимо main метод і ось що отримаємо:"Java-проект від А до Я": SpringBoot + Flyway - 22Як я і очікував, flyway розпізнав, що скрипт був змінений і не провів міграцію. У деяких випадках дійсно буває необхідно запустити оновлену міграцію і щоб flyway це пропустив, потрібно видалити запис у таблиці flyway_schema_history і вже після цього накотити оновлену міграцію. Це не нормальна поведінка і так не має бути, але знати про такий спосіб вирішення проблеми також потрібно. Розібралися з першою міграцією. Тепер хотілося б додати ще одну міграцію, з даними про країни, як було у статті про БД: файл V00002__Add_test_data_to_country.sql"Java-проект від А до Я": SpringBoot + Flyway - 23 І знову запустимо main метод:"Java-проект від А до Я": SpringBoot + Flyway - 24З логів видно, що перед запуском міграції БД була у версії 00001, тому запустяться всі міграції після цієї версії. Далі запустилася версія 00002 і пройшла успішно. Перевіримо, чи вже вірите мені, що три записи в country будуть вже перебувають у БД?)) Я б перевірив, тому пруф: "Java-проект від А до Я": SpringBoot + Flyway - 25Ось якось так. Якщо запустити ще раз проект, то flyway просто пропустить накочування міграцій, оскільки база даних повністю відповідає потрібній версії.

Висновок

Цього разу ми навчабося сяк-так розуміти і використовувати інструмент для міграції БД у зв'язці зі SpringBoot. Ця інформація потрібна для розуміння того, що таке інструмент контролю версій баз даних на прикладі Flyway. Друзі, вихідники проекту, який я показав, опубліковані в нашій організації на гітхабі . Якщо вам подобається приклад, ставте йому зірку , і я розумітиму, що моя робота корисна і її реально варто продовжувати. Традиційно пропоную підписатися на мій гітхаб акаунт. Через нього я веду всю свою роботу з open source і всі ті демо-проекти, які незмінно супроводжують мої статті. Дякую всім за прочитання. Наступного разу вже писатимемо наш додаток. Буде ще в майбутньому необхідна теорія з докеру, але ми її розбавимо практикою.

Корисні посилання

Сьогодні не так вже й багато корисних посилань. Зверніть увагу на відео Євгена, воно дійсно варте того!
  1. Сайт для створення проектів на спрингу
  2. Євген Борисов - Spring-будівельник
  3. Документація у спрингу по Flyway

Список всіх матеріалів серії на початку цієї статті.

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ