Kotlin 直列化
項目一覧
Overview
Kotlin ドライバーは、 Kotlin オブジェクトを直列化および逆直列化するための kotlinx.serialization
ライブラリをサポートしています。
このドライバーは効率的なBson
シリアライザーを提供し、 @Serializable
としてマークされたクラスで使用して、 Kotlin オブジェクトの BSON データへの直列化を処理します。
また、デフォルトをエンコードし、null をエンコードし、クラス弁別子を定義する構成で、 カスタム コーデックをサポートするためにbson-kotlinx
ライブラリをインストールすることもできます。
注意
Kotlin シリアル化ライブラリではなくCodec
インターフェースを使用して Kotlin オブジェクトを BSON データにカスタム エンコードおよびデコードを指定する方法については、「 コーデックガイド」を参照してください。
フレームワークにすでに理解している場合、または慣用的な Kotlin アプローチを使用したい場合は、 Kotlin シリアル化を選択することができます 。
Kotlin ドライバーは Kotlin シリアル化Json
ライブラリで使用できますが、 Json
シリアライザーはObjectId
などの BSON 値型を直接サポートしていません。 BSON と JSON の間の変換を処理できるカスタム シリアライザーを提供する必要があります。
サポートされているタイプ
Kotlin ドライバーは次の機能をサポートします。
Kotlin 直列化ライブラリでサポートされているすべての Kotlin 型
利用可能なすべてのBSON types
Kotlin 直列化をプロジェクトに追加する
Support for 直列化 in the Kotlin driver depends on the official Kotlin 直列化 library.
GradleとMavenパッケージ マネージャーを使用してプロジェクトにシリアル化の依存関係を追加する方法を確認するには、次のタブから選択します。
Gradle を使用している場合 依存関係を管理するには、次のものをbuild.gradle.kts
依存関係リストに追加します。
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:1.6.0") implementation("org.mongodb:bson-kotlinx:5.3.0")
Maven を使用している場合 依存関係を管理するには、次のものをpom.xml
依存関係リストに追加します。
<dependency> <groupId>org.jetbrains.kotlinx</groupId> <artifactId>kotlinx-serialization-core</artifactId> <version>1.6.0</version> </dependency> <dependency> <groupId>org.mongodb</groupId> <artifactId>bson-kotlinx</artifactId> <version>5.3.0</version> </dependency>
データクラスの注釈
クラスをシリアル化可能として宣言するには、 Kotlin シリアル化フレームワークからの@Serializable
アノテーションで Kotlin データクラスを注釈を付けます。
データ クラスは、シリアル化可能としてマークすると、コード内で通常どおり使用できます。 Kotlin ドライバーと Kotlin 直列化フレームワークは BSON の直列化と逆直列化を処理します。
この例では、次の注釈が付けられた単純なデータ クラスを示しています。
@Serializable
クラスをシリアル化可能なものとしてマークします。@SerialName
で、BSON ドキュメント内の プロパティと プロパティの名前を指定します。id
manufacturer
これは、シリアル化可能なクラスでサポートされていない@BsonId
と@BsonProperty
アノテーションの代わりに使用できます。@Contextual
BSONid
プロパティをマークし、組み込みのObjectIdSerializer
を使用します。 この注釈は、BSON types を正しく直列化するのに必要です。
data class PaintOrder( // Use instead of @BsonId val id: ObjectId?, val color: String, val qty: Int, val manufacturer: String = "Acme" // Use instead of @BsonProperty )
注意
@Serializable
データクラスではorg.bson.codecs.pojo.annotations
パッケージの注釈は使用できません。
シリアル化可能なクラスと利用可能な注釈クラスの詳細については、 公式の Kotlin 直列化 を参照してください。 ドキュメント。
カスタムシリアライザーの例
BSON でのデータの表現方法を処理するカスタム シリアライザーを作成できます。 Kotlin ドライバーは、 kotlinx.serialization
パッケージのKSerializer
インターフェースを使用してカスタム シリアライザーを実装します。 特定のフィールドの@Serializable
アノテーションのパラメータとしてカスタム シリアライザーを指定できます。
次の例は、カスタムKSerializer
インスタンスを作成して、 kotlinx.datetime.Instant
をBsonDateTime
に変換する方法を示しています。
object InstantAsBsonDateTime : KSerializer<Instant> { override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("InstantAsBsonDateTime", PrimitiveKind.LONG) override fun serialize(encoder: Encoder, value: Instant) { when (encoder) { is BsonEncoder -> encoder.encodeBsonValue(BsonDateTime(value.toEpochMilliseconds())) else -> throw SerializationException("Instant is not supported by ${encoder::class}") } } override fun deserialize(decoder: Decoder): Instant { return when (decoder) { is BsonDecoder -> Instant.fromEpochMilliseconds(decoder.decodeBsonValue().asDateTime().value) else -> throw SerializationException("Instant is not supported by ${decoder::class}") } } }
次のコードは、 orderDate
フィールドが、前のコードで定義されたカスタム シリアライザー クラスを指定する注釈を持つPaintOrder
データクラスを示しています。
data class PaintOrder( val color: String, val qty: Int, val orderDate: Instant, )
このセクションで説明されるメソッドとクラスの詳細については、次の API ドキュメントを参照してください。
シリアライザー構成をカスタマイズする
org.bson.codecs.kotlinx
パッケージのKotlinSerializerCodec
クラスを使用して、 @Serializable
データ クラスのコーデックを作成し、保存する内容をカスタマイズできます。
BsonConfiguration
クラスを使用して、デフォルトをエンコードするか、null をエンコードするか、クラス弁別子を定義するかなどの構成を定義します。
カスタム コーデックを作成するには、プロジェクトにbson-kotlinx
依存関係をインストールします。 GradleとMavenパッケージ マネージャーを使用してプロジェクトに依存関係を追加する方法を確認するには、次のタブから を選択します。
Gradle を使用している場合 依存関係を管理するには、次のものをbuild.gradle.kts
依存関係リストに追加します。
implementation("org.mongodb:bson-kotlinx:5.3.0")
Maven を使用している場合 依存関係を管理するには、次のものをpom.xml
依存関係リストに追加します。
<dependency> <groupId>org.jetbrains.kotlinx</groupId> <artifactId>bson-kotlinx</artifactId> <version>5.3.0</version> </dependency>
注意
bson-kotlin 依存関係
オプションで、デフォルトのコーデック レジストリを使用してbson-kotlin
依存関係をインストールすることもできます。 この依存関係はリフレクションとコーデック レジストリを使用して Kotlin データ クラスをサポートしていますが、 BsonDiscriminator
、 BsonExtraElements
、 BsonConstructor
などの特定の POJO 注釈はサポートしていません。 詳細については、 bson-kotlin API ドキュメント を参照してください。
一般的に、コーデック構成には高速なbson-kotlinx
ライブラリをインストールして使用することをお勧めします。
次に、 KotlinSerializerCodec.create() メソッド を使用してコーデックを定義できますメソッドを使用して、それをレジストリに追加します。
カスタム Codec の例
次の例は、 KotlinSerializerCodec.create()
メソッドを使用してコーデックを作成し、デフォルトをエンコードしないように構成する方法を示しています。
import org.bson.codecs.configuration.CodecRegistries import org.bson.codecs.kotlinx.BsonConfiguration import org.bson.codecs.kotlinx.KotlinSerializerCodec
val myCustomCodec = KotlinSerializerCodec.create<PaintOrder>( bsonConfiguration = BsonConfiguration(encodeDefaults = false) ) val registry = CodecRegistries.fromRegistries( CodecRegistries.fromCodecs(myCustomCodec), collection.codecRegistry )
このセクションで説明されるメソッドとクラスの詳細については、次の API ドキュメントを参照してください。
多形直列化
Kotlin ドライバーは、多形クラスの直列化と逆直列化をネイティブでサポートしています。 シード処理されたインターフェースと、そのインターフェースを継承するデータ クラスを@Serializable
アノテーションでマークすると、ドライバーはKSerializer
実装を使用して BSON との間で型の変換を処理します。
多形データ クラスのインスタンスを MongoDB に挿入すると、ドライバーは弁別子フィールドであるフィールド_t
を追加します。 このフィールドの値は、データ クラス名です。
多形データ クラスの例
次の例では、インターフェースと、そのインターフェースを継承する 2 つのデータ クラスを作成します。 データ クラスでは、 id
フィールドは、「データ クラスの注釈」セクションで説明されている注釈でマークされます。
sealed interface Person { val name: String } data class Student( val id: ObjectId, override val name: String, val grade: Int, ) : Person data class Teacher( val id: ObjectId, override val name: String, val department: String, ) : Person
その後は、データ クラスを使用した操作を通常どおり実行できます。 次の例では、コレクションをPerson
インターフェースでパラメータ化し、多形クラスTeacher
とStudent
を使用して操作を実行します。 ドキュメントを検索すると、ドライバーは弁別子の値に基づいて型を自動的に検出し、それに応じて逆直列化します。
val collection = database.getCollection<Person>("school") val teacherDoc = Teacher(ObjectId(), "Vivian Lee", "History") val studentDoc = Student(ObjectId(), "Kate Parker", 10) collection.insertOne(teacherDoc) collection.insertOne(studentDoc) println("Retrieving by using data classes") collection.withDocumentClass<Teacher>() .find(Filters.exists("department")) .first().also { println(it) } collection.withDocumentClass<Student>() .find(Filters.exists("grade")) .first().also { println(it) } println("\nRetrieving by using Person interface") val resultsFlow = collection.withDocumentClass<Person>().find() resultsFlow.collect { println(it) } println("\nRetrieving as Document type") val resultsDocFlow = collection.withDocumentClass<Document>().find() resultsDocFlow.collect { println(it) }
Retrieving by using data classes Teacher(id=..., name=Vivian Lee, department=History) Student(id=..., name=Kate Parker, grade=10) Retrieving by using Person interface Teacher(id=..., name=Vivian Lee, department=History) Student(id=..., name=Kate Parker, grade=10) Retrieving as Document type Document{{_id=..., _t=Teacher, name=Vivian Lee, department=History}} Document{{_id=..., _t=Student, name=Kate Parker, grade=10}}
日付と時刻を直列化
このセクションでは、 Kotlin 直列化 を使用して日付型および時刻型を操作する方法を学習できます。
kotlinx-datetime ライブラリ
kotlinx-datetime
は、日付と時刻の値が直列化される方法を高レベルで制御する Kotlin ライブラリです。 ライブラリを使用するには、 kotlinx-datetime
依存関係をプロジェクトの依存関係リストに追加します。
次のタブから選択して、 Gradle } パッケージ マネージャーとMavenパッケージ マネージャーを使用してプロジェクトにkotlinx-datetime
依存関係を追加する方法を確認します。
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.1")
<dependency> <groupId>org.jetbrains.kotlinx</groupId> <artifactId>kotlinx-datetime-jvm</artifactId> <version>0.6.1</version> </dependency>
このライブラリの詳細については、 kotlinx-datetime リポジトリ Githubを参照してください。 .
日付と時刻を含むサンプルデータクラス
ライブラリの依存関係を追加したら、 kotlinx-datetime
ライブラリからデータクラス フィールド値を BSON で期待される型にマッピングするシリアライザーを実装できます。
この例では、ドライバーはAppointment
データ クラスのフィールドを次の動作で直列化します。
name
: ドライバーは値を string として直列化します。date
: フィールドに@Contextual
アノテーションがあるため、ドライバーはkotlinx-datetime
ライザーを使用します。LocalDate
値は BSON 日付としてシリアル化されます。time
:@Contextual
注釈がないため、ドライバーは値を string として直列化します。 これは、LocalTime
値のデフォルトの直列化動作です。
data class Appointment( val name: String, val date: LocalDate, val time: LocalTime, )
次の例では、 Appointment
データ クラスのインスタンスをappointments
コレクションに挿入します。
val collection = database.getCollection<Appointment>("appointments") val apptDoc = Appointment( "Daria Smith", LocalDate(2024, 10, 15), LocalTime(hour = 11, minute = 30) ) collection.insertOne(apptDoc)
MongoDB では、 LocalDate
値は BSON 日付として保存され、 time
フィールドはデフォルトの直列化で string として保存されます。
{ "_id": ..., "name": "Daria Smith", "date": { "$date": "2024-10-15T00:00:00.000Z" }, "time": "11:30", }