1

目的は、単純なクライアント側呼び出しフォームを使用して、JDBC クエリから ResultSet を返す便利なメソッドを作成することです。

私はこのようなものを書いています:

public class JdbcQueryManager {
  public static ResultSet executePreparedStatementWithParameters(
      Connection jdbcConnection, String sqlQuery,
      Map.Entry<? extends Class<?>, ?>... sqlQueryParameters)
      throws JdbcQueryFailureException {
    return executePreparedStatementWithParameters(jdbcConnection, sqlQuery,
        Arrays.asList(sqlQueryParameters), ResultSet.TYPE_FORWARD_ONLY,
        ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT);
  }
  private static ResultSet executePreparedStatementWithParameters(
      Connection jdbcConnection, String sqlQuery,
      List<Map.Entry<? extends Class<?>, ?>> sqlQueryParameters,
      int resultSetType, int resultSetConcurrency, int resultSetHoldability)
      throws JdbcQueryFailureException {
    try {
      PreparedStatement preparedStatement =
          jdbcConnection.prepareStatement(sqlQuery, resultSetType,
              resultSetConcurrency, resultSetHoldability);
      for (int i = 0; i < sqlQueryParameters.size(); i++) {
        int sqlQueryParameterIndex = i + 1; // SQL parameters are 1-based
        Entry<? extends Class<?>, ?> sqlQueryParameter =
            sqlQueryParameters.get(i);
        Class<?> sqlQueryParameterClass = sqlQueryParameter.getKey();
        if (sqlQueryParameterClass == Integer.class) {
          int sqlQueryParameterIntegerValue =
              (Integer) sqlQueryParameter.getValue();
          preparedStatement.setInt(sqlQueryParameterIndex,
              sqlQueryParameterIntegerValue);
        } else if (sqlQueryParameterClass == String.class) {
          String sqlQueryParameterStringValue =
              (String) sqlQueryParameter.getValue();
          preparedStatement.setString(sqlQueryParameterIndex,
              sqlQueryParameterStringValue);
          // TODO: accept other types, not just String and Integer
        } else {
          throw new JdbcQueryFailureException(new IllegalArgumentException(
              sqlQueryParameterClass.getName()));
        }
      }
      ResultSet resultSet = preparedStatement.executeQuery();
      return resultSet;
    } catch (SQLException sqlException) {
      throw new JdbcQueryFailureException(sqlException);
    }
  }
}

この便利なクラスを使用して:

public class QueryParameter<T> extends AbstractMap.SimpleEntry<Class<T>, T> {
  @SuppressWarnings("unchecked")
  public QueryParameter(T parameterValue) {
    super((Class<T>) parameterValue.getClass(), parameterValue);
  }
}

次のような JDBC SQL ステートメントを実行できるようにします。

ResultSet resultSet =
    JdbcQueryManager.executePreparedStatementWithParameters(jdbcConnection,
        sqlQuery, new QueryParameter<String>("AnswerRequest"),
        new QueryParameter<Integer>(42));

…どうすれば上手くなるの?

具体的には、私が困惑しているのは、この一見複雑で、おそらく不要な形式の使用にあります。

List<Map.Entry<? extends Class<?>, ?>>
4

1 に答える 1

3

のリストを渡すことに値はありませんMap.Entry<? extends Class<?>, ?>。メソッドに各パラメーターがどのクラスであるかを伝えようとしています。これをしないでください!!!

preparedStatement.setXXX()一般に信じられていることとは反対に、 「基本的な」Java オブジェクト (ラップされたプリミティブとDates)を使用している場合は、さまざまな型付きメソッドを使用する必要はありません。使用するだけpreparedStatement.setObject(index, object)で、jdbc ドライバーが何をすべきかを判断します!

型付きセッターを使用する必要があるのは、オブジェクトが「基本」型ではない場合だけです。これが本当に必要な場合は、instanceof各パラメーターをチェックするために使用するだけで、使用する文字列値を抽出するコードを記述できますがpreparedStatement.setObject(index, object)、その文字列で呼び出すこともできます。


私は自分でこのようなものを書きましたが、単に使用しました:

public static ResultSet executePreparedStatementWithParameters(
    Connection jdbcConnection, String sqlQuery, Object... parameters)

そしてそれはうまく動作します。

于 2012-06-13T14:21:43.417 に答える