マルチモジュール Gradle プロジェクトでの Flyway の移行 (クリーン アーキテクチャ)
Flyway を使用した Java でのデータベース移行の自動化
データベースの移行は、特に継続的インテグレーションとデリバリー (CI/CD) が標準的な実践である環境では、ソフトウェア開発の重要な側面です。アプリケーションが成長し、進化するにつれて、アプリケーションが依存するデータベース スキーマも変化する必要があります。これらのスキーマ変更を手動で管理すると、エラーが発生し、かなりの時間がかかる可能性があります。
データベースの移行を簡素化するために調整された貴重なオープンソース ツールである Flyway を紹介します。 Flyway はデータベースにバージョン管理を導入し、スキーマを安全かつ確実に移行できるようにします。この記事では、Flyway を使用してマルチモジュールの Gragle Java プロジェクトでデータベースの移行を自動化し、データベースの変更管理が合理化され、エラーが発生しにくいプロセスになるようにする方法を検討します。
フライウェイの詳細
Gradle でのマルチプロジェクト ビルドを理解する
一部の小規模なプロジェクトやモノリシック アプリケーションは、1 つのビルド ファイルと統一されたソース構造だけで管理できる場合がありますが、大規模なプロジェクトは、相互依存する複数のモジュールに編成されることがよくあります。ここでは「相互依存」という用語が重要であり、単一のビルド プロセスを介してこれらのモジュールを接続する必要性を強調しています。
Gradle は、マルチモジュール プロジェクトと呼ばれることが多いマルチプロジェクト ビルド機能を使用して、このセットアップに対応します。 Gradle の用語では、これらのモジュールはサブプロジェクトと呼ばれます。
マルチプロジェクト ビルドは 1 つのルート プロジェクトを中心に構成され、その下に複数のサブプロジェクトを含めることができます。
ディレクトリ構造は次のようになります:
├── .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 サイトの他の関連記事を参照してください。

ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

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

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









Javaのクラスロードには、ブートストラップ、拡張機能、およびアプリケーションクラスローダーを備えた階層システムを使用して、クラスの読み込み、リンク、および初期化が含まれます。親の委任モデルは、コアクラスが最初にロードされ、カスタムクラスのLOAに影響を与えることを保証します

この記事では、カフェインとグアバキャッシュを使用してJavaでマルチレベルキャッシュを実装してアプリケーションのパフォーマンスを向上させています。セットアップ、統合、パフォーマンスの利点をカバーし、構成と立ち退きポリシー管理Best Pra

この記事では、キャッシュや怠zyなロードなどの高度な機能を備えたオブジェクトリレーショナルマッピングにJPAを使用することについて説明します。潜在的な落とし穴を強調しながら、パフォーマンスを最適化するためのセットアップ、エンティティマッピング、およびベストプラクティスをカバーしています。[159文字]

この記事では、Javaプロジェクト管理、自動化の構築、依存関係の解像度にMavenとGradleを使用して、アプローチと最適化戦略を比較して説明します。

この記事では、MavenやGradleなどのツールを使用して、適切なバージョン化と依存関係管理を使用して、カスタムJavaライブラリ(JARファイル)の作成と使用について説明します。
