Java 如何准备类型为:List<;的参数;进入<;?扩展类<>&燃气轮机&燃气轮机;
目标是编写一个方便的方法,使用简单的客户端调用表单从JDBC查询返回结果集 我写过这样的东西:Java 如何准备类型为:List<;的参数;进入<;?扩展类<>&燃气轮机&燃气轮机;,java,generics,guava,covariance,Java,Generics,Guava,Covariance,目标是编写一个方便的方法,使用简单的客户端调用表单从JDBC查询返回结果集 我写过这样的东西: public class JdbcQueryManager { public static ResultSet executePreparedStatementWithParameters( Connection jdbcConnection, String sqlQuery, Map.Entry<? extends Class<?>, ?>...
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);
}
}
}
ResultSet resultSet =
JdbcQueryManager.executePreparedStatementWithParameters(jdbcConnection,
sqlQuery, new QueryParameter<String>("AnswerRequest"),
new QueryParameter<Integer>(42));
公共类JdbcQueryManager{
公共静态结果集executePreparedStatementWithParameters(
连接jdbcConnection,字符串sqlQuery,
映射条目(sqlQueryParameters)
引发JdbcQueryFailureException{
返回executePreparedStatementWithParameters(jdbcConnection、sqlQuery、,
Arrays.asList(sqlQueryParameters),ResultSet.TYPE\u FORWARD\u,
ResultSet.CONCUR_只读,ResultSet.CLOSE_游标(在提交时);
}
私有静态结果集executePreparedStatementWithParameters(
连接jdbcConnection,字符串sqlQuery,
列表>sqlQueryParameters,
int resultSetType、int resultSetConcurrency、int resultSetHoldability)
引发JdbcQueryFailureException{
试一试{
准备好的报表准备好的报表=
prepareStatement(sqlQuery,resultSetType,
ResultsConcurrency,ResultsTholdability);
对于(int i=0;isqlQueryParameter=
sqlQueryParameters.get(i);
类sqlQueryParameterClass=sqlQueryParameter.getKey();
if(sqlQueryParameterClass==Integer.class){
int sqlQueryParameterIntegerValue=
(整数)sqlQueryParameter.getValue();
preparedStatement.setInt(sqlQueryParameterIndex,
sqlQueryParameterIntegerValue);
}else if(sqlQueryParameterClass==String.class){
字符串sqlQueryParameterStringValue=
(字符串)sqlQueryParameter.getValue();
preparedStatement.setString(sqlQueryParameterIndex,
sqlQueryParameterStringValue);
//TODO:接受其他类型,而不仅仅是字符串和整数
}否则{
抛出新的JdbcQueryFailureException(新的IllegalArgumentException(
sqlQueryParameterClass.getName());
}
}
ResultSet ResultSet=preparedStatement.executeQuery();
返回结果集;
}捕获(SQLException SQLException){
抛出新的JdbcQueryFailureException(sqlException);
}
}
}
使用此便利类:
public class QueryParameter<T> extends AbstractMap.SimpleEntry<Class<T>, T> {
@SuppressWarnings("unchecked")
public QueryParameter(T parameterValue) {
super((Class<T>) parameterValue.getClass(), parameterValue);
}
}
公共类QueryParameter扩展了AbstractMap.SimpleEntry{
@抑制警告(“未选中”)
公共查询参数(T参数值){
super((Class)parameterValue.getClass(),parameterValue);
}
}
要能够执行如下JDBC SQL语句:
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);
}
}
}
ResultSet resultSet =
JdbcQueryManager.executePreparedStatementWithParameters(jdbcConnection,
sqlQuery, new QueryParameter<String>("AnswerRequest"),
new QueryParameter<Integer>(42));
ResultSet ResultSet=
JdbcQueryManager.executePreparedStatementWithParameters(jdbcConnection,
sqlQuery,新的QueryParameter(“AnswerRequest”),
新的QueryParameter(42));
。。。我怎样才能做得更好
具体而言,我的困惑在于使用这种看似复杂但可能不需要的形式:
List<Map.Entry<? extends Class<?>, ?>>
列表>
在传递Map.Entry的列表时没有任何值,>
-您试图告诉您的方法每个参数是什么类不要这样做强>
与流行的观点相反,如果您使用的是“基本”java对象(包装的原语和日期),只需使用preparedStatement.setXXX()
方法,就不需要使用各种类型的preparedStatement.setObject(index,object)
,jdbc驱动程序就会知道该怎么做
如果对象不是“基本”类型之一,则只需使用类型设置器。如果您确实需要,那么只需使用instanceof
检查每个参数,然后您可以编写一些代码来提取要使用的字符串值,但您仍然可以使用该字符串调用preparedStatement.setObject(index,object)
我自己也写过类似的东西,我只是用:
public static ResultSet executePreparedStatementWithParameters(
Connection jdbcConnection, String sqlQuery, Object... parameters)
而且它工作正常。旁注:格式化程序每行至少应接受150个字符。这就是为什么,依我看。为什么。。。什么?:)你的意思是“格式化代码,每行字符数更多”/“更宽”,基本上是吗?我想,你只是在用整个
QueryParameter
的东西使你的生活复杂化。为什么不改用execute(sqlQuery,“AnswerRequest”,42)
之类的东西呢?我曾经写过这样的东西,它可以工作(使用4个不同的DBs)。你的意思是接受一个“Object…varargs”参数,然后使用“for(Object o:varargs)preparedStatement.setObject(o)?我想这是Bohemian推荐的…我查看了一些实现setObject的JDBC驱动程序的源代码(例如,Xerial的Sqlite、PostreSQL的pgjdbc等),它们中的大多数只是在设置类型之前进行一系列实例检查(Timestamp、Double、Integer、Float.java.util.Date等)。您在“不要这样做!”中强调了很多!!!“好像它有一些危害,它只是多余的,因此引入了不必要的潜在错误源,由于重复而违反了DRY。有趣的是,你自己也做了类似的事情,你能分享代码吗?”?