Kotlin 直列化
項目一覧
Overview
アプリケーション内の Kotlin オブジェクトを直列化および逆直列化する場合、 kotlinx.serialization
ライブラリを使用できます。
このドライバーは効率的なBson
シリアライザーを提供し、 @Serializable
アノテーションでマークされたクラスで使用して、 Kotlin オブジェクトの BSON データへの直列化を処理します。
Kotlin シリアル化Json
ライブラリは使用できますが、 Json
シリアライザーはObjectId
などの BSON 値型を直接サポートしていません。 BSON と JSON の間の変換を処理できるカスタム シリアライザーを提供する必要があります。
デフォルト、null、クラス弁別子を定義する構成を持つカスタム コーデックをサポートするために、 bson-kotlinx
ライブラリをインストールすることをお勧めします。
注意
kotlinx.serialization
ライブラリではなくCodec
インターフェースを使用してカスタム シリアル化動作を指定する方法については、 コーデックガイドをご覧ください。
ライブラリについてすでに知っている場合、または慣用的なアプローチを使用したい場合は、 Kotlin シリアル化を使用することを選択してください 。
サポートされているタイプ
Kotlin Syncドライバーは次のタイプをサポートしています。
kotlinx.serialization
ライブラリでサポートされているすべての Kotlin 型すべての BSON types
プロジェクトに直列化の依存関係を追加する
アプリケーション内のデータを直列化および逆直列化するには、公式の Kotlin 直列化ライブラリであるkotlinx.serialization
をインストールする必要があります。 このライブラリの詳細については、 kotlinx.serializationGithub リポジトリ を参照してください。
GradleまたはMavenを使用してプロジェクトにシリアル化の依存関係を追加する方法を確認するには、次のタブから選択します。
Gradle を使用している場合 依存関係を管理するには、次のものをbuild.gradle.kts
依存関係リストに追加します。
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:1.5.1") implementation("org.mongodb:bson-kotlinx:5.2.0")
Maven を使用している場合 依存関係を管理するには、次のものをpom.xml
依存関係リストに追加します。
<dependency> <groupId>org.jetbrains.kotlinx</groupId> <artifactId>kotlinx-serialization-core</artifactId> <version>1.5.1</version> </dependency> <dependency> <groupId>org.mongodb</groupId> <artifactId>bson-kotlinx</artifactId> <version>5.2.0</version> </dependency>
注意
bson-kotlin 依存関係
オプションで、デフォルトのコーデック レジストリを使用してbson-kotlin
依存関係をインストールすることもできます。 この依存関係はリフレクションとコーデック レジストリを使用して Kotlin データ クラスをサポートしていますが、 BsonDiscriminator
、 BsonExtraElements
、 BsonConstructor
などの特定の POJO 注釈はサポートしていません。 詳細については、 bson-kotlin API ドキュメント を参照してください。
一般的に、コーデック構成には高速なbson-kotlinx
ライブラリをインストールして使用することをお勧めします。
データクラスの注釈
クラスをシリアル化可能として宣言するには、 Kotlin データクラスに@Serializable
アノテーションを付けます。
You can use your data classes in your code as you use any other data class after you mark them as serializable. Kotlin Sync ドライバーと Kotlin 直列化フレームワークは、BSON の直列化と逆直列化を取り扱います。
この例では、次の注釈を持つサンプル データ クラスを示しています。
@Serializable
: クラスをシリアル化可能としてマークします。@SerialName
:id
manufacturer
BSON ドキュメント内の プロパティと プロパティの名前を指定します。この注釈は、シリアル化可能なクラスでサポートされていない@BsonId
と@BsonProperty
注釈の代わりに使用できます。@Contextual
: 組み込みのObjectIdSerializer
を使用するために BSONid
プロパティをマークします。 この注釈は、ドライバーが BSON types を正しく直列化するのに必要です。
data class PaintOrder( // Use instead of @BsonId val id: ObjectId?, val color: String, val qty: Int, val manufacturer: String = "Grumbacher" // Use instead of @BsonProperty )
注意
POJO 注釈の制限
@Serializable
アノテーションでマークされたデータクラスでは、 org.bson.codecs.pojo.annotations
パッケージの注釈は使用できません。
直列化可能なクラスと利用可能な注釈の詳細については、「 直列化 可能なクラスkotlinx.serialization
」を参照してください。 ( ライブラリのドキュメントを参照してください)。
カスタムシリアライザーの例
BSON でのデータの表現方法を処理するカスタム シリアライザーを作成できます。 Kotlin Sync ドライバーは、 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.toEpochMilli())) else -> throw SerializationException("Instant is not supported by ${encoder::class}") } } override fun deserialize(decoder: Decoder): Instant { return when (decoder) { is BsonDecoder -> Instant.ofEpochMilli(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 ドキュメントを参照してください。
KSerializer Kotlin ドキュメント内
インスタンス Kotlin ドキュメント内
シリアライザー構成をカスタマイズする
org.bson.codecs.kotlinx
パッケージのKotlinSerializerCodec
クラスを使用して、 @Serializable
データクラスのコーデックを作成し、ドライバーが MongoDB に保存する内容をカスタマイズできます。
BsonConfiguration
クラスを使用して構成を定義します。これには、デフォルトをエンコードするか、null をエンコードするか、クラス弁別子を定義するかどうかが含まれます。
カスタム コーデックを作成するには、プロジェクトにbson-kotlinx
依存関係が必要です。 インストール手順については、このガイドの「 プロジェクトへの直列化依存関係の追加 」セクションを参照してください。
コーデックを定義するには、 KotlinSerializerCodec.create()メソッドを使用すると、コーデックをレジストリに追加できます。
カスタム Codec の例
次の例は、 KotlinSerializerCodec.create()
メソッドを使用してコーデックを作成し、デフォルトをエンコードしないように構成する方法を示しています。
val myCustomCodec = KotlinSerializerCodec.create<PaintOrder>( bsonConfiguration = BsonConfiguration(encodeDefaults = false) ) val registry = CodecRegistries.fromRegistries( CodecRegistries.fromCodecs(myCustomCodec), collection.codecRegistry )
このセクションで説明されるメソッドとクラスの詳細については、次の API ドキュメントを参照してください。
多形直列化
Kotlin Sync ドライバーは、多形クラスの直列化と逆直列化をネイティブでサポートしています。 シード処理されたインターフェースと、そのインターフェースを継承するデータ クラスを@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") val resultTeacher = collection.withDocumentClass<Teacher>() .find(Filters.exists("department")) .firstOrNull() println(resultTeacher) val resultStudent = collection.withDocumentClass<Student>() .find(Filters.exists("grade")) .firstOrNull() println(resultStudent) println("\nRetrieving by using Person interface") val resultsPerson = collection.withDocumentClass<Person>().find() resultsPerson.forEach { result -> println(result) } println("\nRetrieving as Document type") val resultsDocument = collection.withDocumentClass<Document>().find() resultsDocument.forEach { result -> println(result) }
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", }