コンテンツにスキップ

Java の基本

JVM 向けの pgmem には、クライアントの io.github.shibukawa.pgmem:pgmem、テスト用モジュールの pgmem-junit5、pgmem-spring、pgmem-micronaut、プラットフォームごとの classifier でバイナリを配る pgmem-native があります。クライアントはサードパーティの実行時依存を持たないので、JDBC ドライバは自分で追加してください。

build.gradle.kts
val pgmemOs = System.getProperty("os.name").lowercase()
val pgmemArch = System.getProperty("os.arch").lowercase()
val pgmemPlatform = when {
pgmemOs.contains("mac") || pgmemOs.contains("darwin") -> "darwin"
pgmemOs.contains("win") -> "windows"
pgmemOs.contains("linux") -> "linux"
else -> error("Unsupported OS: $pgmemOs; use PGMEM_BINARY")
}
val pgmemCpu = when (pgmemArch) {
"amd64", "x86_64" -> "x86_64"
"aarch64", "arm64" -> "arm64"
else -> error("Unsupported architecture: $pgmemArch; use PGMEM_BINARY")
}
val pgmemNative = "$pgmemPlatform-$pgmemCpu"
dependencies {
testImplementation("io.github.shibukawa.pgmem:pgmem-junit5:1.18.0") // io.github.shibukawa.pgmem:pgmem も入る
testRuntimeOnly("io.github.shibukawa.pgmem:pgmem-native:1.18.0:$pgmemNative") // 自分のプラットフォーム用のバイナリ
testRuntimeOnly("org.postgresql:postgresql:42.7.7")
testImplementation(platform("org.junit:junit-bom:5.14.0"))
testImplementation("org.junit.jupiter:junit-jupiter")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}
tasks.test {
useJUnitPlatform()
}

classifier は linux-x86_64、linux-arm64、darwin-arm64、windows-x86_64、windows-arm64 です。複数のプラットフォームでビルドするなら、5 つ全部に依存するのではなく、Maven のプロファイルや Gradle の OS 判定プラグインでプラットフォームごとに 1 つを選んでください。バイナリは初回に ~/.cache/pgmem/<version>/ へ展開されます。Java 17 以降が必要です。

Gradle の例は実行ホストから classifier を選びます。Maven では mvn -Dpgmem.native.classifier=linux-x86_64 test のように指定してください。複数ホストで使う場合は、下の profiles を POM に追加すると自動選択できます。Intel Mac 向けの native artifact はありません。その場合は native 依存を省き、ローカルビルドの PGMEM_BINARY を指定します。

Maven の既存設定が JUnit 5 に対応していない場合は、次の build 設定も追加します。

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.14.0</version>
<configuration><release>17</release></configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.5.4</version>
</plugin>
</plugins>
</build>
Maven profiles
<profiles>
<profile>
<id>pgmem-linux-amd64</id>
<activation><os><name>Linux</name><arch>amd64</arch></os></activation>
<properties><pgmem.native.classifier>linux-x86_64</pgmem.native.classifier></properties>
</profile>
<profile>
<id>pgmem-linux-x86_64</id>
<activation><os><name>Linux</name><arch>x86_64</arch></os></activation>
<properties><pgmem.native.classifier>linux-x86_64</pgmem.native.classifier></properties>
</profile>
<profile>
<id>pgmem-linux-aarch64</id>
<activation><os><name>Linux</name><arch>aarch64</arch></os></activation>
<properties><pgmem.native.classifier>linux-arm64</pgmem.native.classifier></properties>
</profile>
<profile>
<id>pgmem-linux-arm64</id>
<activation><os><name>Linux</name><arch>arm64</arch></os></activation>
<properties><pgmem.native.classifier>linux-arm64</pgmem.native.classifier></properties>
</profile>
<profile>
<id>pgmem-darwin-aarch64</id>
<activation><os><family>mac</family><arch>aarch64</arch></os></activation>
<properties><pgmem.native.classifier>darwin-arm64</pgmem.native.classifier></properties>
</profile>
<profile>
<id>pgmem-darwin-arm64</id>
<activation><os><family>mac</family><arch>arm64</arch></os></activation>
<properties><pgmem.native.classifier>darwin-arm64</pgmem.native.classifier></properties>
</profile>
<profile>
<id>pgmem-windows-amd64</id>
<activation><os><family>windows</family><arch>amd64</arch></os></activation>
<properties><pgmem.native.classifier>windows-x86_64</pgmem.native.classifier></properties>
</profile>
<profile>
<id>pgmem-windows-x86_64</id>
<activation><os><family>windows</family><arch>x86_64</arch></os></activation>
<properties><pgmem.native.classifier>windows-x86_64</pgmem.native.classifier></properties>
</profile>
<profile>
<id>pgmem-windows-aarch64</id>
<activation><os><family>windows</family><arch>aarch64</arch></os></activation>
<properties><pgmem.native.classifier>windows-arm64</pgmem.native.classifier></properties>
</profile>
<profile>
<id>pgmem-windows-arm64</id>
<activation><os><family>windows</family><arch>arm64</arch></os></activation>
<properties><pgmem.native.classifier>windows-arm64</pgmem.native.classifier></properties>
</profile>
</profiles>
  1. プロセスを起動します。 Pgmem は AutoCloseable で、閉じるとすべてのサーバーが止まります。

    try (Pgmem pg = Pgmem.builder().database("app").start()) {
    Server template = pg.template();
    System.out.println(template.jdbcUrl()); // jdbc:postgresql://127.0.0.1:54321/app?user=postgres&sslmode=disable
    }

    ビルダーにはほかに user(...)、param("shared_buffers", "128MB")、log(true)、binary(path) があります。

  2. スキーマを登録します。 マイグレーションツールを使います。マイグレーションツールを参照してください。

  3. シードデータを入れます。 シードデータを参照してください。

  4. JDBC で使います。 jdbcUrl() にはユーザーと sslmode が含まれ、dataSource() は javax.sql.DataSource を返します。

    try (Connection conn = DriverManager.getConnection(template.jdbcUrl());
    PreparedStatement ps = conn.prepareStatement("SELECT name FROM users WHERE id = ?")) {
    ps.setLong(1, 1);
    try (ResultSet rs = ps.executeQuery()) {
    rs.next();
    String name = rs.getString(1);
    }
    }

    この URL で HikariCP のプールを作ることもできます。接続ごとにバックエンドプロセスが起動します。

String schema = Files.readString(Path.of("src/test/resources/schema.sql"));
try (Connection conn = DriverManager.getConnection(template.jdbcUrl());
Statement st = conn.createStatement()) {
st.execute(schema);
}
src/test/resources/seed.xml
<dataset>
<users id="1" name="Frank" email="frank@example.com"/>
<users id="2" name="Grace" email="grace@example.com"/>
<orders id="1" user_id="1" amount="1200"/>
</dataset>
IDatabaseTester tester = new JdbcDatabaseTester(
"org.postgresql.Driver", template.jdbcUrl(), template.user(), "");
tester.setDataSet(new FlatXmlDataSetBuilder()
.build(getClass().getResourceAsStream("/seed.xml")));
tester.setSetUpOperation(DatabaseOperation.CLEAN_INSERT);
tester.onSetup();

スナップショットとフォークを直接使う

Section titled “スナップショットとフォークを直接使う”
try (Pgmem pg = Pgmem.builder().database("app").start()) {
migrate(pg.template().jdbcUrl());
Snapshot snap = pg.template().snapshot(); // 開いているトランザクションを待つ。30 秒
try (Fork fork = snap.fork()) { // 専用の複製
DataSource ds = fork.dataSource();
// ...
}
}

snapshot() の前に、テンプレートへの接続はすべてコミットするか閉じてください。次のページの JUnit 5 拡張は、これをテストのライフサイクルに組み込みます。