我有太多方法可以重复执行类似
的操作Statement stmt = null;
ResultSet rstmt = null;
try {
stmt = conn.createStatement();
rstmt = stmt.executeQuery(...);
while (rstmt.next()) {
//handle rows
}
} catch (SQLException e) {
//handle errors
} finally {
try {rstmt.close();} catch (SQLException ex) {}
try {stmt.close();} catch (SQLException ex) {}
}
语句和结果集的这种设置/拆卸/清理是重复的,并隐藏了有趣的代码片段。
是否有任何模式或习惯用于处理此问题(不引入任何外部框架)?
答案 0 :(得分:10)
在Spring Framework中查看SimpleJDBCTemplate。这完全符合你的要求。
如果您不想引入外部框架,那么只需使用它来实现您自己的灵感。
答案 1 :(得分:4)
你想要执行周围的习语。
您可能想问'What is the "Execute Around" idiom?'。
(如果你喜欢ASCII图:my weblog on 'Factoring out exception handling')
答案 2 :(得分:4)
您可以创建一个接收SQL查询的方法和一个处理ResultSet
的对象。例如:
private void executeSql(String sql, ResultSetHandler handler) {
Statement stmt = null;
ResultSet rstmt = null;
try {
stmt = conn.createStatement();
rstmt = stmt.executeQuery(sql);
while (rstmt.next()) {
handler.handle(rstmt);
}
}
catch (SQLException e) {
//handle errors
}
finally {
try {rstmt.close();} catch (SQLException ex) {}
try {stmt.close();} catch (SQLException ex) {}
}
}
ResultSetHandler
是一个界面:
public interface ResultSetHandler {
void handle(ResultSet rs) throws SQLException;
}
你可以创建一个实现该接口的匿名类的对象,所以它不会太杂乱。
答案 3 :(得分:1)
您应该重新考虑使用iBatis和Hibernate等Java持久性管理器。这些可以自动化很多样板。我一直在使用iBatis,其中SQL语句都整齐地打包并以XML文件命名,代码量必须是原始JDBC方法的25%左右。您可以逐步重构系统以使用iBatis。
答案 4 :(得分:0)
虽然它没有消除设置和拆卸逻辑,但我更喜欢这种风格使JDBC交互更加愉快:
Statement statement = connection.createStatement();
try {
ResultSet results = statement.executeQuery(...);
try {
while (results.next()) {
//handle rows
}
} finally {
results.close();
}
} finally {
statement.close();
}
通过嵌套try
块,您可以自动确保results
和statement
同时调用close()
方法,而无需诉诸try
/ { {1}}块中的{1}}语句。同样,通过在获取对象后立即启动catch
块,您无需担心检查finally
值(当然,除非try
或{{1} })return null
- 在这种情况下,你有更大的问题。)