问题
我有一种方法可以使用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;
}
我应该如何使用Java 7try-with-resources来改进这段代码?
我已尝试使用下面的代码,但它使用了许多try
,并没有提高的可读性much。我应该用另一种方式使用try-with-resources
吗?
public List<User> getUser(int userId) {
String sql = "SELECT id, name FROM users WHERE id = ?";
List<User> users = new ArrayList<>();
try {
try (Connection con = DriverManager.getConnection(myConnectionURL);
PreparedStatement ps = con.prepareStatement(sql);) {
ps.setInt(1, userId);
try (ResultSet rs = ps.executeQuery();) {
while(rs.next()) {
users.add(new User(rs.getInt("id"), rs.getString("name")));
}
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return users;
}
#1 热门回答(145 赞)
我意识到这很久以前就已经回答了,但是想要建议一种额外的方法来避免嵌套的try-with-resources双块。
public List<User> getUser(int userId) {
try (Connection con = DriverManager.getConnection(myConnectionURL);
PreparedStatement ps = createPreparedStatement(con, userId);
ResultSet rs = ps.executeQuery()) {
// process the resultset here, all resources will be cleaned up
} catch (SQLException e) {
e.printStackTrace();
}
}
private PreparedStatement createPreparedStatement(Connection con, int userId) throws SQLException {
String sql = "SELECT id, username FROM users WHERE id = ?";
PreparedStatement ps = con.prepareStatement(sql);
ps.setInt(1, userId);
return ps;
}
#2 热门回答(59 赞)
在你的示例中不需要外部尝试,因此你至少可以从3下降到2,并且你也不需要在资源列表的末尾关闭;
。使用两个try块的优点是你的所有代码都是预先存在的,因此你不必引用单独的方法:
public List<User> getUser(int userId) {
String sql = "SELECT id, username FROM users WHERE id = ?";
List<User> users = new ArrayList<>();
try (Connection con = DriverManager.getConnection(myConnectionURL);
PreparedStatement ps = con.prepareStatement(sql)) {
ps.setInt(1, userId);
try (ResultSet rs = ps.executeQuery()) {
while(rs.next()) {
users.add(new User(rs.getInt("id"), rs.getString("name")));
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return users;
}
#3 热门回答(2 赞)
以下是使用lambdas和JDK 8 Supplier的简洁方法,以适应外部尝试中的所有内容:
try (Connection con = DriverManager.getConnection(JDBC_URL, prop);
PreparedStatement stmt = ((Supplier<PreparedStatement>)() -> {
try {
PreparedStatement s = con.prepareStatement(
"SELECT userid, name, features FROM users WHERE userid = ?");
s.setInt(1, userid);
return s;
} catch (SQLException e) { throw new RuntimeException(e); }
}).get();
ResultSet resultSet = stmt.executeQuery()) {
}