构造函数

Ebean 不需要默认构造函数。我们应该使用构造函数在创建实体 bean 实例时提供必需的/非空属性。

例如,如果 Customer 实体 bean 需要一个 name 属性,我们可以在构造函数中使用它并使用 Kotlin 非空类型。

...
@Entity
class Customer(name : String) : BaseModel() {

  @Length(100)
  var name: String = name  // Kotlin non-nullable type

}

建议在 Kotlin 中使用的构造函数样式类似于上面将构造函数参数分配给属性的样式。原因是对于实体 bean 属性,我们经常有映射注释(@Length 等),并且不将它们作为构造函数的一部分(在其中注释有更多目标 - 方法、字段、参数等)会更轻松/更清晰。

非空类型

Ebean 识别 Kotlin 非空类型,并自动将它们视为 @NotNull。当属性是 Kotlin 非空类型时,我们不需要指定 @NotNull@Column(nullable=false)@ManyToOne(optional=false)

MappedSuperclass

通常情况下,有一个映射超类扩展 io.ebean.Model,并像下面一样具有 @WhenCreated@WhenModified

@MappedSuperclass
abstract class BaseModel : Model() {

  @Id
  var id: Long = 0

  @Version
  var version: Long = 0

  @WhenCreated
  lateinit var whenCreated: Instant

  @WhenModified
  lateinit var whenModified: Instant

}

对 whenCreated 和 whenModified 属性使用 lateinit 并将它们作为空类型是可以的。

对于 @Id 属性(例如上面的 JVM 原始 int 和 long),最好使用非空 Int = 0Long = 0

@OneToMany

对于集合类型 @OneToMany@ManyToMany,最好使用非空可变列表,并使用 mutableListOf() 对它们进行初始化。Ebean 增强将对此进行优化,并且仅在需要时才初始化集合类型(因此最好将其建模为 Kotlin 非空集合类型)。

@Entity
@Table(name = "orders")
class Order(customer: Customer) : BaseModel() {

  ...

  @OneToMany(mappedBy = "order", cascade = [CascadeType.PERSIST])
  var details: MutableList<OrderDetail> = mutableListOf()

}