JDBC PreparedStatement setObject编译时安全性

时间:2013-09-19 07:32:02

标签: java jdbc

我有一个使用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的风险。示例情况:

  1. 有人调用getResultSet(“SELECT columnWithVarchar2Type FROM someTable WHERE columnWithVarchar2Type =?”,Arrays.asList(someCustomObject));
  2. db.getConnection()。prepareStatement(sql)返回OraclePreparedStatement
  3. preparedStatement.setObject抛出java.sql.SQLException'无效列类型'
  4. OraclePreparedStatement的行为可能是合理的;它不知道如何将someCustomObject映射到columnWithVarchar2Type。但是,对于getResultSet(String,List)的调用者来说,这是一个惊喜 - 毕竟,调用者提供了一个包含对象的列表,就像请求一样!

    问题是:鉴于PreparedStatement的实现之间的差异,有没有办法将任何编译时安全性引入getResultSet方法的签名,以防止调用者传递将抛出的参数运行时的SQLExceptions?

    完整的编译时安全性当然是不可能的,但有没有办法使用,例如泛型,以防止有人传入总是的参数导致SQLException独立于传递的SQL?

    编辑:这在理论上甚至是不可能的(没有什么能阻止某人实现PreparedStatement并决定永远不会抛出SQLExceptions或总是从setObject()中抛出SQLExceptions)。但是,了解ORM如何解决这个问题会很高兴。

0 个答案:

没有答案