Q: どの依存関係を設定すればよいですか?

A: ldbcを利用するには、用途に応じて以下の依存関係を設定する必要があります。

コネクタ

ldbcを使用してデータベース接続処理を行うには以下のいずれかの依存関係を設定します。

jdbc-connector

Javaで書かれた従来のコネクタを使用する場合は以下の依存関係を設定します。

libraryDependencies ++= Seq(
  "io.github.takapi327" %% "jdbc-connector" % "0.8.0",
  "com.mysql" % "mysql-connector-j" % "9.7.0"
)

ldbc-connector

Scalaで書かれた新しいコネクタを使用する場合は以下の依存関係を設定します。

libraryDependencies ++= Seq(
  "io.github.takapi327" %% "ldbc-connector" % "0.8.0"
)

ldbc-connectorは、JVMだけではなくJS, Nativeのプラットフォームでも動作します。

Scala.jsやScala Nativeでldbcを使用する場合は、以下のように依存関係を設定します。

libraryDependencies ++= Seq(
  "io.github.takapi327" %%% "ldbc-connector" % "0.8.0"
)

プレーンなDSL

プレーンなDSLを使用する場合、以下の依存関係を設定します.

libraryDependencies ++= Seq(
  "io.github.takapi327" %% "ldbc-dsl" % "0.8.0"
)

プレーンなDSLは、シンプルなSQL文をそのまま記述する方法です。たとえば、直接SQLリテラルを用いてクエリを実行できます。

import ldbc.dsl.*

val plainResult = sql"SELECT name FROM user"
  .query[String]
  .to[List]
  .readOnly(connector)
// plainResultはList[String]として返される

クエリビルダー

クエリビルダーを使用する場合、以下の依存関係を設定します.

libraryDependencies ++= Seq(
  "io.github.takapi327" %% "ldbc-query-builder" % "0.8.0"
)

クエリビルダーは、型安全なAPIでクエリを構築できる方法です。次の例では、Userモデルを定義し、TableQueryを使ってSELECT文を構築しています。

import ldbc.dsl.codec.Codec
import ldbc.query.builder.*

case class User(id: Int, name: String, email: String) derives Table
object User:
  given Codec[User] = Codec.derived[User]

val userQuery = TableQuery[User]
  .select(user => user.id *: user.name *: user.email)
  .where(_.email === "alice@example.com")

// userQuery.statementは "SELECT id, name, email FROM user WHERE email = ?" として生成される

スキーマ定義とモデルマッピング

スキーマ定義とモデルマッピングを使用する場合、以下の依存関係を設定します.

libraryDependencies ++= Seq(
  "io.github.takapi327" %% "ldbc-schema" % "0.8.0"
)

スキーマ定義とモデルマッピングを利用すると、テーブル定義とScalaモデルとの1対1のマッピングを実現できます。以下は、Userテーブルを定義する例です。

import ldbc.schema.*

case class User(id: Long, name: String, email: String)

class UserTable extends Table[User]("user"):
  def id: Column[Long] = bigint().autoIncrement.primaryKey
  def name: Column[String] = varchar(255)
  def email: Column[String] = varchar(255)
  
  override def * : Column[User] = (id *: name *: email).to[User]

val userQuery = TableQuery[UserTable]
  .select(user => user.id *: user.name *: user.email)
  .where(_.email === "alice@example.com")

// userQuery.statementは "SELECT id, name, email FROM user WHERE email = ?" として生成される

テスト

ldbcを使用するRepositoryの結合テストを書くには、以下の依存関係を設定します。

ldbc-testkit(フレームワーク非依存のコア)

libraryDependencies ++= Seq(
  "io.github.takapi327" %% "ldbc-testkit" % "0.8.0" % Test
)

ldbc-testkit-munit(MUnit統合)

libraryDependencies ++= Seq(
  "io.github.takapi327" %% "ldbc-testkit-munit" % "0.8.0" % Test
)

いずれのモジュールもJVM、Scala.js、Scala Nativeで動作します。

libraryDependencies ++= Seq(
  "io.github.takapi327" %%% "ldbc-testkit-munit" % "0.8.0" % Test
)

ldbc-testkit-munitはMUnitのCatsEffectSuiteを継承したLdbcSuiteトレイトを提供します。ephemeralTest(テスト終了後に自動ロールバック)とpersistentTest(DDLなど実際のコミットが必要な場合)を使ってRepositoryのテストを簡潔に記述できます。

SQLファイルからのコード生成

既存のSQLファイルからモデルとテーブル定義を生成する場合は、sbtプラグインをproject/plugins.sbtに追加します。sbt 1とsbt 2の両方に対応しています。

addSbtPlugin("io.github.takapi327" % "ldbc-plugin" % "0.8.0")

詳細はスキーマコード生成を参照してください。

ZIOとの併用

Cats EffectではなくZIOを使用する場合は、ldbc-zio-interopを追加します。

libraryDependencies ++= Seq(
  "io.github.takapi327" %% "ldbc-zio-interop" % "0.8.0"
)

JVMとScala.jsで動作します(ZIO Interop CatsがScala Nativeに未対応のため、Scala Nativeでは利用できません)。詳細はZIOとの併用を参照してください。

認証プラグイン

ldbc-connectorには主要なMySQL認証プラグインが同梱されているため、通常は追加の依存関係は不要です。独自の認証プラグインを実装する場合や、Aurora IAM認証を利用する場合のみ以下を追加します。

ldbc-authentication-plugin(認証プラグインの基盤)

libraryDependencies ++= Seq(
  "io.github.takapi327" %%% "ldbc-authentication-plugin" % "0.8.0"
)

ldbc-aws-authentication-plugin(Aurora IAM認証)

libraryDependencies ++= Seq(
  "io.github.takapi327" %%% "ldbc-aws-authentication-plugin" % "0.8.0"
)

いずれもJVM、Scala.js、Scala Nativeで動作します。詳細は認証プラグインを参照してください。

参考資料