连接池与缓存
在上一个教程中,我们使用 Exposed 框架为网站添加了持久化。 在本教程中,我们将分别探讨如何使用 HikariCP 和 Ehcache 库来实现数据库连接池和缓存。
添加依赖项
首先,您需要为 HikariCP 和 Ehcache 库添加依赖项。 打开 gradle.properties 文件并指定库版本:
h2_version = 2.3.232
hikaricp_version = 5.1.0然后,打开 build.gradle.kts 并添加以下依赖项:
点击 build.gradle.kts 文件右上角的 Load Gradle Changes 图标来安装新添加的依赖项。
连接池
当 Exposed 在 transaction 调用的作用域内对数据库执行第一次操作时,它会在每个 transaction 调用内部启动一个新的 JDBC 连接。 但建立多个 JDBC 连接是非常消耗资源的: 重用现有连接有助于提高性能。 “连接池”机制解决了这个问题。
在本节中,我们将使用 HikariCP 框架来管理应用程序中的 JDBC 连接池。
将连接设置提取到配置文件中
在上一个教程中,我们在 com/example/dao/DatabaseSingleton.kt 文件中使用了硬编码的 driverClassName 和 jdbcURL 来建立数据库连接:
让我们将数据库连接设置提取到一个自定义配置组中。
打开
src/main/resources/application.conf文件,并在ktor组之外添加storage组,如下所示:kotlin打开
com/example/dao/DatabaseSingleton.kt并更新init函数,以从配置文件加载存储设置:kotlininit函数现在接受ApplicationConfig并使用config.property来加载自定义设置。最后,打开
com/example/Application.kt并将environment.config传递给DatabaseSingleton.init,以便在应用程序启动时加载连接设置:kotlin
启用连接池
要在 Exposed 中启用连接池,您需要向 Database.connect 函数提供 DataSource 作为参数。 HikariCP 提供了实现 DataSource 接口的 HikariDataSource 类。
要创建
HikariDataSource,请打开com/example/dao/DatabaseSingleton.kt并将createHikariDataSource函数添加到DatabaseSingleton对象中:kotlin以下是关于数据源设置的一些说明:
createHikariDataSource函数接收驱动程序类名和数据库 URL 作为参数。maximumPoolSize属性指定了连接池可以达到的最大容量。isAutoCommit和transactionIsolation被设置为与 Exposed 使用的默认设置同步。
要使用
HikariDataSource,请将其传递给Database.connect函数:kotlin您现在可以运行应用程序并确保一切运行如初。
缓存
您可以使用数据库缓存来补充数据库。 缓存是一种能够将常用数据存储在临时内存中的技术, 可以减轻数据库的工作负载并减少读取常用数据的时间。
在本教程中,我们将使用 Ehcache 库在文件中组织缓存。
将缓存文件路径添加到配置中
打开 src/main/resources/application.conf 文件并将 ehcacheFilePath 属性添加到 storage 组:
此属性指定了用于存储缓存数据的文件路径。 稍后我们将使用它来配置处理缓存的 DAOFacade 实现。
实现缓存
要实现缓存,我们需要提供另一个 DAOFacade 实现,该实现从缓存中返回值,并在没有缓存值的情况下将其委托给数据库接口。
在
com.example.dao软件包中创建一个新的DAOFacadeCacheImpl.kt文件,并将以下实现添加到其中:kotlin以下是该代码示例的简要概述:
- 为了初始化和配置缓存,我们定义了一个 Ehcache
CacheManager实例。我们将storagePath作为根目录用于磁盘存储。 - 我们为条目创建了一个缓存,用于按 ID 存储文章:
articlesCache将Int类型的键映射到Article类型的值。 - 然后我们为本地内存和磁盘资源提供大小约束。您可以在 Ehcache 文档中详细了解这些参数。
- 最后,我们通过调用
cacheManager.getCache()并提供指定的名称、键和值类型来获取创建的缓存。
- 为了初始化和配置缓存,我们定义了一个 Ehcache
为了在缓存中使用,
Article类应该是可序列化的并实现java.io.Serializable。 打开com/example/models/Article.kt并如下更新代码:kotlin现在我们准备好实现
DAOFacade的成员了。 回到DAOFacadeCacheImpl.kt,添加以下方法:kotlinallArticles:我们不尝试缓存所有文章;我们将其委托给主数据库。article:当我们获取一篇文章时,我们首先检查它是否存在于缓存中,只有当它不在缓存中时,我们才会将其委托给主DAOFacade,并将该文章添加到缓存中。addNewArticle:当我们添加新文章时,我们将其委托给主DAOFacade,但同时也将该文章添加到缓存中。editArticle:编辑现有文章时,我们同时更新缓存和数据库。deleteArticle:在删除时,我们需要同时从缓存和主数据库中删除该文章。
初始化 DAOFacadeCacheImpl
让我们创建一个 DAOFacadeCacheImpl 实例,并添加一个示例文章,以便在应用程序启动前插入到数据库中:
首先,打开
DAOFacadeImpl.kt文件并删除文件底部的dao变量初始化。然后,打开
com/example/plugins/Routing.kt并在configureRouting块内部初始化dao变量:kotlin大功告成。 您现在可以运行应用程序并确保一切运行如初。
您可以在此处找到包含连接池和缓存的完整示例:tutorial-website-interactive-persistence-advanced。
