不同类别的来电额外资讯功能

时间:2019-03-29 10:12:39

标签: kotlin kotlin-extension

我正在尝试创建一个非常简单的事务管理器,如下所示:

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中,只有业务逻辑应该放在那里。

这可能吗?

1 个答案:

答案 0 :(得分:1)

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是来自PersistenceManager.transaction函数调用的lambda接收器对象。

相关问题