它有点废话 Api - 最终导致您编写大量样板代码。
我认为最好的方法是包装类并制作它,以便处理连接处理其他东西(因为您可以跟踪在包装调用的过程中所做的事情)。
只要您有一个可以在类中生成委托方法的 IDE,那么包装这样的东西就是一件微不足道的工作。
我没有意识到需要处理所有额外的东西,但只是发现有人在这里这样做,但是我很幸运,因为我们已经包装了基本类以将所有烦人的异常转换为 RuntimeExceptions 并提供一些更高级别的 sql 操作.
我做了一个小课来跟踪不同的东西:
public class CleanupList
{
private final ArrayList<AutoCloseable> _disposables;
public CleanupList()
{
_disposables = new ArrayList<>();
}
public void cleanup()
{
for(AutoCloseable closeable : _disposables){
//it sucks that they put an exception on this interface
//if anyone actually throws an exception in a close method then there's something seriously wrong going on
//they should have copied the c# more closely imo as it has nicer syntax aswell
try
{
closeable.close();
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
_disposables.clear();
}
public <T extends AutoCloseable> T track(T statement)
{
_disposables.add(statement);
return statement;
}
}
然后例如在 Wrapped Connection 中(这是包装数据库连接的东西):
public class WrappedConnection implements AutoCloseable
{
private final CleanupList _cleanupList;
private Connection _connection;
public WrappedConnection(Connection connection)
{
_connection = connection;
_cleanupList = new CleanupList();
}
public void close()
{
try
{
_connection.close();
_cleanupList.cleanup();
}
catch (SQLException e)
{
throw new RuntimeException(e);
}
}
public PreparedStatement prepareStatement(String sql)
{
try
{
return trackForDisposal(_connection.prepareStatement(sql));
}
catch (SQLException e)
{
throw new RuntimeException(e);
}
}
private <T extends AutoCloseable> T trackForDisposal(T statement)
{
return _cleanupList.track(statement);
}
.... lots more methods
}
然后,您还可以将相同的列表传递到 PreparedStatement/Result 集(我在这里没有显示)等的包装版本中,并以类似的方式使用它。
我不知道其他人在使用什么,但在 IDEA 中,您可以为不在 using(或者我应该说 try-with-resources)块中的可自动关闭的东西打开警告:
try(SomethingThatNeedsClosing somethingThatNeedsClosing = new SomethingThatNeedsClosing()){
//do stuff
}
这些 using 块让您尝试最终自动关闭,并且只能与 AutoClosable 接口类型的东西一起使用
我不知道为什么这个警告在 IDEA 中默认没有打开,但是你去。