我有一个使用JDBC PreparedStatements访问数据库的应用程序。为了保持数据访问的通用性,访问数据库的方法大量使用PreparedStatement setObject方法(see question discussing a similar approach)。一些伪代码说明:
public ResultSet getResultSet(String sql, List<Object> parameters) throws SQLException {
PreparedStatement preparedStatement = db.getConnection().prepareStatement(sql);
for(int i = 0; i < parameters.size(); i++) {
preparedStatement.setObject(i+1, parameters.get(i));
}
return preparedStatement.executeQuery();
}
这减少了代码重复,因为getResultSet(String,List)可用于执行不同的查询。但是,它还存在在运行时抛出SQLExceptions的风险。示例情况:
OraclePreparedStatement的行为可能是合理的;它不知道如何将someCustomObject映射到columnWithVarchar2Type。但是,对于getResultSet(String,List)的调用者来说,这是一个惊喜 - 毕竟,调用者提供了一个包含对象的列表,就像请求一样!
问题是:鉴于PreparedStatement的实现之间的差异,有没有办法将任何编译时安全性引入getResultSet方法的签名,以防止调用者传递将抛出的参数运行时的SQLExceptions?
完整的编译时安全性当然是不可能的,但有没有办法使用,例如泛型,以防止有人传入总是的参数导致SQLException独立于传递的SQL?
编辑:这在理论上甚至是不可能的(没有什么能阻止某人实现PreparedStatement并决定永远不会抛出SQLExceptions或总是从setObject()中抛出SQLExceptions)。但是,了解ORM如何解决这个问题会很高兴。