Menu Docs
Página inicial do Docs
/ / /
Driver de Kotlin Sync
/

Serialização Kotlin

Nesta página

  • Visão geral
  • Tipos suportados
  • Adicionar as dependências de serialização ao seu projeto
  • Anotar classes de dados
  • Exemplo de serializador personalizado
  • Personalizar a Configuração do Serializador
  • Exemplo de codec personalizado
  • Serialização polimórfica
  • Exemplo de classes de dados polimórficos
  • Serialize datas e horários
  • Biblioteca kotlinx-datetime
  • Classe de dados de exemplo com datas e horários

Você pode usar a biblioteca kotlinx.serialization ao serializar e desserializar objetos Kotlin em seu aplicação.

O driver fornece um serializador Bson eficiente que você pode usar com classes marcadas com a anotação @Serializable para lidar com a serialização de objetos Kotlin em dados BSON.

Embora você possa usar a Kotlin biblioteca de serialização Json , o Json serializador não oferece suporte direto a BSON tipos de valor , como ObjectId. Você deve fornecer um serializador personalizado que possa lidar com a conversão entre BSON e JSON.

Recomendamos instalar a biblioteca bson-kotlinx para oferecer suporte a codecs personalizados que tenham configurações para codificar padrões, nulos e definir discriminadores de classe .

Observação

Para saber como usar a interface Codec em vez da biblioteca kotlinx.serialization para especificar o comportamento de serialização personalizada, consulte o guiaCodecs .

Você pode optar por usar a serialização do Kotlin se já estiver familiarizado com a biblioteca ou se preferir usar uma abordagem idiomática.

O driver do Kotlin Sync é compatível com os seguintes tipos:

  • Todos os tipos de Kotlin suportados pela biblioteca kotlinx.serialization

  • Todos osBSON types

Você deve instalar a biblioteca oficial de serialização Kotlin , kotlinx.serialization, para serializar e desserializar dados em seu aplicação. Para saber mais sobre essa biblioteca, consulte o kotlinx.Github repositório de serialização .

Selecione a partir das seguintes abas para ver como adicionar as dependências de serialização ao seu projeto usando Gradle ou Maven:

Se você estiver usando o Gradle para gerenciar suas dependências, adicione o seguinte à sua build.gradle.kts lista de dependências do :

build.gradle.kts
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:1.5.1")
implementation("org.mongodb:bson-kotlinx:5.2.0")

Se você estiver usando o Maven para gerenciar suas dependências, adicione o seguinte à sua pom.xml lista de dependências do :

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>

Observação

bson-kotlin Dependency

Você também pode opcionalmente instalar a dependência do bson-kotlin através do registro de codec padrão. Essa dependência usa a reflexão e o registro do codec para oferecer suporte a classes de dados Kotlin, mas não oferece suporte a determinadas anotações POJO, como BsonDiscriminator, BsonExtraElementse BsonConstructor. Para saber mais, consulte a documentação da API bson-kotlin.

Geralmente, recomendamos que instale e utilize a biblioteca bson-kotlinx mais rápida para configuração de codec.

Para declarar uma classe como serializável, anote suas classes de dados do Kotlin com a anotação @Serializable .

Você pode usar suas classes de dados em seu código da mesma forma que usa qualquer outra classe de dados depois de marcá-las como serializáveis. O driver Kotlin Sync e a estrutura de serialização do Kotlin lidam com serialização e desserialização BSON.

Este exemplo mostra uma classe de dados de amostra com as seguintes anotações:

  • @Serializable: Marca a classe como serializável.

  • @SerialName: especifica o nome das propriedades id e manufacturer no documento BSON. Esta anotação pode ser utilizada no lugar das anotações do @BsonId e @BsonProperty , que não são suportadas em classes serializáveis.

  • @Contextual: marca a propriedade BSON id para usar o ObjectIdSerializer. Essa anotação é necessária para que o driver serialize os BSON types corretamente.

@Serializable
data class PaintOrder(
@SerialName("_id") // Use instead of @BsonId
@Contextual val id: ObjectId?,
val color: String,
val qty: Int,
@SerialName("brand")
val manufacturer: String = "Grumbacher" // Use instead of @BsonProperty
)

Observação

Limitação de anotações POJO

Você não pode utilizar anotações do pacote org.bson.codecs.pojo.annotations em uma classe de dados marcada com a anotação @Serializable .

Para saber mais sobre classes serializáveis e anotações disponíveis, consulte Classes serializáveis na kotlinx.serialization documentação da biblioteca .

Você pode criar um serializador personalizado para lidar com como seus dados são representados no BSON. O driver Kotlin Sync usa a interface KSerializer da biblioteca kotlinx.serialization para implementar serializadores personalizados. Você pode especificar o serializador customizado como parâmetro para a anotação @Serializable para um campo específico.

O exemplo abaixo mostra como criar uma instância personalizada do KSerializer para converter um kotlinx.datetime.Instant para um 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}")
}
}
}

O código abaixo mostra a classe de dados PaintOrder na qual o campo orderDate tem uma anotação que especifica a classe de serializador personalizado definida no código anterior:

@Serializable
data class PaintOrder(
val color: String,
val qty: Int,
@Serializable(with = InstantAsBsonDateTime::class)
val orderDate: Instant,
)

Para saber mais sobre os métodos e as classes mencionadas nesta seção, consulte a seguinte documentação da API:

Você pode usar a classe KotlinSerializerCodec do pacote org.bson.codecs.kotlinx para criar um codec para suas classes de dados do @Serializable e personalizar o que o driver armazena no MongoDB.

Use a classe BsonConfiguration para definir a configuração, que pode incluir se deseja codificar padrões, codificar nulos ou definir discriminadores de classe .

Para criar um codec personalizado, seu projeto deve ter a dependência bson-kotlinx . Consulte a seção Adicionar as dependências de serialização ao seu projeto deste guia para obter instruções de instalação.

Você pode definir seu codec usando o arquivo KotlinSerializerCodec.create() método, então você pode adicionar o codec ao registro.

O exemplo seguinte mostra como criar um codec utilizando o método KotlinSerializerCodec.create() e, em seguida, configurá-lo para não codificar padrões:

val myCustomCodec = KotlinSerializerCodec.create<PaintOrder>(
bsonConfiguration = BsonConfiguration(encodeDefaults = false)
)
val registry = CodecRegistries.fromRegistries(
CodecRegistries.fromCodecs(myCustomCodec), collection.codecRegistry
)

Para saber mais sobre os métodos e as classes mencionadas nesta seção, consulte a seguinte documentação da API:

O driver Kotlin Sync suporta nativamente serialização e desserialização de classes polimórficas. Quando você marca uma interface selada e classes de dados que herdam essa interface com a anotação @Serializable , o driver usa uma implementação KSerializer para lidar com a conversão de seus tipos de e para BSON.

Quando você insere uma instância de uma classe de dados polimórficos no MongoDB, o driver adiciona o campo _t, o campo discriminador. O valor deste campo é o nome da classe de dados.

O exemplo seguinte cria uma interface e duas classes de dados que herdam esta interface. Nas classes de dados, o campo id é marcado com as anotações descritas na seção Anotar Classes de Dados :

@Serializable
sealed interface Person {
val name: String
}
@Serializable
data class Student(
@Contextual
@SerialName("_id")
val id: ObjectId,
override val name: String,
val grade: Int,
) : Person
@Serializable
data class Teacher(
@Contextual
@SerialName("_id")
val id: ObjectId,
override val name: String,
val department: String,
) : Person

Em seguida, você pode executar operações com classes de dados como de costume. O exemplo a seguir parametriza a coleção com a interface Person e, em seguida, executa operações com as classes polimórficas Teacher e Student. Ao recuperar documentos, o driver detecta automaticamente o tipo com base no valor do discriminador e os desserializa adequadamente.

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}}

Nesta seção, você pode aprender sobre como usar a serialização do Kotlin para trabalhar com tipos de data e hora.

kotlinx-datetime é uma biblioteca Kotlin que oferece um alto nível de controle sobre como seus valores de data e hora são serializados. Para utilizar a biblioteca, adicione a dependência kotlinx-datetime à lista de dependência do seu projeto.

Selecione a partir das seguintes guias para ver como adicionar a dependência do kotlinx-datetime ao seu projeto utilizando os gerenciadores de pacote Gradle e Maven :

build.gradle.kts
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.1")
pom.xml
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-datetime-jvm</artifactId>
<version>0.6.1</version>
</dependency>

Para saber mais sobre esta biblioteca, consulte o repositório kotlinx-datetime no Github.

Após adicionar a dependência da biblioteca, você pode implementar serializadores da biblioteca do kotlinx-datetime que mapeiam seus valores de campo de classe de dados para os tipos esperados no BSON.

Neste exemplo, o driver serializa os campos da classe de dados Appointment com o seguinte comportamento:

  • name: o driver serializa o valor como uma string.

  • date: o driver utiliza o serializador kotlinx-datetime porque o campo tem a anotação @Contextual . LocalDate valores são serializados como datas BSON.

  • time: o driver serializa o valor como uma string porque ele não tem a anotação @Contextual . Este é o comportamento de serialização padrão para valores LocalTime .

@Serializable
data class Appointment(
val name: String,
@Contextual val date: LocalDate,
val time: LocalTime,
)

O exemplo seguinte insere uma instância da classe de dados Appointment na coleção appointments :

val collection = database.getCollection<Appointment>("appointments")
val apptDoc = Appointment(
"Daria Smith",
LocalDate(2024, 10, 15),
LocalTime(hour = 11, minute = 30)
)
collection.insertOne(apptDoc)

No MongoDB, o valor LocalDate é armazenado como uma data BSON e o campo time é armazenado como uma string por serialização padrão:

{
"_id": ...,
"name": "Daria Smith",
"date": {
"$date": "2024-10-15T00:00:00.000Z"
},
"time": "11:30",
}

Voltar

Formatos de dados especializados