লিকুইবেস দিয়ে ডেল্টা স্কিমা জেনারেট করা: স্প্রিং হাইবারনেট - ৩

স্প্রিং এবং স্প্রিং বুটে যদি নিচের প্রপার্টিজ এ update বা created থাকে, তাহলে এনটিটি ক্লাস থেকে হাইবারনেট নিজেই ডাটাবেস এর জন্য স্কিমা জেনারেট করে ফেলে।

spring.jpa.hibernate.ddl-auto=update


ডেভেলপমেন্ট মোডে এটা বেশ ভালো বুদ্বি। কিন্তু প্রোডাকশনে update রাখাও বিপদজনক। কারণ, আপডেট পুরান স্কিমা রেখেই দেয। ধরুন, আপনি একটা ফিল্ডের নাম পরিবর্তন করেছেন, আপডেট দেয়া থাকলে আগের ফিল্ড রেখে দিয়ে নতুন একটা তৈরী করে দেয়।


কি করতে চাই:

  • ডেভেলপমেন্ট মোড, আমি আমার এনটিটি ক্লাস ইচ্ছেমত পরিবর্তন করব,
  • কাজ শেষ হলে আমি কি পরিবর্তন করেছি তা sql আকারে পেয়ে যাবো।
  • তারপর লিকুইবেসে চেঞ্জলগে সেই পরিবর্তিত sql দিয়ে দিলেই আমার প্রোডাকশন স্কিমা অপডেট হয়ে যাবে।


কিভাবে:

  • ডেভেলপমেন্ট ডাটাবেস ডিলিট করে নতুন করে এপ্লিকেশন চালালে সে এনটিটি ক্লাস থেকে নতুন ডাটাবেস স্কিমা তৈরী করে ফেলবে
  • তারপর এপ্লিকেশন স্টেজিং মোডে চালাতে হবে, তাহলে প্রোডাকশনের সর্বশেষ স্কিমা স্টেজ ডাটাবেসে থাকবে
  • এখন, লিকুইবেসের কমান্ড দিলে সে ডেভ ডাটাবেস এবং স্টেজিং ডাটাবেসের পার্থক্য sql আকারে জেনারেট করে দিবে
  • সর্বশেষে, প্রোডাকশন চেঞ্জ লগে সেই sql যুক্ত করে দিলেই কাজ শেষ।


# ===============================
# = DATA SOURCE
# ===============================
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/blog_dev?createDatabaseIfNotExist=true&useUnicode=yes&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=সিক্রেট 
spring.datasource.testWhileIdle = true
spring.datasource.validationQuery = SELECT 1
spring.datasource.maximumPoolSize=20

# ===============================
# = JPA / HIBERNATE
# ===============================
spring.jpa.hibernate.ddl-auto=update

# ===============================
# = LIQUIBASE
# ===============================
spring.liquibase.enabled=false

application-dev.properties



# ===============================
# = DATA SOURCE
# ===============================
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/blog_stage?createDatabaseIfNotExist=true&useUnicode=yes&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=সিক্রেট
spring.datasource.testWhileIdle = true
spring.datasource.validationQuery = SELECT 1
spring.datasource.maximumPoolSize=20

# ===============================
# = JPA / HIBERNATE
# ===============================
spring.jpa.hibernate.ddl-auto=none

# ===============================
# = LIQUIBASE
# ===============================
spring.liquibase.enabled=true
##### DO NOT CHANGE IT TO STAGE #####
spring.liquibase.change-log=classpath:/liquibase/changelog/changelog-prod.xml

application-stage.properties


# স্টেজিং ডাটাবেস 
username=root
password=সিক্রেট 
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/blog_stage


# Reference database for diff, ডেভ ডাটাবেস 
referenceUsername=root
referencePassword=root
referenceDriver=com.mysql.jdbc.Driver
referenceUrl=jdbc:mysql://localhost:3306/blog_dev

# mvn liquibase:update -Pstage
changeLogFile=src/main/resources/liquibase/changelog/prod/changelog-prod.xml

# mvn liquibase:generateChangeLog -Pstage
outputChangeLogFile=src/main/resources/liquibase/generated/liquibase-changeLog.mysql.sql

# mvn liquibase:diff -Pstage
diffChangeLogFile=src/main/resources/liquibase/generated/liquibase-diff.mysql.sql

liquibase-stage.properties


<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
        xmlns="http://www.liquibase.org/xml/ns/dbchangelog/1.9"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog/1.9
         http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.9.xsd">
    <include file="prod/changelog-schema-1.0.0.sql"         relativeToChangelogFile="true"/>
    <include file="prod/changelog-data-1.0.0.sql"         relativeToChangelogFile="true"/>
</databaseChangeLog>

changelog-prod.xml



ডেল্টা স্কিমা (নমুনা)

..................................................

--changeset maruf:1560008960107-3
ALTER TABLE TAG ADD value VARCHAR(255) NOT NULL;

--changeset maruf:1560008960107-4
ALTER TABLE COMMENT ADD PRIMARY KEY (id);

--changeset maruf:1560008960107-5
ALTER TABLE TAG ADD CONSTRAINT UK_2fox76y7xhorgbd15vhh1ujs8 UNIQUE (value);

--changeset maruf:1560008960107-6
CREATE INDEX FKpnt8rwhdbbowq2oi5a9gn4yp6 ON COMMENT(post_id);

--changeset maruf:1560008960107-7
DROP TABLE POST_COMMENT;

--changeset maruf:1560008960107-8
ALTER TABLE TAG DROP COLUMN name;

--changeset maruf:1560008960107-9
ALTER TABLE TAG DROP COLUMN title;

--changeset maruf:1560120341961-1
ALTER TABLE FILE_META ADD createdAt datetime(6) NULL;

--changeset maruf:1560120341961-2
ALTER TABLE FILE_META ADD createdBy VARCHAR(255) NULL;

--changeset maruf:1560120341961-3
ALTER TABLE FILE_META ADD updatedAt datetime(6) NULL;

--changeset maruf:1560120341961-4
ALTER TABLE FILE_META ADD updatedBy VARCHAR(255) NULL;

......................................................

changelog-schema-1.0.0.sql


কমান্ড সমূহ

১.মেনুয়ালি ডেভ ডাটাবেস ডিলিট করা

২. ডেভ মোডে এপ্লিকেশন চালানো, আমার ক্ষেত্রে বাই ডিফল্ট ডেভ মোডে চলে

mvn spring-boot:run

৩. আবার স্টেজিং মোডে চালানো - প্রোডাকশন ডাটাবেস লোড নিবে

mvn spring-boot:run -Dspring-boot.run.profiles=stage


৪. ডেভ - স্টেজিং = ডেল্টা স্কিমা জেনারেট করা

mvn liquibase:diff -Pstage



ধন্যবাদ।