如何用注解将Kotlin数据类存入DynamoDB及获取对应Kotlin SDK
核心问题
- 无法将自定义Kotlin数据类直接传入
PutItemRequest的item字段 - 不清楚如何获取适配Kotlin的DynamoDB SDK版本
- 疑惑该实现是否和Android Room的转换器逻辑一致
现有代码的问题
你当前混合使用了旧版AWS Java SDK(com.amazonaws:aws-java-sdk-dynamodb)和新版AWS Kotlin SDK(aws.sdk.kotlin:dynamodb),两者API体系不兼容;同时仅用@DynamoDBAttribute注解无法直接让数据类转为DynamoDB所需的Map<String, AttributeValue>类型。
正确实现方式
方案1:使用新版AWS Kotlin SDK的序列化(推荐)
新版Kotlin SDK支持用kotlinx.serialization直接序列化数据类,无需依赖旧Java SDK的注解:
步骤1:调整数据类与依赖
删除旧Java SDK依赖,只保留Kotlin SDK和序列化相关依赖:
// build.gradle.kts implementation("aws.sdk.kotlin:dynamodb:$awsVersion") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")
数据类仅保留@Serializable注解:
import kotlinx.serialization.Serializable @Serializable data class Item( val name: String = "", val id: String = "", val stuff: String = "" )
步骤2:序列化数据类为DynamoDB Item
使用Kotlin SDK的扩展函数将数据类转为Map<String, AttributeValue>:
import aws.sdk.kotlin.services.dynamodb.model.AttributeValue import aws.sdk.kotlin.services.dynamodb.model.PutItemRequest import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonPrimitive suspend fun putItemInTable() { val item = Item(name = "Test", id = "123", stuff = "Sample") // 序列化数据类为DynamoDB所需的AttributeValue映射 val itemMap = Json.encodeToString(item).let { jsonStr -> Json.parseToJsonElement(jsonStr).jsonObject.mapValues { (_, value) -> AttributeValue.SBuilder().s(value.jsonPrimitive.content).build() } } val request = PutItemRequest { tableName = "table" item = itemMap } DynamoDbClient { region = AWS_REGION }.use { ddb -> ddb.putItem(request) println("新条目已存入") } }
方案2:使用旧版Java SDK的DynamoDBMapper(兼容原有注解)
如果要保留@DynamoDBAttribute等注解,需使用旧Java SDK的DynamoDBMapper,但要注意与Kotlin SDK的API隔离:
步骤1:调整依赖与数据类
保留旧Java SDK依赖,数据类添加@DynamoDBTable注解并指定表名:
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable @DynamoDBTable(tableName = "table") data class Item( @DynamoDBAttribute var name: String = "", @DynamoDBAttribute var id: String = "", @DynamoDBAttribute var stuff: String = "" )
步骤2:用DynamoDBMapper执行写入
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper suspend fun putItemInTable() { val item = Item(name = "Test", id = "123", stuff = "Sample") val ddbClient = AmazonDynamoDBClientBuilder.standard().withRegion(AWS_REGION).build() val mapper = DynamoDBMapper(ddbClient) mapper.save(item) println("新条目已存入") }
关于AWS Java SDK DynamoDB的Kotlin版本
不存在单独的aws-java-sdk-dynamodb Kotlin版本,AWS官方提供的AWS SDK for Kotlin是专门为Kotlin设计的独立SDK,对应的DynamoDB依赖就是aws.sdk.kotlin:dynamodb,它完全基于Kotlin协程,API更符合Kotlin习惯。
与Android Room的差异
和Room的转换器逻辑不一样:Room是通过注解直接生成数据库操作代码,自动完成对象与数据库行的映射;而DynamoDB需要显式通过序列化工具(如Kotlin SDK的序列化)或DynamoDBMapper来完成对象到AttributeValue的映射,无法直接将数据类赋值给PutItemRequest的item字段。
内容的提问来源于stack exchange,提问作者Psijic

