首页 > 解决方案 > 如何在非接口非抽象类中使用 JDBI @Transaction 注解?

问题描述

所以我来自 Spring Boot 背景,我对 Spring@Transactional注解如何与 Hibernate 无缝协作印象深刻。我现在正在开发一个 Dropwizard 应用程序,该应用程序正在使用Jdbi3. 而且我发现了一个类似的注释,它的工作方式与某些先决条件@Transaction完全相同。Spring

春天

所以根据 Spring Guidelines,RepositoryController是分别与数据库和 HTTP 请求通信的两个接口,ServiceLayer 是所有业务逻辑所在的地方。总是有这样一种情况,服务中的单个方法使用多个存储库执行 CRUD 操作。因此,让服务方法使用 注释非常有意义@Transational

Jdbi 与 Dropwizard

如果我错了,请纠正我。在这里JdbiRepository成为DaoController成为ResourceService留下Service。也许不同的人使用不同的层架构,但让我们假设这是我的问题所在的情况。

问题陈述

我希望在 Jdbi 中实现与 Spring 中相同的事务处理,因为它对我来说更有意义,而无需添加任何额外的层。这是我将抛出一些代码,我希望实现的目标:

Dao1.kt

 interface Dao1{
    @SqlUpdate("INSERT INTO table1...")
    fun insert() : Int
 }

Dao2.kt

 interface Dao2{
    @SqlUpdate("INSERT INTO table2...")
    fun insert() : Int
 }

Service.kt

class Service{
  @Transaction
  fun save() {
    Dao1 =Dao1() //What should be expected way to instantiate
    Dao2 =Dao2() //What should be expected way to instantiate
    dao1.insert()
    dao2.insert()
  }
}

需要注意的几点

谢谢

标签: javaspring-bootdropwizardjdbijdbi3

解决方案


您可以使用 Jdbi@Transaction来装饰 bizlogic 类中的方法。它将在事务中运行底层数据库查询。

假设Repository可以由多个Dao's& 假设这样的控制流组成,这是构建 bizlogic(业务逻辑类)和存储库的一种方法。

Resource -> BizLogic -> Repository -> Dao 

例如(Kotlin + Dropwizard + Jdbi):

Resource

    @GET
    @Path("{Id}")
    @Produces(MediaType.APPLICATION_JSON)
    fun getAccount(
            @PathParam("Id") Id: String,
            @Suspended asyncResponse: AsyncResponse
    ) = asyncResponse.with {
        accountManager.getAccount(Id)
    }

方法在BizLogic

    @Transaction
    suspend fun getAccount(Id: String): List<Account> = 
       accountRepository.getAccountsById(Id) ?: emptyList()

方法在Repository

    suspend fun getAccountsById(Id: String): List<Account>? = withContext(Dispatchers.IO){
        accountDao.lookupById(Id)
    }

Dao

        @SqlQuery("select user_id, name, email from users where user_id = :id")
        fun lookupById(@Bind("id") Id: String): List<Account>?

Ps:您将需要使用guice或处理与 jdbi 实例的存储库/dao 绑定spring-di


推荐阅读