我有一种方法可以使用JDBC从数据库中获取用户:
public List<User> getUser(int userId) {
String sql = "SELECT id, name FROM users WHERE id = ?";
List<User> users = new ArrayList<User>();
try {
Connection con = DriverManager.getConnection(myConnectionURL);
PreparedStatement ps = con.prepareStatement(sql);
ps.setInt(1, userId);
ResultSet rs = ps.executeQuery();
while(rs.next()) {
users.add(new User(rs.getInt("id"), rs.getString("name")));
}
rs.close();
ps.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
return users;
}
Run Code Online (Sandbox Code Playgroud)
我应该如何使用Java 7 try-with-resources来改进此代码?
我已尝试使用下面的代码,但它使用了许多try块,并且不会提高可读性.我应该try-with-resources以其他方式使用吗?
public List<User> getUser(int userId) {
String sql = "SELECT id, name …Run Code Online (Sandbox Code Playgroud) 我在尝试使用资源时遇到问题,我要求确定一下.我是否可以使用它,如果我需要对异常做出反应,我仍然需要catch块中的资源?给出的例子如下:
try (java.sql.Connection con = createConnection())
{
con.setAutoCommit(false);
Statement stm = con.createStatement();
stm.execute(someQuery); // causes SQLException
}
catch(SQLException ex)
{
con.rollback();
// do other stuff
}
Run Code Online (Sandbox Code Playgroud)
我担心在这种情况下,我仍然注定要使用旧的try-catch-finally,即使根据oracle文档 - "在try-with-resources语句中捕获并最终阻塞,任何catch或finally块都在资源之后运行声明已关闭."
对于MySQL连接我有一个连接对象,并使用一个交易机制connection.startTransaction(),connection.commitTransaction(),connection.rollbackTransaction().
对于每一个startTransaction(),必须始终有要么打电话commitTransaction()或到rollbackTransaction().错过这样的电话或同时打电话都会破坏我的交易系统.
所以我用以下方式使用它们:
boolean i_am_in_a_transaction=true;
try {
connection.startTransaction();
...
i_am_in_a_transaction=false;
connection.commitTransaction();
} finally {
if(i_am_in_a_transaction) {
connection.rollbackTransaction();
}
}
Run Code Online (Sandbox Code Playgroud)
这确保了声明的调用顺序,但这是很费力的,因为我必须在我使用事务的地方写这些行.
在C++中,我将使用一个事务对象来检查它的析构函数,如果commit()函数被调用,否则调用rollback():
class Transaction {
public:
Transaction()
:am_in_transaction(false) {
}
~Transaction() {
if(_am_in_transaction) {
rollback();
}
}
void startTransaction() {
_am_in_transaction=true;
...start Transaction...
}
void commit() {
_am_in_transaction=false;
...commit Transaction...
}
void rollback() {
_am_in_transaction=false;
...rollback Transaction...
}
private:
bool _am_in_transaction;
}
Run Code Online (Sandbox Code Playgroud)
这样我就可以在一个地方实现逻辑,并且可以非常简单地使用它:
Transaction my_transaction; …Run Code Online (Sandbox Code Playgroud)