JDBI DAO 实例可以复用吗?

Posted

技术标签:

【中文标题】JDBI DAO 实例可以复用吗?【英文标题】:Can JDBI DAO instance be reused? 【发布时间】:2015-02-24 19:51:50 【问题描述】:
final MyDAO dao = database.onDemand(MyDAO.class);

dao 实例可以重复使用吗?还是我们需要为每次使用实例化它?

从代码看来,它负责维护数据库事务。但是,在 DropWizard 中的示例是:-

final UserDAO dao = jdbi.onDemand(UserDAO.class);
environment.jersey().register(new UserResource(dao));

因此,在同一资源中,这个 dao 实例将在所有路径中重复使用。这意味着当对同一资源(可能在两条路径中)发出两个请求时,它们都将使用相同的 dao 实例。这不会引起问题吗?

【问题讨论】:

【参考方案1】:

onDemand 会根据需要自动获取和释放连接。通常这意味着它将获得一个连接来执行一个语句,然后立即释放它,但是诸如打开事务或基于迭代器的结果等各种事情将导致连接保持打开状态,直到事务完成或迭代结果被完全遍历。所以即使当两个请求访问同一个资源时,它们也会处于不同的句柄中。所以不会造成任何问题。

public abstract class Dao implements GetHandle 

   public void printHandle() 
      System.out.println(getHandle());
   



@Test
public void testHandle() 
    Dao onDemandDao = dbi.onDemand(Dao.class);
    Handle handle = dbi.open();
    Dao handleAttachedDao = handle.attach(Dao.class);
    Dao openDao = dbi.open(Dao.class);
    for(int i=0; i< 5; i++ ) 
        onDemandDao.printHandle();
    
    for(int i=0; i< 5; i++ ) 
        handleAttachedDao.printHandle();
    
    for(int i=0; i< 5; i++ ) 
        openDao.printHandle();
    

这个测试的输出是,

org.skife.jdbi.v2.BasicHandle@35d114f4
org.skife.jdbi.v2.BasicHandle@3684d2c0
org.skife.jdbi.v2.BasicHandle@4be460e5
org.skife.jdbi.v2.BasicHandle@454e9d65
org.skife.jdbi.v2.BasicHandle@7805478c
org.skife.jdbi.v2.BasicHandle@6807989e
org.skife.jdbi.v2.BasicHandle@6807989e
org.skife.jdbi.v2.BasicHandle@6807989e
org.skife.jdbi.v2.BasicHandle@6807989e
org.skife.jdbi.v2.BasicHandle@6807989e
org.skife.jdbi.v2.BasicHandle@c2e33
org.skife.jdbi.v2.BasicHandle@c2e33
org.skife.jdbi.v2.BasicHandle@c2e33
org.skife.jdbi.v2.BasicHandle@c2e33
org.skife.jdbi.v2.BasicHandle@c2e33

可以看到,onDemand Dao每次访问方法时都会创建新的句柄。

【讨论】:

以上是关于JDBI DAO 实例可以复用吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 H2-in-memory 数据库测试 JDBI DAO?

Playframework 1.2.5 和 JDBI

如何使用 JDBI SQL 对象 API 创建一对多关系?

企业开发spring框架业务逻辑复用的两个技巧

Mapper(DAO层)接口如何实例化

《设计模式:可复用面向对象软件的基础》之单例模式