kotlin - 来自不同类的调用扩展功能
问题描述
我正在尝试创建一个非常简单的事务管理器,如下所示:
object PersistenceManager {
private val dataSource: DataSource by lazy {
val config = ConfigFactory.load()
hikari(config.getConfig("postgres"))
}
private fun hikari(appConfig: Config): DataSource {
// init datasource
}
fun <T> transaction(statement: Connection.() -> T): T {
val connection = dataSource.connection
try {
return connection.statement()
} catch (e: Exception) {
connection.rollback()
throw e
} finally {
connection?.close()
}
}
}
class BrandsDB {
private val query = "select name from brands order by name"
fun Connection.getAll(): List<String> {
val ps = this.prepareStatement(query)
val rs = ps.executeQuery()
return JdbcMapperFactory.newInstance()
.newMapper(String::class.java)!!.stream(rs).toList()
}
}
class BrandsService(private val brandsDB: BrandsDB) {
fun getBrands(): List<String> {
return transaction {
brandsDB.getAll() // I'd like to do something like this but since
// getAll() method belongs to Connecion, I can't
}
}
}
所以这一切背后的想法是,我可以在一个transaction
块中拥有多个查询,如果出现任何问题,我可以回滚(我应该在这些查询中插入或更新)。我还想避免将连接传递给该brandsDB.getAll()
方法,但让它以“隐式”方式获取连接。
我知道我可以将getAll()
方法提取到它自己的文件中或使BrandsDB
类成为对象,但这可以在任何地方以静态方式调用该方法,这是我不喜欢的。我也不想将任何与数据库相关的代码放在 中BrandsService
,只有业务逻辑应该放在那里。
这可能吗?
解决方案
Connection
是 Java 中的接口(不是类!),因此您可以创建自己的接口来扩展它并委托给它。
interface OurConnection : Connection {
fun getAll() : SomeType
}
fun <T> PersistenceManager.extendedTransaction(action: OurConnection.() -> T) : T {
//call the original method
return PersistenceManager.transaction {
object : OurConnection, Connection by this {
override fun getAll() = TODO("implement me")
}.action()
}
}
我使用委托实现,Connection
在我的接口中隐式委托方法。它是Connection by this
线,函数调用this
中的 lambda 接收器对象在哪里。PersistenceManager.transaction
推荐阅读
- python - 如何从 Matplotlib 谱图中删除图例?
- opencv - 最新版本的opencv是否包含dlib
- android - 应用程序启动器图标未显示在 android 电视的主屏幕中
- java - 以角度将字符串转换为字节[]并将其保存为pdf
- ios - 如何解决与 webView 及其子视图的 Gesture 冲突?
- javascript - 检查数组的值是否存在于不同数组的对象中
- c# - “IServiceCollection”不包含“AddAWSService”的定义,并且在 asp.net core 2.2 中没有可访问的扩展方法“AddAWSService”错误?
- google-cloud-platform - gcp - 在数据库插入时触发云功能?
- vue.js - Axios : 添加 validateStatus 钩子以获取 HTTP 304 响应
- django - 在 Django 中将数据添加到创建的 sqlite 数据库