مهاجرت های پایگاه داده در SpringBoot با flyway

به نام خداتا حالا شده بعد از اینکه دیتا بیس و جدول ها رو ایجاد کردین بخواهین به تغییری تو یه فیلد ازجدول بدین؟مثلا یه ستون اضافه کنین یا یکی حذف کنید؟ یا بخواید نوع (Data Type) رو عوض کنین؟برای اینکه این کارها رو به صورت دستی ایجاد نکنیم و استرس اینکه تعییر در محیط Development و production یکسان باشند بیاید با هم این مقاله رو بخونیم :)تو سیستمهایی کوچیک و بزرگ که برای سازمان ها مختلف مینویسیم تغییرات در جداول پایگاه داده یه چیزه خیلی روال هستش چون بر اساس نیاز کارفرما ما باید تغییرات رو اعمال کنیم و برای اینکه کارمون راحت تر باشه و استرس اینکه تعییر در محیط Development و production یکسان باشند نیاز داریم تا از یک کتابخانه هایی استفاده کنیم که این کار رو برای ما راحت کنند. تو زبان جاوا کتابخانه های زیادی وجود دارن که بعضی از مهمترین هاش اینا هستن: flyway, liquibaseخب ما تو این مقاله میخوایم از flyway تو زبان جاوا و فریمورک spring boot استفاده کنیم.خب دیگه تئوری کافیه و بریم به صورت عملی این کار رو با هم انجام بدیم :)یه چیزم بگم اولش که من خیلی خوب نمینویسم :) اگه جایی رو خوب متوجه نشدین بهم بگین که توضیح بدم یا متن رو اصلاح کنم.برای شروع کافیه موارد زیر رو داشته باشیم1- یک دیتابیس mysql یا mariadb 2-یک IDE که انتخاب من Intellij هستش و شما میتونین با هر IDE دیگه خواستین کار کنین3- یک پروژه spring bootبرای اینکه یه پروژه spring boot ایجاد میکنیم، به این آدرس میریم و یه پروژه میسازیم ( البته از راههای دیگه هم میشه ساخت ولی من با این روش راحتترم) طبق عکس زیر Group, Artiface,Name packageName رو مشخص میکنیم (هر اسمی که دوست داشتین بزارین فعلن مهم نیست) و همچنین از maven برای Build پروژه استفاده مکنیم.بر روی دکمه سمت چپ ADD DEPENDENCIES کلیک میکنیم تا کتابحانه های Spring Data JPA, Flyway Migration,Spring Web,MySQL Driverرو به پروژه اضافه کنیم و نسخه جاوا رو هم مشخص میکنیم من در حال حاضر از جاوا 11 دارم استفاده میکنم.یجاد پروژه در سایت start.spring.ioحالا باید رو دکمه GENERATE که پایین عکس مشخص هستش کلیک کنیم و پروژه دانلود میشه. ( به همین راحتی)وقتی که دانلود پروژه تموم شد اون رو تو مسیری که میخواید کپی کنید و بعدش اون رو از حالت فشرده خارج کنید، داخل پروژه برید و فایلهای زیر رو باید ببینید.محتویات فایل pom.xml به صورت زیر هستش:<?xml version=&quot1.0&quot encoding=&quotUTF-8&quot?><project xmlns=&quothttp://maven.apache.org/POM/4.0.0&quot xmlns:xsi=&quothttp://www.w3.org/2001/XMLSchema-instance&quot xsi:schemaLocation=&quothttp://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd&quot> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.6.5</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.mahdi</groupId> <artifactId>flyway</artifactId> <version>0.0.1-SNAPSHOT</version> <name>flyway</name> <description>Demo project for use flyway in Spring Boot</description> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.flywaydb</groupId> <artifactId>flyway-core</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build></project> تو intellij برای اینکه یه پروژه رو باز کنید تنها کافیه رو فایل Pom.xml کلیک راست کنید و بزنید RunWith و اسم برنامه Intellij IDEA رو انتخاب کنید بعدش به شما به پیام میده مینی بر اینکه این پروژه از نظر شما trust هست که شما گزینه trust رو انتخاب کنید.احتمالا بعدش یه مدت طول میکشه که برنامه کتابخانه ها رو دانلود کنه و بعد اینکه دانلود تموم بشه این صفحه رو باید ببینید.نمایش پروژهخب الان دیگه مراحل ایجاد پروژه تموم شد و کار ما تازه شروع شد :)ایتدا یه DataBase با اسم دلخواه تو mysql میسازیم. (چون یکم نصب انواع DataBase تو ویندوز وقت گیره من اصولا یه VMWARE رو ویندوز نصب میکنم و داخل اون انواع و اقسام سیستم عامل ها رو دارم - شما هم هرجور که راحتین انجام بدین و به نظر من اصلا هم تعصب تکنولوژی هم نداشته باشین) در حال حاصر من یه Rocky linux دارم که رو اون mysql رو نصب کردم.اگه هنوز رو سیستمتون Mariadb or mysql نصب نکردین از اینجا اون رو روی سیستم عاملهای از نوع redhat نصب کنید و از اینجا برای debian نصب کنید.با دستور زیر به پایگاه داده وصل میشیمmysql -uroot -pو دستور ایجاد database رو میزنیم و اسم flyway_test رو انتخاب کردیم ( شما هر اسمی دوست داشتس انتخاب کن)CREATE DATABASE flyway_test DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;حالا باید یک کاربر بسازیم که برنامه بتونه به پابگاه داده وصل بشه. اسم کاربر رو میزاریم app و با رمز App@123GRANT ALL PRIVILEGES ON `flyway_test`.* TO 'app'@'%' IDENTIFIED BY 'App@123';حالا باید دستور FLUSH PRIVILEGES رو بزنیم تا تغییرات بر روی پایگاه داده ایجاد بشه.حالا بر اطمینان از اینکه همه چیز درست انجام شده باشه از mariadb با دستور quit میام بیرون و دوباره با کاربر app به mariadb لاگین میکنیم.خب الان باید بریم سر وقت کدمون تا بهش بگیم به کدوم پایگاه داده وصل بشه.برای اینکار در فایل application.properties اطلاعات زیر را وارد میکنیمserver.port=8080spring.datasource.url=jdbc:mysql://192.168.231.128:3306/flyway_test?serverTimezone=UTC&useSSL=falsespring.datasource.username=appspring.datasource.password=App@123## Hibernate propertiesspring.jpa.hibernate.use-new-id-generator-mappings=falsespring.jpa.hibernate.ddl-auto=validatespring.jpa.show-sql=true خب الان باید اطلاعات مربوط به کانفیگ flyway هم تو فایل application.properties برازیم#flywayConfigspring.flyway.enabled=truespring.flyway.url=jdbc:mysql://192.168.231.128:3306/flyway_test?serverTimezone=UTC&useSSL=falsespring.flyway.user=appspring.flyway.password=App@123spring.flyway.group=trueنمای کلی فایل application.properties در عکی زیر مشخص هستشapplication.propertiesآدرس 192.168.231.128 مربوط به سرور پایگاه داده من هستش که برای شما مسلما با این فرق داره، اگر روی کامپیوتر خودتون هستش باید localhost باشه و اصولا پورت پیش فرض پایگاه داده 3306 هستش.خب حالا برای اینکه به پروژه بگیم وقتی داری میای بالا باید چه تعییراتی تو پایگاه داده بدی تو مسیر زیر باید فایل با مشخصات زیر بسازیم.src/main/resources/db/migrationخب اسم فایلی که میسازیم باید از الگو زیر پیروی کنه:قسمت اول: باید حرف V انگلیسی باشد (V بزرگ)قسمت دوم:شماره نسخه تعییرات باشد. این شماره میتونه 1- 001-1.2.3-2029.67.786.4 و .... باشد.قسمت سوم: دو عدد underscores به صورت پیوستهقسمت چهارم: توضیح مختصر در مورد تغییراتقسمت پنجم: پسوند .sqlقسمت های یک و سه و پنج میتونن از طریق تنظمات عوض بشنspring.flyway.sql-migration-prefix=T spring.flyway.sql-migration-separator=-- spring.flyway.sql-migration-suffixes=.blog 1.0--create_users_table.blog اسم فایل با استفاده از تنظمات جدیدکه ما از این تنظمات چشم پوشی میکنیم.خب حالا میایم یه folder به اسم model میسازیم و داخل اون یه کلاس به اسم Author میسازیم.package com.mahdi.flyway.model; import javax.persistence.*; import java.util.Date; @Table(name = &quotauthor&quot) @Entity public class Author{ @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = &quotid&quot, nullable = false) private Long id; @Column(unique = true, length = 100, nullable = false) private String name; @Column(length = 100, nullable = false) private String password; @Column(nullable = false, columnDefinition = &quottinyint not null default 0&quot) private boolean enabled; @Column(updatable = false) private Date createdAt; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public boolean isEnabled() { return enabled; } public void setEnabled(boolean enabled) { this.enabled = enabled; } public Date getCreatedAt() { return createdAt; } public void setCreatedAt(Date createdAt) { this.createdAt = createdAt; } }برای اینکه بخوایم همین جدول در پایگاه داده هم ساخته بشه با استفاده از الگو و در مسیر اعلام شده فایلی به اسم زیر میسازیمV1__create_authers_table.sqlو محتویات زیر را داخل فایل میزاریم: CREATE TABLE author ( id BIGINT NOT NULL AUTO_INCREMENT, name VARCHAR(100) NOT NULL, password VARCHAR(100) NOT NULL, enabled TINYINT DEFAULT 0 NOT NULL, created_at datetime NULL, updated_at datetime NULL, CONSTRAINT pk_authors PRIMARY KEY (id) ); ALTER TABLE author ADD CONSTRAINT uc_authors_name UNIQUE (name);خب کار ما فعلن تموم شد و حالا اگه پروژه رو اجرا کنیم باید جدول author را به صورت خودکار بسازه.همانطور که در عکس بالا میبینید متن زیر نشان دهنده این هستش که جدول با موفقیت ساخته شده استSuccessfully applied 1 migration to schema `flyway_test`, now at version v1برای اطمینان میتونبد دستور show tables رو بزنید، دو تا جدول ساخته شده که یکی از اونها flyway_schema_history هستش که برای نگه داشتن تاریخچه migrate هستش.اگه خواستین تعییرات دیگه هم بدین باید اسم فایل به ترتیب بره بالا مثلا فایل بعدی V2__create_user_table.sql باشه.نکته اول: بعد از اینکه فایل با موفقیت ایجتد شد به هیچ عنوان محتویات فایل رو عوض نکنید ،بعد از اجرای فایل یه checksum از فایل گرفته میشه و داخل جدول در فیلد checksum قرار داده میشه.نکته دوم: کلی دستور برای flyway هستش که میتونید از اینجا برید و بخونید و بر اساس نیازتون اون رو اجرا کنید.نکته مهم: همیشه بر یادگیری بهتر همیشه خودتون یه بار پروژه رو بسازین تا بهتر متوجه بشین.آدرس گیت پروژه:https://github.com/mahdiShirinabadi/flyway_testپایدار باشید