Статья из серии о создании Java-проекта (ссылки на другие материалы — в конце). Ее цель — разбор ключевых технологий, итог — написание телеграм-бота. В этой части пробуем запустить SpringBoot и к нему — Flyway.
Минимальное количество теории, как вы любите)))
Итоговое сравнение Flyway/Liquibase опускаем на неопределенное время и переходим к сути. А то и так уже он затянулся. Чтобы дважды не описывать Flyway, решил его сразу добавлять в наш будущий проект JRTB.!["Java-проект от А до Я": SpringBoot + Flyway - 1]()
многоликий многомодульный:
Здесь нужно заполнить и выбрать необходимое:
А теперь добавим модули. Нам нужно найти интеграцию с Flyway. Можно еще добавить что-то связанное с MySQL и Spring Data. Добавим еще ломбок (это очень нужная вещь, просто поверьте пока что :D))
Для этого дела нажимаем на ADD DEPENDENCIES… и выберем все, что нужно:
Вот так добавим Flyway.
Ломбок…
И так далее. В итоге получим:
Хух… заполнили все))
Теперь жмем GENERATE… и все — архив со сгенерированным проектом готов :)
Там еще есть такая крутая штука как SHARE…, которая дает вам ссылку на страницу, которую вы только что заполнили. То есть, вот та, которую я генерировал. И даже если у вас что-то пойдет не так, всегда можно будет проверить по ссылке.
Далее нам нужно привязать созданный проект к гит репозиторию, поэтому клонируем созданный проект springboot-flyway-demo и качаем его через IDEA.
Для этого, нужно открыть идею и выбрать File -> New -> Project from Existing Sources…:
Теперь добавляем URL и нажимаем Clone.
Следующим шагом нужно перенести внутренности сгенерированного проекта внутрь того, что мы клонировали. Запутал? Сейчас покажу.
Разархивировал и получил такой набор файлов:
Вот их и нужно перенести в клонированный проект.
Как и в прошлой статье, добавим pom.xml как мавен проект:
Теперь нам интересно посмотреть на то, что нам сгенерировали.
Если открыть все папки в src и далее, то будет видна обычная иерархия в мавен проектов, которую мы разбирали в предыдущей статье. Кто не читал — почитайте!
Видно, что у нас есть Application класс, и при помощи него запустится наше SpringBoot приложение.
Благодаря плагину в мавене для SpringBoot, у нас появился нужный нам таск для мавена, а именно — spring-boot:run. Где мы можем найти эту информацию?
Справа, открыв плашку Maven и наш проект:
Будет ошибка, и ее так мы не сможем прочесть, увидим что-то такое:
Чтобы получить больше информации, для быстроты мы можем запустить main метод Application классе:
И тогда уже увидим реальную причину:
Здесь уже информации поболее и можно с ней что-то делать. Что не так? У нас есть зависимости, связанные с БД, и поэтому нужно предоставить настройки для подключения к оной.
Для этого дела гуглим, находим, что нужно добавить следующие конфигурации в application.properties:
Теперь нужно добавить хотя бы одну миграцию. Чтобы правильно составить миграцию, нужно взять следующий шаблон: V<VERSION>__<NAME>.sql
Руководствуясь им, создадим файл миграции с именем V00001__Create_country_table.sql в соответствующей папке: /src/main/resources/db.migration/.
В ней создадим таблицу country. Скрипт возьмем из второй статьи о БД.
Перед запуском зайдем и создадим БД для работы: flyway_demo_db. Сделаем это через MysqlWorkbench:
Теперь-то можно запустить еще раз main метод:
Все получилось, но так как у нас ничего еще нет в проекте, он закончил работу. Однако видно из логов (что такое логи — вот почитайте), что:
Как я и ожидал, прошла миграция, в ходе которой создалась таблица country и появилась таблица flyway_schema_history, которая хранит информацию по миграциям. Пойдем дальше и посмотрим какие там есть записи (и есть ли вообще они).
$ SELECT * FROM flyway_schema_history;
Вот и запись, одна-единственная. В ней — много интересных данных. Версия, описание миграции, какой тип SQL (и, может быть, еще XML), имя самого скрипта, чексумма (это что-то типа hashcode, при помощи которого проверяется, изменилась или нет миграция. Делается это на случай, если мы провели миграцию в БД и потом ее поправили: делать этого нельзя, все правки вносятся только посредством новой миграции и чтобы этого не было, чек сумма следит за этим), имя sql юзера, дата обработки миграции, время на выполнение и результат (успешно или не успешно).
Миграция, написанная один раз, не должна быть изменена будущем. Даже если в ней находится дефект. Все изменения проходят только посредством новой миграции. Это очень важно.
Чтобы показать, что будет, давайте немного изменим наш скрипт и попробуем запустить его вновь.
Добавим в нашу миграцию одну запись в таблицу country:
и запустим main метод и вот что получим:
Как я и ожидал, flyway распознал, что скрипт был изменен и не провел миграцию.
В некоторых случаях действительно бывает необходимо запустить обновленную миграцию и чтобы flyway это пропустил, нужно удалить запись в таблице flyway_schema_history и уже после этого накатить обновленную миграцию. Это не нормальное поведение и так не должно быть, но знать о таком способе разрешения проблемы также нужно.
Разобрались с первой миграцией. Теперь хотелось бы добавить еще одну миграцию, с данными о странах, как было в статье о БД:
файл V00002__Add_test_data_to_country.sql
И запустим опять main метод:
Из логов видно, что перед началом запуска миграции БД была в версии 00001, поэтому запустятся все миграции после этой версии. Далее, запустилась версия 00002 и прошла успешно.
Проверим, или уже верите мне, что три записи в country будут уже находится в БД?))
Я бы проверил, поэтому пруф:
Вот как-то так. Если запустить еще раз проект, то flyway просто пропустит накатывание миграций, так как база данных полностью соответствует необходимой версии.

Что в рамках этого нам нужно сделать?
- Запустить SpringBoot приложение на базе Maven.
- Добавить туда Flyway: благо, они легко интегрируются.
- Добавить схему таблиц, которые есть у нас в примере базы данных.
Что такое flyway
Чтобы что-то использовать, нужно для начала выяснить, что это такое и зачем. Flyway — это инструмент для контроля версии базы данных. Слова известные, но как-то понимания не добавилось, да? Попробуем описать проблему, которую решает flyway. Допустим, у нас есть проект. Как и все в нашем мире, он не совершенен, поэтому спланировать и составить окончательную версию проекта не получилось. Каждый раз появляются те или иные неучтенные нюансы. Проект в своей работе использует БД. Разумеется, при изменении проекта может измениться и структура базы данных. Допустим, мы добавляем новое поле для одной из сущностей нашего проекта. Как это сделать?- Добавить это поле в нашу сущность, обновить все, чтобы бизнес логика работала.
- Обновить базу данных. Единственный возможный способ — сделать это вручную. Для этого нужно зайти и прописать необходимый sql скрипт.
- а если у нас не одно место, где мы разворачиваем наш проект, то это в каждом из них нужно делать?
- а если мы захотим вернуться назад, как мы узнаем, в каком именно состоянии сейчас находится структура БД?
- как мы будем уверены, что изменение БД прошло успешно?
- как получить возможность отследить все изменения БД, которые прошли на проекте?
Запускаем SpringBoot + Flyway
Что такое Spring Boot
А что же такое запускаем?... Чтобы понять, что и зачем мы делаем, нужно определиться с тем, что такое SpringBoot. Вначале быстро поговорим (ну ооочень быстро) о Spring. На данный момент это де-факто промышленный стандарт в разработке серверных приложений на Java. Стандарт чего? Как вам так объяснить. Spring — это скелет приложения, на который мы потом набрасываем “мясо” — нашу бизнес-логику. При помощи спринга (здесь и далее буду использовать эту кальку, чтобы не тратить время на переключение языка :D )) Спринг дает нам старт, с которого мы начинаем все делать. Он- Хочешь работать с базой данных? Хочешь с реляционной? Хочешь с нереляционной? Вот, пожалуйста, у нас Spring Data.
- Хочешь работать с http запросами? Вот тебе, пожалуйста, Spring web (Spring MVC).
- Тебе нужен контейнер для всех объектов в одном месте? Вот Spring Core.
- Нужно настроить безопасность на проекте, да так, чтобы были разные роли и субординация? Spring Security.
- Ты только подумал о том, что хорошо бы иметь такую штуку, так окажется, что у Спринга уже есть то, что тебе нужно, и оно быстро и легко интегрируется.
Запускаем SpringBoot
Так как мы уже разбирались в том, что такое мавен, давайте создадим новый проект для наших нужд. Для этого просто нужно перейти на сайт, специально созданный для этого дела. Называется он Spring Initializr.
- Инструмент по сборке проекта — gradle или maven. Как видите, об Ant уже и не вспоминают. Это хорошая подсказка о том, каким средствам сборки стоит уделить время.
- Язык, на котором можно писать — java, kotlin, groovy. Здесь все просто: все они JVM подобные и спокойно запускают Java код. К слову, стоит посмотреть и на Котлин. Груви уже откровенно стал неинтересным (было время, когда на груви переходили, но оно быстро прошло).
- Версию спринга… Здесь нужно понимать, что версии главной части спринга и его модулей согласованы.
- Данные о проекте. Я уже описывал эти вещи.
- Выбираем, в какой архив будет собираться — Jar или War.
- Ну и версию джавы нашей любимой. А то в последнее время развелось этих версий… много) То ждали годами, а теперь по две в год.
- Maven — не зря же мы говорили с вами об этом ранее.
- Java — наша родимая :D
- Версию возьмем 2.2.11. Почему не самую новую? Потому что чем новее, тем больше шансов, что там могут быть какие-то косяки. Для нас не принципиально, какая именно версия, а более старая будет надежнее. Поэтому выбираем 2.2.11.
- Group: com.github.javarushcommunity
- Artifact: springboot-flyway-demo
- Name: SpringBoot + Flyway Demo
- Description: Project demonstrates integration between SpringBoot and Flyway. (Да, умение писать документацию — это важная часть разработки:))
- Package name: com.github.javarushcommunity.springbootflywaydemo. Здесь за нас сразу же создадут базовый пакет с классом, который запустит наше приложение.
- Packaging: Jar
- Java: 8. Не будем идти впереди паровоза и возьмем старую добрую восьмерку. Почему не 11? А зачем? Для нашего примера не вижу смысла.












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 метод и получаем:



- Успешно подключились к БД.
- Прошла валидация миграции и с ней все ок.
- Flyway создал таблицу для управления миграциями.
- И то, что начала миграция 00001 — создание country прошла успешно.







Вывод
В этот раз мы научились худо-бедно понимать и использовать инструмент для миграции БД в связке со SpringBoot. Эта информация необходима для понимания того, что такое инструмент контроля версий баз данных на примере Flyway. Друзья, исходники проекта, который я показал, опубликованы у нас в организации на гитхабе. Если вам нравится пример, ставьте ему звезду, и я буду понимать, что моя работа полезна и ее реально стоит продолжать. Традиционно предлагаю подписаться на мой гитхаб аккаунт. Через него я веду всю свою работу по open source и все те демо проекты, которые неизменно сопровождают мои статьи. Всем спасибо за прочтение. В следующий раз уже будем писать наше приложение. Будет еще в будущем необходимая теория по докеру, но мы ее густо разбавим практикой.Полезные ссылки
Сегодня не так уж и много полезных ссылок. Обратите внимание на видео Евгения, оно действительно стоит того!- Сайт для создания проектов на спринге
- Евгений Борисов — Spring-построитель
- Документация в спринге по Flyway

ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ