Kotlin中DynamoDB事务向动态命名多表写入数据的实现问题
DynamoDB Mapper多表事务动态表名解决方案
你可以通过以下两种方案实现保留对象映射能力的前提下,支持事务内多表动态表名配置:
方案1:为每个写入操作单独指定Mapper配置
TransactionWriteRequest的addPut方法原生支持重载,可以为每一个写入对象单独传入对应的DynamoDBMapperConfig,适配不同对象对应不同动态表名的需求。
代码示例:
// 从环境变量获取当前部署阶段 val stage = System.getenv("STAGE") ?: "local" // 构造AClass对应表的配置 val aTableMapperConfig = DynamoDBMapperConfig.Builder() .withTableNameOverride(DynamoDBMapperConfig.TableNameOverride.withTableNameReplacement("$stage-Table1")) .build() // 构造BClass对应表的配置 val bTableMapperConfig = DynamoDBMapperConfig.Builder() .withTableNameOverride(DynamoDBMapperConfig.TableNameOverride.withTableNameReplacement("$stage-Table2")) .build() // 构造事务请求 val transactionWriteRequest = TransactionWriteRequest().apply { addPut(aClassObject, aTableMapperConfig) addPut(bClassObject, bTableMapperConfig) } // 执行事务 mapper.transactionWrite(transactionWriteRequest)
你可以在实体类的@DynamoDBTable注解中填写任意占位符值,运行时会被传入的配置表名覆盖,不会触发编译错误,示例:
@DynamoDBTable(tableName = "placeholder-Table1") class AClass { // 类属性定义 }
方案2:统一配置动态表名解析器
如果所有表的命名规则统一(均为$stage-基础表名),可以通过自定义TableNameResolver实现全局统一处理,无需为每个类单独构造配置:
// 自定义表名解析器 val dynamicTableNameResolver = object : DynamoDBMapperConfig.TableNameResolver { override fun getTableName(clazz: Class<*>, config: DynamoDBMapperConfig): String { val tableAnnotation = clazz.getAnnotation(DynamoDBTable::class.java) val baseTableName = tableAnnotation.tableName val stage = System.getenv("STAGE") ?: "local" return "${stage}-${baseTableName}" } } // 构造全局mapper配置 val globalDynamicConfig = DynamoDBMapperConfig.Builder() .withTableNameResolver(dynamicTableNameResolver) .build() // 事务写入,和固定表名的写法完全一致 val transactionWriteRequest = TransactionWriteRequest().apply { addPut(aClassObject) addPut(bClassObject) } mapper.transactionWrite(transactionWriteRequest, globalDynamicConfig)
该方案下实体类的@DynamoDBTable注解直接填写基础表名即可:
@DynamoDBTable(tableName = "Table1") class AClass { // 类属性定义 }
内容的提问来源于stack exchange,提问作者Kancha
相关产品推荐
相关产品推荐

