可以重用JDBI DAO实例吗?

App*_*rew 6 dao jdbi dropwizard

final MyDAO dao = database.onDemand(MyDAO.class);
Run Code Online (Sandbox Code Playgroud)

可以dao实例被重用?或者我们是否需要为每次使用实例化它?

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

final UserDAO dao = jdbi.onDemand(UserDAO.class);
environment.jersey().register(new UserResource(dao));
Run Code Online (Sandbox Code Playgroud)

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

Man*_*dan 6

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

这个测试的输出是,

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
Run Code Online (Sandbox Code Playgroud)

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