Docs Menu
Docs Home
/ / /
Kotlin Sync 드라이버
/

코덱

이 페이지의 내용

  • 개요
  • 코덱
  • 인코딩() 메서드
  • Decode() 메서드
  • 예시
  • CodecRegistry
  • CodecProvider
  • 기본 코덱 레지스트리
  • BsonTypeClassMap
  • 사용자 지정 코덱 예시

이 가이드 에서는 BSON 데이터에 대한 코틀린 (Kotlin) 객체의 인코딩 및 디코딩을 처리하다 하는 코덱 및 지원 클래스에 학습 수 있습니다. Codec 추상화를 사용하면 모든 코틀린 (Kotlin) 유형을 해당 BSON 에 매핑할 수 있습니다. 이 기능 을 사용하면 Document 또는 BsonDocument 과 같은 클래스를 사용하는 대신 도메인 객체를 BSON 에 직접 매핑할 수 있습니다.

Codec 추상화를 사용하여 맞춤 인코딩 및 디코딩 로직을 지정하는 방법을 알아보고 다음 섹션에서 구현 예시를 볼 수 있습니다.

  • 코덱

  • CodecRegistry

  • CodecProvider

  • 사용자 지정 코덱 예시

코틀린(Kotlin) 직렬화

사용자 지정 코덱을 구현하는 대신 코틀린 (Kotlin) 직렬화를 사용하여 @Serializable 클래스로 데이터 인코딩 및 디코딩을 처리하다 할 수 있습니다. kotlinx.serialization 라이브러리에 이미 익숙하거나 관용적 인 코틀린 (Kotlin) 접근 방식을 선호하는 경우 코틀린 (Kotlin) 직렬화를 선택할 수 있습니다. 학습 내용은 코틀린 (Kotlin) 직렬화 가이드 를 참조하세요.

Codec 인터페이스에는 코틀린( 코틀린 (Kotlin) ) 객체를 BSON 데이터로 직렬화 및 역직렬화하기 위한 추상 메서드가 포함되어 있습니다. 이 인터페이스의 구현 에서 사용자 지정 변환 로직을 정의할 수 있습니다.

Codec 인터페이스를 구현하려면 encode(), decode()getEncoderClass() 추상 메서드를 재정의합니다.

encode() 메서드에는 다음 매개 변수가 필요합니다.

Parameter Type
설명
writer
BSON 문서 작성을 위한 메서드를 노출하는 인터페이스 유형인 BsonWriter를 구현하는 클래스의 인스턴스입니다. 예를 들어, BsonBinaryWriter 구현은 데이터의 바이너리 스트림에 씁니다. 이 인스턴스를 사용하여 적절한 쓰기 메서드를 사용하여 BSON 값을 작성합니다.
value
구현에서 인코딩하는 데이터입니다. 유형은 구현에 할당된 유형 변수와 일치해야 합니다.
encoderContext
현재 값을 MongoDB 컬렉션 에 저장 할지 여부를 포함하여 BSON 으로 인코딩하는 코틀린( 코틀린 (Kotlin) ) 객체 데이터에 대한 메타 정보를 포함합니다.

encode() 메서드는 BsonWriter 인스턴스 를 사용하여 인코딩된 값을 MongoDB 로 보내고 값을 반환하지 않습니다.

decode() 메서드는 BSON 데이터의 값으로 채워진 Kotlin 객체 인스턴스를 반환합니다. 이 메서드에는 다음 매개 변수가 필요합니다.

Parameter Type
설명
reader
BSON 문서를 읽기 위한 메서드를 노출하는 인터페이스 유형인 BsonReader를 구현하는 클래스의 인스턴스입니다. 예를 들어, BsonBinaryReader 구현은 데이터의 바이너리 스트림에서 읽습니다.
decoderContext
코틀린(Kotlin) 객체로 디코딩하는 BSON 데이터에 대한 정보를 포함합니다.

Kotlin은 유형 삭제로 인해 유형을 추론할 수 없으므로 getEncoderClass() 메서드는 Kotlin 클래스의 클래스 인스턴스를 반환합니다.

이 섹션에는 사용자 지정 Codec 인터페이스를 구현 하는 방법을 보여주는 코드 예제가 포함되어 있습니다.

PowerStatus 열거형 에는 전기 스위치의 상태를 나타내는 "ON""OFF" 값이 포함되어 있습니다.

enum class PowerStatus {
ON,
OFF
}

PowerStatusCodec 클래스는 Codec 인터페이스를 구현하여 코틀린 (Kotlin) enum 값을 해당 BSON 부울 값으로 변환합니다. encode() 메서드는 PowerStatus 값을 BSON 부울로 변환하고 decode() 메서드는 반대 방향으로 변환을 수행합니다.

class PowerStatusCodec : Codec<PowerStatus> {
override fun encode(
writer: BsonWriter, value: PowerStatus, encoderContext: EncoderContext
) = writer.writeBoolean(value == PowerStatus.ON)
override fun decode(
reader: BsonReader, decoderContext: DecoderContext)
: PowerStatus {
return when (reader.readBoolean()) {
true -> PowerStatus.ON
false -> PowerStatus.OFF
}
}
override fun getEncoderClass(): Class<PowerStatus> = PowerStatus::class.java
}

CodecRegistryPowerStatusCodec 인스턴스 를 추가할 수 있습니다. 이 페이지의 CodecRegistry 섹션에서 Codec 을(를) 레지스트리에 포함하는 방법을 학습 보세요.

이 섹션에 언급된 클래스 및 인터페이스에 학습 보려면 다음 API 설명서를 참조하세요.

CodecRegistry 은(는) 코틀린 (Kotlin) 클래스를 인코딩 및 디코딩하는 변경할 수 없는 Codec 인스턴스 컬렉션 입니다. 다음 CodecRegistries 클래스 정적 팩토리 메서드 중 하나를 사용하여 연결된 유형에 포함된 Codec 인스턴스에서 CodecRegistry 를 구성할 수 있습니다.

  • fromCodecs(): Codec 인스턴스에서 레지스트리를 생성합니다.

  • fromProviders(): CodecProvider 인스턴스에서 레지스트리를 생성합니다.

  • fromRegistries(): CodecRegistry 인스턴스에서 레지스트리를 생성합니다.

다음 코드는 fromCodecs() 메서드를 사용하여 CodecRegistry 를 구성하는 방법을 보여줍니다.

val codecRegistry = CodecRegistries
.fromCodecs(IntegerCodec(), PowerStatusCodec())

앞의 예시 에서는 CodecRegistry 에 다음 Codec 구현을 할당합니다.

  • IntegerCodec: Codec Integers 을 변환합니다. BSON 패키지 의 일부입니다.

  • PowerStatusCodec: 코틀린 (Kotlin) 열거형 값을 BSON 부울로 변환하는 이전 섹션의 샘플 Codec 입니다.

다음 코드를 사용하여 CodecRegistry 인스턴스 에서 Codec 인스턴스를 조회 할 수 있습니다.

val powerStatusCodec = codecRegistry.get(PowerStatus::class.java)
val integerCodec = codecRegistry.get(Integer::class.java)

등록되지 않은 클래스의 Codec 인스턴스 를 조회 하려고 하면 codecRegistry.get() 메서드에서 CodecConfigurationException 예외가 발생합니다.

이 섹션의 클래스 및 인터페이스에 대한 자세한 내용은 다음 API 설명서를 참조하세요.

CodecProviderCodec 인스턴스를 생성하고 이를 CodecRegistry 인스턴스에 할당하는 추상 메서드가 포함된 인터페이스입니다. CodecRegistry 인터페이스와 유사하게, BSON 라이브러리는 CodecProvider.get() 메서드로 조회된 Codec 인스턴스를 사용하여 코틀린( 코틀린 (Kotlin) )과 BSON 데이터 유형을 서로 변환합니다.

그러나 해당 Codec 객체가 필요한 필드가 포함된 클래스를 추가하는 경우 전체 클래스에 대해 Codec 를 인스턴스화하기 전에 클래스의 필드에 대해 Codec 객체를 인스턴스화해야 합니다. CodecProvider.get() 메서드의 CodecRegistry 매개변수를 사용하여 Codec 가 의존하는 Codec 인스턴스를 전달할 수 있습니다.

Codec 클래스를 사용한 읽기 및 쓰기 (write) 작업을 보여주는 실행 가능한 예시 를 보려면 이 가이드 의 사용자 지정 코덱 예제 섹션을 참조하세요.

기본값 코덱 레지스트리는 일반적으로 사용되는 코틀린 (Kotlin) 객체와 MongoDB 유형 간의 변환을 지정하는 CodecProvider 클래스 설정하다 입니다. 다른 코덱 레지스트리를 지정하지 않는 한 운전자 는 자동으로 기본값 코덱 레지스트리를 사용합니다.

하나 이상의 Codec 클래스의 동작을 재정의하고 다른 클래스의 기본값 코덱 레지스트리의 동작은 유지하려면 우선 순위에 따라 레지스트리를 지정할 수 있습니다. 예를 예시 , 열거형 유형에 대한 Codec 의 기본값 제공자 동작을 사용자 지정 MyEnumCodec 으)로 재정의한다고 가정해 보겠습니다. 다음 예시 와 같이 기본값 코덱 레지스트리 앞의 위치에 있는 레지스트리 목록에 추가해야 합니다.

val newRegistry = CodecRegistries.fromRegistries(
CodecRegistries.fromCodecs(MyEnumCodec()),
MongoClientSettings.getCodecRegistry()
)

이 섹션의 클래스 및 인터페이스에 대한 자세한 내용은 다음 API 설명서를 참조하세요.

BsonTypeClassMap 클래스에는 BSON 과 코틀린 (Kotlin) 유형 간의 권장 매핑이 포함되어 있습니다. 사용자 Codec CodecProvider 지정 또는 Kotlin BSON types 에서 이 클래스를 사용하면 을 디코딩할 유형을 관리 하는 데 도움이 될 수 있습니다. 여기에는 Document 클래스와 같이 Iterable 또는 Map 를 구현 하는 컨테이너 클래스도 포함되어 있습니다.

새 항목이나 대체 항목이 포함된 Map를 전달하여 BsonTypeClassMap 기본 매핑을 추가하거나 수정할 수 있습니다.

다음 코드는 기본값 BsonTypeClassMap 인스턴스 에서 BSON 배열 유형에 해당하는 코틀린 (Kotlin) 클래스 유형을 조회 하는 방법을 보여줍니다.

val bsonTypeClassMap = BsonTypeClassMap()
val clazz = bsonTypeClassMap[BsonType.ARRAY]
println("Kotlin class name: " + clazz.name)
Kotlin class name: java.util.List

BsonTypeClassMap 생성자에 대체 항목을 지정하여 인스턴스 에서 이러한 매핑을 수정할 수 있습니다. 다음 코드 스니펫은 BsonTypeClassMap 인스턴스 의 BSON 배열 유형에 대한 매핑을 Set 클래스로 대체하는 방법을 보여줍니다.

val replacements = mutableMapOf<BsonType, Class<*>>(BsonType.ARRAY to MutableSet::class.java)
val bsonTypeClassMap = BsonTypeClassMap(replacements)
val clazz = bsonTypeClassMap[BsonType.ARRAY]
println("Class name: " + clazz.name)
Kotlin class name: java.util.Set

기본값 매핑의 전체 목록은 BsonTypeClassMap 을 참조하세요. API 문서.

이 섹션에서는 CodecCodecProvider 인터페이스를 구현 하여 사용자 지정 코틀린 (Kotlin) 클래스에 대한 인코딩 및 디코딩 로직을 정의하는 방법을 설명합니다. 사용자 지정 구현을 지정하고 사용하여 읽기 및 쓰기 (write) 작업을 수행하는 방법을 보여 줍니다.

다음 코드는 샘플 데이터 클래스 Monolight 를 정의합니다.

data class Monolight(
var powerStatus: PowerStatus = PowerStatus.OFF,
var colorTemperature: Int? = null
) {
override fun toString():
String = "Monolight { powerStatus: $powerStatus, colorTemperature: $colorTemperature }"
}

이 클래스에는 인코딩 및 디코딩을 처리하다 하기 위해 각각 해당 Codec 가 필요한 다음 필드가 포함되어 있습니다.

  • powerStatus: 장치 표시등이 "ON" 인지 "OFF" 인지 설명합니다. 이 필드 의 경우 PowerStatus 열거형 값을 BSON 부울로 변환하는 PowerStatusCodec 을 사용합니다.

  • colorTemperature: 장치 표시등의 색상을 Int 값으로 켈빈 단위로 설명합니다. 이 필드 에는 BSON 라이브러리에 제공된 IntegerCodec 를 사용합니다.

The following code shows how to implement a Codec for the Monolight class. The constructor expects an instance of CodecRegistry from which it retrieves the Codec instances needed to encode and decode the class fields:

class MonolightCodec(registry: CodecRegistry) : Codec<Monolight> {
private val powerStatusCodec: Codec<PowerStatus>
private val integerCodec: Codec<Int>
init {
powerStatusCodec = registry[PowerStatus::class.java]
integerCodec = IntegerCodec()
}
override fun encode(writer: BsonWriter, value: Monolight, encoderContext: EncoderContext) {
writer.writeStartDocument()
writer.writeName("powerStatus")
powerStatusCodec.encode(writer, value.powerStatus, encoderContext)
writer.writeName("colorTemperature")
integerCodec.encode(writer, value.colorTemperature, encoderContext)
writer.writeEndDocument()
}
override fun decode(reader: BsonReader, decoderContext: DecoderContext): Monolight {
val monolight = Monolight()
reader.readStartDocument()
while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) {
when (reader.readName()) {
"powerStatus" -> monolight.powerStatus =
powerStatusCodec.decode(reader, decoderContext)
"colorTemperature" -> monolight.colorTemperature =
integerCodec.decode(reader, decoderContext)
"_id" -> reader.readObjectId()
}
}
reader.readEndDocument()
return monolight
}
override fun getEncoderClass(): Class<Monolight> = Monolight::class.java
}

필드의 Codec 인스턴스를 Monolight 클래스에서 사용할 수 있도록 하려면 다음 코드 예시 와 같이 사용자 지정 CodecProvider 를 구현 합니다.

class MonolightCodecProvider : CodecProvider {
@Suppress("UNCHECKED_CAST")
override fun <T> get(clazz: Class<T>, registry: CodecRegistry): Codec<T>? {
return if (clazz == Monolight::class.java) {
MonolightCodec(registry) as Codec<T>
} else null // Return null when not a provider for the requested class
}
}

변환 로직을 정의한 후 다음 조치를 수행할 수 있습니다.

  • MongoDB 에 Monolight 의 인스턴스 저장

  • MongoDB 에서 다음 인스턴스로 문서를 조회합니다. Monolight

다음 코드는 MonolightCodecProviderwithCodecRegistry() 메서드에 전달하여 MongoCollection 인스턴스 에 할당합니다. 또한 예시 클래스는 Monolight 클래스를 사용하여 데이터를 삽입하고 검색합니다.

val mongoClient = MongoClient.create(uri)
val codecRegistry = CodecRegistries.fromRegistries(
CodecRegistries.fromCodecs(IntegerCodec(), PowerStatusCodec()),
CodecRegistries.fromProviders(MonolightCodecProvider()),
MongoClientSettings.getDefaultCodecRegistry()
)
val database = mongoClient.getDatabase("codec_test")
val collection = database.getCollection<Monolight>("monolights")
.withCodecRegistry(codecRegistry)
// Insert instances of Monolight
val monolights = listOf(
Monolight(PowerStatus.ON, 5200),
Monolight(PowerStatus.OFF, 3000)
)
collection.insertMany(monolights)
// Retrieve instances of Monolight
val results = collection.find()
results.forEach { l ->
println(l)
}
Monolight { powerStatus: ON, colorTemperature: 5200 }
Monolight { powerStatus: OFF, colorTemperature: 3000 }

이 섹션에 언급된 메서드 및 클래스에 대한 자세한 내용은 다음 API 문서를 참조하세요.

돌아가기

코틀린(Kotlin) 직렬화