The English version of quarkus.io is the official project site. Translated sites are community supported on a best-effort basis.

用Panache和Kotlin简化MongoDB

MongoDB是一个众所周知的NoSQL数据库,被广泛使用。MongoDB与Panache在这个熟悉的框架之上提供了一个新的层次。本指南将不深入讨论这两者的具体细节,因为这些内容已经在 MongoDB with Panache指南 中涵盖。在本指南中,我们将介绍在基于Kotlin的Quarkus应用程序中使用MongoDB with Panache所需的Kotlin特定变化。

第一:一个例子

正如我们在MongoDB with Panache指南中所看到的,它允许我们用一些自动提供的功能来扩展我们实体和存储库(也称为DAO)中的功能。在使用Kotlin时,该方法与我们在Java版本中看到的非常相似,只是有一两个微小的变化。为了使你的实体具有Panache功能,你可以这样定义它:

class Person: PanacheMongoEntity {
    lateinit var name: String
    lateinit var birth: LocalDate
    lateinit var status: Status
}

如你所见,我们的实体仍然很简单。然而,与Java版本有一点不同。Kotlin语言并不像Java那样支持静态方法的概念。相反,我们必须使用一个 companion object(同伴对象)

class Person : PanacheMongoEntity() {
    companion object: PanacheMongoCompanion<Person> {  (1)
        fun findByName(name: String) = find("name", name).firstResult()
        fun findAlive() = list("status", Status.Alive)
        fun deleteStefs() = delete("name", "Stef")
    }

    lateinit var name: String  (2)
    lateinit var birth: LocalDate
    lateinit var status: Status
}
1 companion object持有所有与特定实例无关的方法,允许进行一般管理和与特定类型绑定的查询。
2 这里有一些选项,但我们选择了 lateinit 的方法。这允许我们将这些字段声明为非空,因为我们知道它们会被构造函数(未显示)或从数据库加载数据的MongoDB POJO编解码器正确分配。
这些类型与那些教程中提到的Java类型不同。对于Kotlin支持,所有的Panache类型将在 io.quarkus.mongodb.panache.kotlin 包中都可以找到。这个子包允许区分Java和Kotlin变体,并允许在一个项目中明确地使用这两种类型。

在Kotlin版本中,我们只是把大部分的功能 active record pattern 转移到了 companion object 。除了这个细微的变化,我们还可以从 Java 方面轻松映射的方式来处理我们的类型。

使用资源库模式

定义你的实体

当使用存储库模式时,你可以将你的实体定义为普通的POJO。

class Person {
    var id: ObjectId? = null; // used by MongoDB for the _id field
    lateinit var name: String
    lateinit var birth: LocalDate
    lateinit var status: Status
}

定义你的存储库

当使用 Repositories 时,你可以得到与活动记录模式完全相同的方便方法,注入到你的 Repository 中,通过它们实现 PanacheMongoRepository

@ApplicationScoped
class PersonRepository: PanacheMongoRepository<Person> {
     fun findByName(name: String) = find("name", name).firstResult()
     fun findAlive() = list("status", Status.Alive)
     fun deleteStefs() = delete("name", "Stef")
}

所有在 PanacheMongoEntityBase 上定义的操作都可以在你的版本库上使用,所以使用它与使用active record(活动记录)模式完全一样,只是你需要注入它。

@Inject
lateinit var personRepository: PersonRepository

@GET
fun count() = personRepository.count()

最有用的操作

编写存储库后,您可以执行以下最常见的操作:

// creating a person
var person = Person()
person.name = "Stef"
person.birth = LocalDate.of(1910, Month.FEBRUARY, 1)
person.status = Status.Alive

// persist it: if you keep the default ObjectId ID field, it will be populated by the MongoDB driver
personRepository.persist(person)

person.status = Status.Dead;

// Your must call update() in order to send your entity modifications to MongoDB
personRepository.update(person);


// delete it
personRepository.delete(person);

// getting a list of all Person entities
val allPersons = personRepository.listAll()

// finding a specific person by ID
// here we build a new ObjectId, but you can also retrieve it from the existing entity after being persisted
ObjectId personId = new ObjectId(idAsString);
person = personRepository.findById(personId) ?: throw Exception("No person with that ID")

// finding all living persons
val livingPersons = personRepository.list("status", Status.Alive)

// counting all persons
val countAll = personRepository.count()

// counting all living persons
val countAlive = personRepository.count("status", Status.Alive)

// delete all living persons
personRepository.delete("status", Status.Alive)

// delete all persons
personRepository.deleteAll()

// delete by id
val deleted = personRepository.deleteById(personId)

// set the name of all living persons to 'Mortal'
var updated = personRepository.update("name", "Mortal").where("status", Status.Alive)

所有 list 方法都有相对应的 stream 版本。

val persons = personRepository.streamAll();
val namesButEmmanuels = persons
    .map { it.name.toLowerCase() }
    .filter { it != "emmanuel" }

关于更多的例子,请参考 Java版本 以获取完整详细信息。除了一些针对Kotlin的调整以使Kotlin开发者感觉更自然外,两个API都是一样的,工作方式也是一样的。这些调整包括更好地使用nullability和API方法上缺乏 Optional

使用 Panache 设置和配置 MongoDB

要开始使用带有 Kotlin 的 Panache 的 MongoDB,您通常可以按照 Java 教程中列出的步骤进行操作。配置项目的最大变化是要包含的 Quarkus 工件。当然,如果需要,您可以保留 Java 版本,但如果您只需要 Kotlin API,那么请包含以下依赖项:

pom.xml
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-mongodb-panache-kotlin</artifactId>  (1)
</dependency>
1 注意最后添加了 -kotlin 。通常你只需要这个版本,但如果你的项目将同时使用 Java 和 Kotlin 代码,你可以安全地包含这两个工件。
build.gradle
implementation("io.quarkus:quarkus-mongodb-panache-kotlin") (1)
1 注意最后添加了 -kotlin 。通常你只需要这个版本,但如果你的项目将同时使用 Java 和 Kotlin 代码,你可以安全地包含这两个工件。

Related content