如何在非接口和非抽象类中使用JDBI@Transaction注释



所以我来自Spring Boot背景,Spring@Transactional注释如何与Hibernate无缝配合给我留下了深刻印象。我现在正在开发一个使用Jdbi3的Dropwizard应用程序。我发现了一个类似的@Transaction注释,它的工作方式与Spring完全相同,但有一些先决条件。

弹簧

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

带Dropwizard的Jdbi

所以,如果我错了,请纠正我。这里,在Jdbi中,Repository变成DaoController变成Resource,并且Service保持为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()
}
}

需要注意的几点

  • 我知道onDemand只能在abstract类或接口上使用,因此我无法使用onDemand实例化Service。此外,我无法使我的Service抽象化。

  • 很少有文章建议制作一个抽象的Repository并在那里使用Transaction。但根据我的想法,当我想到存储库时,我发现它和entity/table有一对一的映射。或者可能是相关实体。因此,如果我想在同一个服务方法中更新movieuser表,那么在某些XRepository中,将这两个事务语句放在一个方法下听起来非常荒谬。这是业务逻辑的一部分,应该驻留在Service中。

  • 我想我可以使用jdbi.inTransactionjdbi.useTransaction。但在这种情况下,我必须手动连接每个Dao。有更好的方法吗?

感谢

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

假设CCD_ 35可以由多个CCD_;假设控制流是这样的,下面是如何构建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:您将需要使用guicespring-di处理repository/dao与jdbi实例的绑定

最新更新