簡體   English   中英

如何准備類型的參數:列表 <Entry<? extends Class<?> ,?&gt;&gt;

[英]How to I prepare an argument of type: List<Entry<? extends Class<?>, ?>>

目標是編寫一個方便的方法,該方法使用簡單的客戶端調用表單從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<?>, ?>>

Map.Entry<? extends Class<?>, ?>列表中傳遞沒有任何價值Map.Entry<? extends Class<?>, ?> Map.Entry<? extends Class<?>, ?> - 您試圖告訴您的方法每個參數是什么類。 不要這樣做!

與流行的看法相反,如果您使用的是“基本”java對象(包裝的基元和Dates ),則不需要使用各種類型的preparedStatement.setXXX()方法,只需使用preparedStatement.setObject(index, object)和jdbc驅動程序會弄明白該做什么!

您需要使用類型化setter的唯一時間是您的對象不是 “基本”類型之一。 如果你真的需要這個,那么只需使用instanceof來檢查每個參數,然后你編寫一些代碼來提取一個String值來使用,但是你仍然可以用該String調用preparedStatement.setObject(index, object)


我自己寫過這樣的東西,我只是用過:

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

它工作得很好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM