简体   繁体   English

Java-> Kotlin。 数据类转换模式

[英]Java -> Kotlin. Data classes conversion pattern

I am writing a Spring Boot application with maven. 我正在用Maven编写Spring Boot应用程序。 But recently I upgraded JDK to 10, and Lombok stable stopped working with it. 但是最近我将JDK升级到了10,而Lombok stable停止使用它。 I decided that it will be a great excuse to start using Kotlin. 我决定开始使用Kotlin将是一个很好的借口。 But I am not happy with the look of data classes of Kotlin with spring boot application. 但是我对使用Spring Boot应用程序的Kotlin数据类的外观不满意。

example Java: 示例Java:

@Data
@Entity
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(exclude = {"creator", "content"})
public class Document {

    @Id
    @GeneratedValue(generator = "uuid2")
    @GenericGenerator(name = "uuid2", strategy = "uuid2")
    private String id ;

    @Size(min = 4, max = 100)
    private String name;

    @ManyToOne
    @Column(updatable = false)
    private User creator;

    @OneToOne(cascade = CascadeType.ALL)
    private Content content;

    @ManyToOne
    private Project project;

    @NotNull
    @Column(updatable = false)
    @JsonFormat(pattern = "yyyy/MM/dd hh:mm:ss")
    private LocalDateTime creationDate;

    @NotNull
    @LastModifiedDate
    @JsonFormat(pattern = "yyyy/MM/dd hh:mm:ss")
    private LocalDateTime lastModified;

    @ManyToOne
    @LastModifiedBy
    private User modificator;
}

example Kotlin: 例如Kotlin:

@Entity
data class Document(@Id
                @GeneratedValue(generator = "uuid2")
                @GenericGenerator(name = "uuid2", strategy = "uuid2")
                val id: String,
                @Size(min = 4, max = 100)
                val name: String,
                @ManyToOne
                @JoinColumn(updatable = false)
                private val creator: User,
                @OneToOne(cascade = arrayOf(CascadeType.ALL))
                private val content: Content,
                @ManyToOne
                @JoinColumn(updatable = false)
                val project: Project,
                @NotNull
                @Column(updatable = false)
                @JsonFormat(pattern = "yyyy/MM/dd hh:mm:ss")
                val creationDate: LocalDateTime,
                @NotNull
                @LastModifiedDate
                @JsonFormat(pattern = "yyyy/MM/dd hh:mm:ss")
                private val lastModified: LocalDateTime,
                @ManyToOne
                @LastModifiedBy
                private val modificator: User
)

which makes my code really unreadable. 这使得我的代码真的不可读。 Do you have any template how spring boot data classes should be written? 您是否有模板应如何编写Spring Boot数据类? Or how to convert existing Java classes to Kotlin using all of Kotlin benefits? 还是如何利用Kotlin的所有优点将现有的Java类转换为Kotlin?

I am using IntelliJ Idea Community edition 2018.1. 我正在使用IntelliJ Idea社区版本2018.1。 Or maybe you have a better idea to persist Lombock like model classes? 或者,也许您有一个更好的主意来像模型类一样保留Lombock?

Kotlin data classes allow for a level of concision and efficiency that you can't get with POJOs. Kotlin数据类提供了POJO无法达到的简洁性和效率。 I use this pattern that you're looking for extensively in my projects at work. 我使用这种模式,您正在我的项目中广泛寻找该模式。

And, yes, they look similar to that. 而且,是的,它们看起来与此相似。 However, there are some inefficiencies in your code that can be easily bypassed. 但是,您的代码中有一些效率低下的问题可以轻松绕开。 For example, there isn't any point in nullability annotations when the language has it built-in. 例如,当内置语言时,可空性注释没有任何意义。

Here's one of my project classes, as an example of real-world use: 这是我的一个项目类,以实际使用为例:

@Entity
@Table(name = "Acks")
data class AckEntity(
        @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
        val id: Int = 0,

        @Enumerated(EnumType.STRING)
        val ackType: AckType,

        @OneToOne(cascade = [CascadeType.ALL], fetch = FetchType.EAGER)
        @JoinColumn(name = "alert")
        val alert: AlertEntity,

        @ManyToOne(fetch = FetchType.EAGER)
        @JoinColumn
        val session: SessionEntity? = null,

        @Embedded
        val sale: SaleEntity?,

        val version: Int,
        val timestamp: Date?) : DataEntity

Compared to how these classes used to look in Java, I'd say that this is far-and-away a cleaner approach. 与这些类过去在Java中的外观相比,我想说这是一种更干净的方法。

However, it might just take some time to get used to how Kotlin does things. 但是,可能需要一些时间来习惯Kotlin的操作方式。 Once you learn how to speed-read the language though, I think you'll see your efficiency increase quite a bit. 但是,一旦您学会了如何快速阅读该语言,我认为您会发现效率得到了很大提高。 I know I did. 我知道我做到了

You don't have to convert the Model classes to Kotlin if you don't like the look of it. 如果您不喜欢外观,则不必将Model类转换为Kotlin。 Kotlin can just pick up .java classes. Kotlin可以选择.java类。 Otherwise you can do something like, btw this is just an automatic conversion in intelliJ. 否则,您可以做类似的事情,顺便说一下,这只是intelliJ中的自动转换。

@Data
@Entity
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(exclude = { "creator", "content" })
class Document {

    @Id
    @GeneratedValue(generator = "uuid2")
    @GenericGenerator(name = "uuid2", strategy = "uuid2")
    var id: String? = null
        set(id) {
            field = this.id
        }

    @Size(min = 4, max = 100)
    var name: String? = null
        set(name) {
            field = this.name
        }

    @ManyToOne
    @Column(updatable = false)
    var creator: User? = null
        set(creator) {
            field = this.creator
        }

    @OneToOne(cascade = CascadeType.ALL)
    var content: Content? = null
        set(content) {
            field = this.content
        }

    @ManyToOne
    var project: Project? = null
        set(project) {
            field = this.project
        }

    @NotNull
    @Column(updatable = false)
    @JsonFormat(pattern = "yyyy/MM/dd hh:mm:ss")
    var creationDate: LocalDateTime? = null
        set(creationDate) {
            field = this.creationDate
        }

    @NotNull
    @LastModifiedDate
    @JsonFormat(pattern = "yyyy/MM/dd hh:mm:ss")
    var lastModified: LocalDateTime? = null
        set(lastModified) {
            field = this.lastModified
        }

    @ManyToOne
    @LastModifiedBy
    var modificator: User? = null
        set(modificator) {
            field = this.modificator
        }
}

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM