6
final MyDAO dao = database.onDemand(MyDAO.class);

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

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

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

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

4

1 回答 1

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();
    }
}

这个测试的输出是,

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 每次访问该方法时都会创建新的句柄。

于 2014-12-28T16:33:31.020 回答