简体   繁体   English

将大多数属性从一个 class object 复制到另一个 class

[英]Copy most attributes from one class object to another class

Between two separate data classes, Person and PersonRecord , which share the same attribute names, I want an elegant way to copy the values from one class's attributes to the other's.在共享相同属性名称的两个单独的数据类PersonPersonRecord之间,我想要一种优雅的方式将值从一个类的属性复制到另一个类的属性。

I have a data class, say for example Person , that defines the business logic data of a person in the application.我有一个数据 class,例如Person ,它定义了应用程序中人员的业务逻辑数据。

import kotlinx.serialization.Serializable

data class Person(
    val id: String,
    val name: String,
    val age: Int,
    val currentEmployment: Employment,
    val workPermit: WorkPermit
)

@Serializable
data class Employment(
    val employer: String,
    val job: String,
    val yearsWithEmployer: Double
)

@Serializable
data class WorkPermit(
    val nationality: String,
    val visa: String
)

I need to use these with an AWS DynamoDB client, but this question doesn't really concern DynamoDB specifically.我需要将这些与 AWS DynamoDB 客户端一起使用,但这个问题并不特别关注 DynamoDB。 I'll explain my usage below.我将在下面解释我的用法。

For several reasons, I've decided to implement a DAO class that is essentially a copy of the class Person , called PersonRecord except the fields containing complex types, ie, Employment and WorkPermit , are stored as Strings instead.出于多种原因,我决定实现一个 DAO class,它本质上是 class Person的副本,称为PersonRecord ,除了包含复杂类型的字段,即, EmploymentWorkPermit存储为字符串。 Also, all the fields are mutable and nullable.此外,所有字段都是可变且可为空的。 I had to make it this way because it's supposed to be a mapper class for DynamoDB Enhanced Client ( doc ).我必须这样做,因为它应该是 DynamoDB 增强客户端 ( doc ) 的映射器 class 。

Annotating this class as @DynamoDbBean defines how the client writes items into a specified table.将此 class 注释为@DynamoDbBean定义了客户端如何将项目写入指定的表。

package util

import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable
import software.amazon.awssdk.enhanced.dynamodb.Key
import software.amazon.awssdk.enhanced.dynamodb.TableSchema
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSortKey

@DynamoDbBean
internal data class PersonRecord(
    @get: DynamoDbPartitionKey
    @get: DynamoDbSortKey
    var id: String? = null,
    var name: String? = null,
    var age: Int? = null,
    var currentEmployment: String? = null,
    var workPermit: String? = null,
)

class PersonDao(
    ddb: DynamoDbEnhancedClient,
    personTableName: String
) {
    private val personTable: DynamoDbTable<PersonRecord> = ddb.table(
        personTableName,
        TableSchema.fromBean(PersonRecord::class.java)
    )

    private fun toPersonRecord(person: Person): PersonRecord =
        PersonRecord(
            id = person.id,
            name = person.name,
            age = person.age,
            currentEmployment = Json.encodeToString(person.currentEmployment),
            workPermit = Json.encodeToString(person.workPermit)
        )

    private fun toPerson(personRecord: PersonRecord): Person =
        Person(
            id = personRecord.id!!,
            name = personRecord.name!!,
            age = personRecord.age!!,
            currentEmployment = Json.decodeFromString(
                personRecord.currentEmployment!!
            ),
            workPermit = Json.decodeFromString(
                personRecord.workPermit!!
            )
        )

    fun writePerson(person: Person) =
        personTable.putItem(toPersonRecord(person))

    fun readPerson(id: String): Person? {
        val personRecord = personTable.getItem(
            Key.builder()
                .partitionValue(id)
                .build()
        )

        return if (personRecord != null) toPerson(personRecord)
        else null
    }
}

I am using the public functions readPerson and writePerson to read and write the pretty Person class, while these functions internally convert to and fro PersonRecord .我正在使用公共函数readPersonwritePerson来读写漂亮的Person class,而这些函数在内部来回转换PersonRecord

Is there a way to copy between the different classes Person and PersonRecord more elegantly?有没有办法更优雅地在不同类PersonPersonRecord之间进行复制? If, in the future, we change the shape of Person slightly, there's a lot to change in the PersonRecord and PersonDao classes too.如果将来我们稍微改变Person的形状,那么PersonRecordPersonDao类也有很多需要改变的地方。 In particular, I need a way to handle decoding String to Employment and WorkPermit , and vice-versa.特别是,我需要一种将String解码为EmploymentWorkPermit的方法,反之亦然。

In the example above, it'd be trivial to add a field or two, but in my actual application I'm dealing with over a dozen fields, and a bunch of unit tests intricately involved with the fields themselves.在上面的示例中,添加一个或两个字段是微不足道的,但在我的实际应用程序中,我正在处理十几个字段,以及一堆与字段本身错综复杂的单元测试。

Someone suggested to use class reflections, but I don't understand how I'd use it based on what theKotlin docs describe.有人建议使用 class 反射,但根据Kotlin 文档的描述,我不明白如何使用它。

You can try to read Person properties into a map via reflections (there is no other way) and use delegated properties feature to construct PersonRecord from that map.您可以尝试通过反射(没有其他方法)将 Person 属性读入 map 并使用委托属性功能从该 map 构造 PersonRecord。

https://kotlinlang.org/docs/delegated-properties.html#storing-properties-in-a-map https://kotlinlang.org/docs/delegated-properties.html#storing-properties-in-a-map

Here is a sample of reading via reflection https://stackoverflow.com/a/38688203/8642957这是通过反射读取的示例https://stackoverflow.com/a/38688203/8642957

Yes, MapStruct is great and it's available in kotlin via kapt.是的, MapStruct很棒,它可以通过 kapt 在 kotlin 中使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将数据从一个对象从一个类复制到Android中另一个类的另一个项目 - Copy data from one object from one class to another boject in another class in Android 有没有办法将一个对象从一个类复制到另一个完全不同的类中的对象? - Is there a way to copy one object from one class into another object from an entirely different class? 将 java 对象/类从一个类加载器复制到另一个类加载器 - Copy java object/class from one classloader to another classloader 将一类的对象复制到另一类的对象…菜鸟 - Copy Object of one class to object of another class…noob 如何从另一个class深度复制一个object? - How to deep copy an object from another class? Java:将属性从一个对象实例复制到另一个对象实例 - Java: Copy attributes from one object instance to another? 将属性白名单从一个类的实例复制到另一个实例 - Copy whitelist of attributes from class one instance to the other 如何将一个对象字段数据复制到同一类的另一对象? - How it copy one object fields data to another object of the same class? Java-将静态arrayList从一个类复制到另一个类的HashMap - Java - copy static arrayList from one class to a HashMap in another class 将一个 class 中字段的所有值复制到另一个 class - Copy all values from fields in one class to another class
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM