我有不同的方法,它们从数据库中查询不同的数据,但每种方法的主要结构都是相同的。为了减少代码,我想缩小它,但我不知道如何。我已经尝试过接口但是返回语句不能从内部类调用。 (它应该是类型安全的!)
结构:
public <special type> getXYdata(some parameters) {
try (Connection connection = mDataSource.getConnection();
Statement statement = connection.createStatement();
ResultSet results = statement.executeQuery(... special query ...)
) {
// Handle ResultsSet and return object of a special type.
} catch (SQLTimeoutException e) {
throw new ContentManagerException("Query took to long or connection timed out", e);
} catch (SQLException e) {
throw new ContentManagerException("Query or parsing its results failed", e);
}
}
点子:
private interface QHandler<T> {
String getQuery();
T handleResultSet(ResultSet set) throws SQLException;
}
然后:
private void executeQuery(QHandler handler) throws ContentManagerException {
try (Connection connection = mDataSource.getConnection();
Statement statement = connection.createStatement();
ResultSet results = statement.executeQuery(handler.getQuery())
) {
handler.handleResultSet(results);
} catch (SQLTimeoutException e) {
throw new ContentManagerException("Query took to long or connection timed out", e);
} catch (SQLException e) {
throw new ContentManagerException("Query or parsing its results failed", e);
}
}
但是如果我在我的一个数据方法中调用这个私有方法,我就无法从handleResultSet()
方法返回一个对象,因为return语句会影响这个接口方法。是否有一个选项,告诉execiteQuery()
方法处理程序有哪种返回类型?
注意:它必须是类型安全的,如果可能的话不能进行投射!
答案 0 :(得分:2)
您的方法不应使用原始QHandler类型,并且应该是通用的:
private <T> T executeQuery(QHandler<T> handler) throws ContentManagerException {
try (Connection connection = mDataSource.getConnection();
Statement statement = connection.createStatement();
ResultSet results = statement.executeQuery(handler.getQuery())
) {
return handler.handleResultSet(results);
} catch (SQLTimeoutException e) {
throw new ContentManagerException("Query took to long or connection timed out", e);
} catch (SQLException e) {
throw new ContentManagerException("Query or parsing its results failed", e);
}
}
请注意,您正在尝试重新发明Spring的JdbcTemplate。您可以考虑使用它而不是重新发明它。
答案 1 :(得分:0)
也许您对替代解决方案持开放态度。如果你使用的是Java 8,你可以这样做:
Interface MyHandler {
<T> T handle(Connection c);
}
class MyHelperClass {
public <T> T withConnection(MyHandler handler) {
try {
Connection connection = mDataSource.getConnection();
return handler.handle(connection);
} catch (...) {
...
} finally {
...
}
}
}
用法:
Result r = myHelperObject.withConnection(con -> {
ResultSet results = connection.createStatement().executeQuery(query)
return new Result(..)
});
这样您就可以使用lambda表达式,因此您不需要为处理程序接口实现各种新类。