我应该在哪里存储 DBI 连接以及何时关闭它?

Where should I store a DBI connection and when should I close it?

我将其存储在 public 静态字段中

public class DB {

    private static final String url = "jdbc:sqlite:file:target/todo";
    public static final DBI dbi = new DBI(url);


    public static void migrate() {
        Flyway flyway = new Flyway();
        flyway.setDataSource(url, "", "");
        flyway.migrate();
    }
}

永远不要关闭它,有没有更好的选择?

最好的选择是创建一个处理程序class。这个 class "hands" out handles 因为有人需要他们。您最需要担心的是关闭手柄。如果你真的想要一个快速的系统,像 c3p0 这样的东西是很棒的。通常,最好使用 getters/setters 将可变对象设为私有和最终。如果需要,您可以保持 DBI 静态。当你调用 checkout 句柄时,你应该使用 try-with-resources。

public Handle getHandle(){
    dbi.open(dataSource);
}

public void doSomething(){
    try(Handle handle = getHandle()){
        // Do something
    }
    catch(DBIException e){
        // TODO Handle it...
    }
}

我可能会让我的处理程序自动关闭并在关闭时关闭所有剩余的东西(如任何连接池)。顺便说一下,这让您可以在处理程序中提取您的凭据并在那里保证数据安全。

这相当于您如何处理获取应用程序中的任何依赖项。最好的通用模型,恕我直言,将它传递给需要它的事物的构造函数。如果您想在您的数据库访问周围放置某种 DAO 外观,请将 DBI 传递给您的 DAO 的构造函数。如果您使用的是 DI 框架,请将 DBI 实例绑定到该框架,然后 @Inject 它。

对于您关于连接的具体问题,JDBC 连接的 DBI 等效项是句柄。您应该获得一个句柄,使用它,并在完成后立即关闭它。 DBI 实例的典型用途是给它一个管理实际数据库连接的数据源,通过在完成后立即释放句柄,可以更好地利用连接池。

在大多数情况下,如果要关闭数据源,您只会关闭 DBI 实例,这就是关闭 DBI 实例所做的全部工作。 98% 的时间,在 java-for-server 世界中,关闭数据源没有意义,因此担心关闭 DBI(与 Handle 相比)不是什么大问题。

使用JDBI时,请记住:

DBI -> Datasource
Handle -> Connection
Query/SQLStatement -> Statement

This doc详细说明了这些。