gpt4 book ai didi

java - 准备语句 : create method using an ArrayList of parameters

转载 作者:行者123 更新时间:2023-11-30 11:45:53 25 4
gpt4 key购买 nike

我正在尝试修改一些 Java 现有代码(不是我做的),我发现查询没有使用 prepare 语句完成。因为我有很多代码,所以我试图尽可能少地修改它。所以不用像

这样的方法
public void executeInsertStmt(String strQuery, String param1, String param2) {

...
...
PreparedStatement preparedStatement = cnx.prepareStatement(stringRequest);
preparedStatement.setString(1, param1);
preparedStatement.setString(2, param2);
}

我想做类似的事情(我不确定这是最好的解决方案)。

public void executeInsertStmt(String strQuery, ArrayList<ArrayList<Object>> parameters) {

PreparedStatement preparedStatement = cnx.prepareStatement(stringRequest);

int counter=1;
for (final ArrayList<Object> eachParam : parameters) {

switch(DataTypes.valueOf(eachParam.get(0).toString().toUpperCase()))
{
case STRING:
preparedStatement.setString(counter, (String)eachParam.get(1));
break;
case DATE:
preparedStatement.setDate(counter, (Date)eachParam.get(1));
break;
case INT:
preparedStatement.setInt(counter, (Integer)eachParam.get(1));
break;
default:
preparedStatement.setString(counter, (String)eachParam.get(1));
break;
}

counter++;

}
}

然后有这样的东西:

strQuery = "insert into toto values (?,?)";
ArrayList<Object> paramToPass1 = new ArrayList<Object>();

paramToPass1.add("String");
paramToPass1.add("TheValueForTheString");

ArrayList<Object> paramToPass2 = new ArrayList<Object>();

paramToPass2.add("String");
paramToPass2.add("TheValueForTheString2");

ArrayList<ArrayList<Object>> paramToPass = new ArrayList<ArrayList<Object>>();

paramToPass.add(paramToPass1);
paramToPass.add(paramToPass2);


executeInsertStmt(strQuery,paramToPass);

因为我有很多参数不同的查询,所以这种方法对我来说是最好的。我不必为每种类型的查询都做一个方法。

你怎么看。

这有什么问题吗?是最好的方法吗?

谢谢你的想法。

最佳答案

您应该为参数使用对象表示,而不是 ArrayList<Object>尺寸 2。此外,您不需要自己的 DataType枚举,已经有一个java.sql.Types类(class)。最重要的是,有一个 setObject() PreparedStatement 上的方法识别这些类型值,所以你不需要 switch声明或调用特定类型 PreparedStatement.set..()方法。

这是一个具有参数对象表示的解决方案,利用了 java.sql.TypespreparedStatement.setObject()支持这些类型,并使您免受类型常量值的影响。

首先,参数的对象表示:

import java.sql.Types;

public class ParamDescriptor {
// Constructor itself is private, we are encapsulating so that
// you don't need to write java.sql.Types constants yourself
private ParamDescriptor(int dataType, Object value) {
_dataType = dataType;
_value = value;
}

// Factory methods for actual instantiation
public static ParamDescriptor forInt (int paramVal) {
return new ParamDescriptor (Types.INTEGER, paramVal);
}

public static ParamDescriptor forString (String paramVal) {
return new ParamDescriptor (Types.VARCHAR, paramVal);
}

public static ParamDescriptor forDate (Date paramVal) {
return new ParamDescriptor (Types.DATE, paramVal);
}
// Add more here to support more data types . . . .


public int getDataType() {
return _dataType;
}

public Object getValue() {
return _value;
}

private int _dataType;
private Object _value;
}

接下来是新版本的executeInsertStmt() .我们已将它减少到只有几行,而且它永远不需要再次更改,无论将来对参数类型的支持如何:

  public void executeInsertStmt(String strQuery, List<ParamDescriptor> parameters) throws SQLException {    
PreparedStatement preparedStatement = cnx.prepareStatement(strQuery);

int counter = 1;
for (ParamDescriptor paramDescriptor : parameters) {
preparedStatement.setObject(counter,
paramDescriptor.getValue(),
paramDescriptor.getDataType());
counter++;
}
}

最后,调用新的 executeInsertStmt() 的代码:

String strQuery = "insert into toto values (?,?)";

ParamDescriptor paramToPass1 = ParamDescriptor.forString("TheValueForTheString");
ParamDescriptor paramToPass2 = ParamDescriptor.forString("TheValueForTheString2");

List<ParamDescriptor> parameters = new ArrayList<ParamDescriptor>();
parameters.add(paramToPass1);
parameters.add(paramToPass2);

executeInsertStmt(strQuery, parameters);

请注意,如果您打算处理小数,还有另一个版本的 PreparedStatement.setObject()支持指定十进制。您可能需要在 executeInsertStmt() 中添加某种支持.

关于java - 准备语句 : create method using an ArrayList of parameters,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10125270/

25 4 0