[英]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.