検索
ホームページJava&#&チュートリアルマルチモジュール Gradle プロジェクトでの Flyway の移行 (クリーン アーキテクチャ)

Flyway を使用した Java でのデータベース移行の自動化

データベースの移行は、特に継続的インテグレーションとデリバリー (CI/CD) が標準的な実践である環境では、ソフトウェア開発の重要な側面です。アプリケーションが成長し、進化するにつれて、アプリケーションが依存するデータベース スキーマも変化する必要があります。これらのスキーマ変更を手動で管理すると、エラーが発生し、かなりの時間がかかる可能性があります。

データベースの移行を簡素化するために調整された貴重なオープンソース ツールである Flyway を紹介します。 Flyway はデータベースにバージョン管理を導入し、スキーマを安全かつ確実に移行できるようにします。この記事では、Flyway を使用してマルチモジュールの Gragle Java プロジェクトでデータベースの移行を自動化し、データベースの変更管理が合理化され、エラーが発生しにくいプロセスになるようにする方法を検討します。

フライウェイの詳細

Gradle でのマルチプロジェクト ビルドを理解する

一部の小規模なプロジェクトやモノリシック アプリケーションは、1 つのビルド ファイルと統一されたソース構造だけで管理できる場合がありますが、大規模なプロジェクトは、相互依存する複数のモジュールに編成されることがよくあります。ここでは「相互依存」という用語が重要であり、単一のビルド プロセスを介してこれらのモジュールを接続する必要性を強調しています。

Gradle は、マルチモジュール プロジェクトと呼ばれることが多いマルチプロジェクト ビルド機能を使用して、このセットアップに対応します。 Gradle の用語では、これらのモジュールはサブプロジェクトと呼ばれます。

マルチプロジェクト ビルドは 1 つのルート プロジェクトを中心に構成され、その下に複数のサブプロジェクトを含めることができます。

gradle project

ディレクトリ構造は次のようになります:

├── .gradle
│   └── ⋮
├── gradle
│   ├── libs.versions.toml
│   └── wrapper
├── gradlew
├── gradlew.bat
├── settings.gradle.kts (1)
├── sub-project-1
│   └── build.gradle.kts (2) 
├── sub-project-2
│   └── build.gradle.kts (2) 
└── sub-project-3
    └── build.gradle.kts (2)

(1) settings.gradle.kts ファイルにはすべてのサブプロジェクトが含まれている必要があります。
(2) 各サブプロジェクトには独自の build.gradle.kts ファイルが必要です。

クリーンなアーキテクチャのための Gradle サブモジュールの活用

クリーン アーキテクチャは、関心事の分離を強調する設計パターンであり、ソフトウェアの保守とテストが容易になります。このアーキテクチャをプロジェクトに実装する実際的な方法の 1 つは、Gradle のサブモジュール構造を使用してコードベースを編成することです。 Clean Architecture と Gradle サブモジュールを調整する方法は次のとおりです:

クリーンなアーキテクチャ層:
コア:

  • ビジネス ロジック、ドメイン モデル、アプリケーション ルールが含まれます。 外部または Web に依存しません。
  • 可能な限りフレームワーク固有の実装から独立させる必要があります。

外部:

  • データベースの移行やサードパーティのサービスとのやり取りなど、外部のアクションや統合を処理します。
  • ビジネス ロジックはコアに依存する可能性がありますが、Web に依存すべきではありません。

ウェブ:

  • REST API を公開し、HTTP リクエストを処理するエントリ ポイント。
  • ビジネス ロジックについてはコアに依存し、統合については外部に依存する場合があります。
├── .gradle
│   └── ⋮
├── gradle
│   ├── libs.versions.toml
│   └── wrapper
├── gradlew
├── gradlew.bat
├── settings.gradle.kts (1)
├── sub-project-1
│   └── build.gradle.kts (2) 
├── sub-project-2
│   └── build.gradle.kts (2) 
└── sub-project-3
    └── build.gradle.kts (2)

ステップ 1: Java ベースの Gradle プロジェクトを作成し、「SchoolStaff」という名前を付けます。

ステップ 2: Spring Initializr に移動し、Web という名前の REST API プロジェクトを生成します。

ステップ 3: Java ベースの Gradle プロジェクトを作成し、外部 という名前を付けます。

ステップ 4: Java ベースの Gradle プロジェクトを作成し、Core という名前を付けます。

ルート build.gradle.kts

SchoolStaff/
├── Core/
│   ├── src/
│   │   └── main/
│   │       ├── java/         # Business logic and domain objects
│   │       └── resources/    # Core-specific resources (if any)
│   └── build.gradle.kts
├── External/
│   ├── src/
│   │   └── main/
│   │       ├── java/         # External integration code
│   │       └── resources/    # db/migration and other external resources
│   └── build.gradle.kts
├── Web/
│   ├── src/
│   │   └── main/
│   │       ├── java/         # REST controllers and entry-point logic
│   │       └── resources/    # Application-specific configuration
│   └── build.gradle.kts
├── build.gradle.kts          # Root Gradle build
└── settings.gradle.kts       # Project module settings

settings.gradle.kts

plugins {
    id("java")
}

allprojects {
    group = "school.staff"
    version = "1.0.0"

    repositories {
        mavenLocal()
        mavenCentral()
    }
}

subprojects {
    apply(plugin = "java")

    dependencies {
        testImplementation(platform("org.junit:junit-bom:5.10.0"))
        testImplementation("org.junit.jupiter:junit-jupiter")
    }

    tasks.test {
        useJUnitPlatform()
    }
}

「Web」プロジェクトに必要な依存関係。

rootProject.name = "SchoolStaff"

include("Core", "External", "Web")

「コア」プロジェクトに必要な依存関係。

dependencies {
    implementation(project(":Core"))
    implementation(project(":External"))
}

「外部」プロジェクトに必要な依存関係。

dependencies {
    runtimeOnly(project(":External"))
}

Flyway の移行には次のプラグインを使用します:

import java.sql.DriverManager
import java.util.Properties
// Function to load properties based on the environment
fun loadProperties(env: String): Properties {
    val properties = Properties()
    val propsFile = file("../web/src/main/resources/application-$env.properties")

    if (propsFile.exists()) {
        propsFile.inputStream().use { properties.load(it) }
    } else {
        throw GradleException("Properties file for environment '$env' not found: ${propsFile.absolutePath}")
    }

    return properties
}
// Set the environment (default is 'dev' if no argument is passed)
val env = project.findProperty("env")?.toString() ?: "dev"

// Load properties for the chosen environment
val dbProps = loadProperties(env)
buildscript {
    dependencies {
        classpath("org.flywaydb:flyway-database-postgresql:11.1.0") // This is required for the flyway plugin to work on the migration, otherwise it will throw an error as No Database found
        classpath("org.postgresql:postgresql:42.7.4")
    }
}
plugins {
    id("java-library")
    id("org.flywaydb.flyway") version "11.0.1"
}

group = "school.staff"
version = "unspecified"

repositories {
    mavenLocal()
    mavenCentral()
}

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-data-jpa:3.4.0")
    implementation("org.postgresql:postgresql:42.7.4")
    implementation("org.flywaydb:flyway-core:11.0.1")
    implementation("org.flywaydb:flyway-database-postgresql:11.0.1")
    implementation("org.flywaydb:flyway-gradle-plugin:11.0.1")

    implementation (project(":Core"))
    testImplementation(platform("org.junit:junit-bom:5.10.0"))
    testImplementation("org.junit.jupiter:junit-jupiter")
}

tasks.test {
    useJUnitPlatform()
}

// Task to create the database if it doesn't exist
tasks.register("createDatabase") {
    doLast {
        val dbUrl = dbProps["spring.datasource.url"] as String
        val dbUsername = dbProps["spring.datasource.username"] as String
        val dbPassword = dbProps["spring.datasource.password"] as String

        // Extract the base URL and database name
        val baseDbUrl = dbUrl.substringBeforeLast("/")+ "/"
        val dbName = dbUrl.substringAfterLast("/")

        // Connect to the PostgreSQL server (without the specific database)
        DriverManager.getConnection(baseDbUrl, dbUsername, dbPassword).use { connection ->
            val stmt = connection.createStatement()
            val resultSet = stmt.executeQuery("SELECT 1 FROM pg_database WHERE datname = '$dbName'")
            if (!resultSet.next()) {
                println("Database '$dbName' does not exist. Creating it...")
                stmt.executeUpdate("CREATE DATABASE \"$dbName\"")
                println("Database '$dbName' created successfully.")
            } else {
                println("Database '$dbName' already exists.")
            }
        }
    }
}

flyway {
    url = dbProps["spring.datasource.url"] as String
    user = dbProps["spring.datasource.username"] as String
    password = dbProps["spring.datasource.password"] as String
    locations = arrayOf("classpath:db/migration")
    baselineOnMigrate = true
}

 //Ensure classes are built before migration
tasks.named("flywayMigrate").configure {
    dependsOn(tasks.named("createDatabase"))
    dependsOn(tasks.named("classes"))
}

このアプローチは、制御された信頼性の高い移行を保証するため、実稼働環境に最適です。アプリケーションの起動ごとに自動的に移行を実行するのではなく、必要な場合にのみ移行を実行することで、より優れた柔軟性と制御を提供します。

Spring アプリケーションの application.properties ファイルも利用して、データベース接続と資格情報を管理しています。 BaselineOnMigrate = true 設定により、最初の移行が将来の移行のベースラインとして使用されます。

 plugins {
    id("org.flywaydb.flyway") version "11.0.1"
}

JPA Buddy を使用して、外部プロジェクトの resource/db/migration ディレクトリ内にすべての移行ファイルを生成できます。

V1__Initial_Migration

flyway {
    url = dbProps["spring.datasource.url"] as String
    user = dbProps["spring.datasource.username"] as String
    password = dbProps["spring.datasource.password"] as String
    locations = arrayOf("classpath:db/migration")
    baselineOnMigrate = true
}

ルート プロジェクトから、次のコマンドを使用して Flyway 移行を実行できます。

CREATE TABLE _user
(
    id                 UUID NOT NULL,
    created_by         UUID,
    created_date       TIMESTAMP WITH TIME ZONE,
    last_modified_by   UUID,
    last_modified_date TIMESTAMP WITH TIME ZONE,
    first_name         VARCHAR(255),
    last_name          VARCHAR(255),
    email              VARCHAR(255),
    password           VARCHAR(255),
    tenant_id          UUID,
    CONSTRAINT pk__user PRIMARY KEY (id)
);

これにより、すべての移行ファイルがデータベースに適用されます。

結論

Gradle マルチモジュール プロジェクト内で Flyway を使用してデータベース移行を自動化する方法を検討しました。これは、CI/CD 環境でスキーマの一貫性を維持するために重要です。

Gradle がマルチプロジェクト ビルドをサポートし、複雑なプロジェクトを管理しやすいサブプロジェクトに編成し、それぞれが独自のビルド構成を持ち、ルート ビルド スクリプトの下に統合される方法についても説明しました。

最後に、クリーン アーキテクチャと Gradle モジュールを調整し、プロジェクトをコア層、外部層、Web 層に構造化し、懸念事項と依存関係管理の明確な分離を促進しました。

これらの実践により、モジュール性、自動化、保守性が強化され、スケーラブルでエラーのないソフトウェア開発の準備が整えられます。

以上がマルチモジュール Gradle プロジェクトでの Flyway の移行 (クリーン アーキテクチャ)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
JVMはオペレーティングシステムAPIの違いをどのように処理しますか?JVMはオペレーティングシステムAPIの違いをどのように処理しますか?Apr 27, 2025 am 12:18 AM

JVMは、JavanativeInterface(JNI)およびJava Standard Libraryを介してオペレーティングシステムのAPIの違いを処理します。1。JNIでは、Javaコードがローカルコードを呼び出し、オペレーティングシステムAPIと直接対話できます。 2. Java Standard Libraryは統一されたAPIを提供します。これは、異なるオペレーティングシステムAPIに内部的にマッピングされ、コードがプラットフォーム間で実行されるようにします。

Java 9で導入されたモジュール性は、プラットフォームの独立性にどのように影響しますか?Java 9で導入されたモジュール性は、プラットフォームの独立性にどのように影響しますか?Apr 27, 2025 am 12:15 AM

modularitydoesnotdirectlyectlyectjava'splatformindepensence.java'splatformendepenceismaindainededainededainededaindainedaindained bythejvm、butmodularityinfluencesApplucationStructure andmanagement、間接的なインパクチャプラット形成依存性.1)

ByteCodeとは何ですか?また、Javaのプラットフォームの独立性とどのように関係していますか?ByteCodeとは何ですか?また、Javaのプラットフォームの独立性とどのように関係していますか?Apr 27, 2025 am 12:06 AM

bytecodeinjavaisthe intermediaterepresentationthateNablesplatformindepence.1)javacodeis compiledintobytecodestoredin.classfiles.2)thejvminterpretsorcompilesthisbytecodeintomachinecodeatime、

Javaがプラットフォームに依存しない言語と見なされるのはなぜですか?Javaがプラットフォームに依存しない言語と見なされるのはなぜですか?Apr 27, 2025 am 12:03 AM

javaachievesplatformedenceTheTheTheJavavirtualMachine(JVM)、これは、javacodeisisisisisissompiledIntobytecode.2)javaCodeisisisisissompiledevedevicetecode.2)

グラフィカルユーザーインターフェイス(GUI)は、Javaのプラットフォーム独立性の課題をどのように提示できますか?グラフィカルユーザーインターフェイス(GUI)は、Javaのプラットフォーム独立性の課題をどのように提示できますか?Apr 27, 2025 am 12:02 AM

Javagui開発におけるプラットフォームの独立性は課題に直面していますが、Swing、Javafx、統一外観、パフォーマンス最適化、サードパーティライブラリ、クロスプラットフォームテストを使用することで対処できます。 Javaguiの開発は、クロスプラットフォームの一貫性を提供することを目的としたAWTとSwingに依存していますが、実際の効果はオペレーティングシステムごとに異なります。ソリューションには以下が含まれます。1)SwingおよびJavafxをGUIツールキットとして使用します。 2)uimanager.setlookandfeel()を介して外観を統合します。 3)さまざまなプラットフォームに合わせてパフォーマンスを最適化します。 4)ApachepivotやSWTなどのサードパーティライブラリを使用する。 5)一貫性を確保するために、クロスプラットフォームテストを実施します。

Java開発のどの側面がプラットフォームに依存していますか?Java開発のどの側面がプラットフォームに依存していますか?Apr 26, 2025 am 12:19 AM

javadevelopmentisnotentirelylylypratform-IndopentDuetoseveralfactors.1)jvmvariationsaffectperformanceandbehavioracrossdifferentos.2)nativeLibrariesviajniintroducePlatform-specificissues.3)giaiasystemsdifferbeTioneplateplatifflics.4)

さまざまなプラットフォームでJavaコードを実行するときにパフォーマンスの違いはありますか?なぜ?さまざまなプラットフォームでJavaコードを実行するときにパフォーマンスの違いはありますか?なぜ?Apr 26, 2025 am 12:15 AM

Javaコードは、さまざまなプラットフォームで実行するときにパフォーマンスの違いがあります。 1)JVMの実装と最適化戦略は、OracleJDKやOpenJDKなどとは異なります。 2)メモリ管理やスレッドスケジューリングなどのオペレーティングシステムの特性もパフォーマンスに影響します。 3)適切なJVMを選択し、JVMパラメーターとコード最適化を調整することにより、パフォーマンスを改善できます。

Javaのプラットフォームの独立性の制限は何ですか?Javaのプラットフォームの独立性の制限は何ですか?Apr 26, 2025 am 12:10 AM

java'splatformindepentedencehaslimitationsincludingporformanceoverhead、versioncompatibulisisues、changleSwithnativeLibraryIntegration、プラットフォーム固有の機能、およびjvminStallation/maintenation。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

VSCode Windows 64 ビットのダウンロード

VSCode Windows 64 ビットのダウンロード

Microsoft によって発売された無料で強力な IDE エディター

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

SublimeText3 英語版

SublimeText3 英語版

推奨: Win バージョン、コードプロンプトをサポート!