Java-重复sql任务的设计模式
我有不同的方法,从数据库中查询不同的数据,但每个方法的主要结构都是相同的。为了减少代码,我想缩小它,但我不知道怎么做。我尝试过接口,但无法从内部类调用return语句。(它应该是类型安全的!) 结构:Java-重复sql任务的设计模式,java,mysql,sql,design-patterns,interface,Java,Mysql,Sql,Design Patterns,Interface,我有不同的方法,从数据库中查询不同的数据,但每个方法的主要结构都是相同的。为了减少代码,我想缩小它,但我不知道怎么做。我尝试过接口,但无法从内部类调用return语句。(它应该是类型安全的!) 结构: public <special type> getXYdata(some parameters) { try (Connection connection = mDataSource.getConnection(); Statement sta
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);
}
}
但是,如果我在数据方法中调用这个私有方法,我就不能从handleResultSet()
方法返回对象,因为return语句会影响这个接口方法。是否有选项告诉execiteQuery()
方法处理程序的返回类型
注意:它必须是类型安全的,如果可能的话,不要铸造 您的方法不应使用原始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);
}
}
private T executeQuery(QHandler处理程序)抛出ContentManagerException{
try(Connection-Connection=mDataSource.getConnection();
语句Statement=connection.createStatement();
ResultSet results=语句.executeQuery(handler.getQuery())
) {
返回handler.handleResultSet(结果);
}捕获(SQLTimeoutException e){
抛出新的ContentManagerException(“查询耗时过长或连接超时”,e);
}捕获(SQLE异常){
抛出新的ContentManagerException(“查询或解析其结果失败”,e);
}
}
请注意,您正在尝试重新设计Spring的JdbcTemplate。你可以考虑使用它,而不是重新创建它。 也许你对替代的解决方案是开放的。如果您使用的是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 {
...
}
}
}
通过这种方式,您可以使用lambda表达式,因此不需要为处理程序接口实现各种新类。我现在将对其进行测试。您有
公共T
的参考资料吗?我只知道public T
,我想了解它。:)回答得好!但是使用lambda,我只能有一个方法接口,我需要minSdkVersion 1.7:),但使用lambda压缩代码也是一个好主意。:)
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);
}
}
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(..)
});