扩展

Kotlin 扩展 提供了使用附加功能扩展现有类的方法。Spring Data Kotlin API 使用这些扩展为现有的 Spring API 添加新的 Kotlin 特定便利功能。

请记住,需要导入 Kotlin 扩展才能使用它们。类似于静态导入,在大多数情况下,IDE 应该会自动建议导入。

例如,Kotlin 具现化类型参数 为 JVM 泛型类型擦除 提供了一种解决方法,Spring Data 提供了一些扩展来利用此功能。这允许更好的 Kotlin API。

要在 Java 中检索 SWCharacter 对象列表,通常会编写以下代码:

Flux<SWCharacter> characters = template.query(SWCharacter.class).inTable("star-wars").all()

使用 Kotlin 和 Spring Data 扩展,您可以改写为:

val characters = template.query<SWCharacter>().inTable("star-wars").all()
// or (both are equivalent)
val characters : Flux<SWCharacter> = template.query().inTable("star-wars").all()

与 Java 一样,Kotlin 中的 characters 是强类型的,但 Kotlin 的巧妙类型推断允许使用更短的语法。

Kotlin 的类型安全查询

Kotlin 通过其语言语法和扩展系统支持领域特定语言的创建。Spring Data MongoDB 附带一个用于 Criteria 的 Kotlin 扩展,它使用Kotlin 属性引用 来构建类型安全的查询。使用此扩展的查询通常具有更好的可读性。Criteria 上的大多数关键字都有一个匹配的 Kotlin 扩展,例如 inValuesregex

考虑以下解释类型安全查询的示例:

import org.springframework.data.mongodb.core.query.*

mongoOperations.find<Book>(
  Query(Book::title isEqualTo "Moby-Dick")               (1)
)

mongoOperations.find<Book>(
  Query(titlePredicate = Book::title exists true)
)

mongoOperations.find<Book>(
  Query(
    Criteria().andOperator(
      Book::price gt 5,
      Book::price lt 10
    ))
)

// Binary operators
mongoOperations.find<BinaryMessage>(
  Query(BinaryMessage::payload bits { allClear(0b101) }) (2)
)

// Nested Properties (i.e. refer to "book.author")
mongoOperations.find<Book>(
  Query(Book::author / Author::name regex "^H")          (3)
)
1 isEqualTo() 是一个中缀扩展函数,接收器类型为 KProperty<T>,返回 Criteria
2 对于按位运算符,请传递一个 lambda 参数,在其中调用 Criteria.BitwiseCriteriaOperators 的方法之一。
3 要构造嵌套属性,请使用 / 字符(重载运算符 div)。

Kotlin 的类型安全更新

类似于Kotlin 的类型安全查询 的语法可用于更新文档:

mongoOperations.updateMulti<Book>(
  Query(Book::title isEqualTo "Moby-Dick"),
  update(Book:title, "The Whale")                        (1)
    .inc(Book::price, 100)                               (2)
    .addToSet(Book::authors, "Herman Melville")          (3)
)
1 update() 是一个工厂函数,接收器类型为 KProperty<T>,返回 Update
2 Update 中的大多数方法都有一个匹配的 Kotlin 扩展。
3 具有 KProperty<T> 的函数也可以用于集合类型。