Java-使用泛型参数调用存储过程

Java-使用泛型参数调用存储过程,java,sql,oracle,generics,Java,Sql,Oracle,Generics,我想调用存储过程(Oracle)。因为我的过程调用是动态的,所以我需要动态地管理过程参数。 问题是我希望避免使用instanceof关键字,因为它不能很好地处理主类型。 有没有更干净的方法来调用这样的过程 public void executeProcedure(StoredProcedure proc) { LinkedList<ProcedureParameter<?>> parameters = proc.getParamet

我想调用存储过程(Oracle)。因为我的过程调用是动态的,所以我需要动态地管理过程参数。 问题是我希望避免使用
instanceof
关键字,因为它不能很好地处理主类型。 有没有更干净的方法来调用这样的过程

    public void executeProcedure(StoredProcedure proc) {        
        LinkedList<ProcedureParameter<?>> parameters = proc.getParameters();

        CallableStatement statement = connection.prepareCall("{ call MY_PACKAGE.MY_PROCEDURE( ?, ?, ? ) }");

        for (int i = 0; i < parameters.size(); i++) {
            Object paramValue = parameters.get(i).getValue();

            // Beginning of smelly code

            if (paramValue instanceof String) {
                statement.setString(i + 1, (String) paramValue);
            }
            else if (paramValue instanceof ...) {
                ...
            }
            else {
                ...
            }

            // End of smelly code
        }

        statement.execute();            
    }
public void executeProcedure(StoredProcedure proc){

LinkedList我认为它可以帮助您在没有instanceof的情况下实现所需的功能:

您可以使用反射,尽管这不是一个好的做法,因为它速度较慢,并且阻止编译器检查方法调用是否正确。您可以将每个类映射到其相应的
CallableStatement
方法。例如,
String
将被映射到“setString”

List,String>methods=newhashmap paramValueClass=paramValue.getClass();
字符串stmtMethod=methods.get(paramValueClass);
if(stmtMethod!=null){
Method=statement.getClass().getMethod(stmtMethod,int.class,paramValueClass);
调用(语句,i+1,paramValue);
}否则{
//错误
}
}

我将实施另一个解决方案,这可能不是最好的解决方案,但在我看来,这并不难闻


由于
StoredProcedure
是一个接口,因此每个存储过程都实现这个接口。因此,每个实现将包含一个返回
call…
语句的方法,因为开发人员知道他实现的过程所需的参数类型。

如果您唯一的问题是原语类型,我建议您只使用它们的对象包装器等价物,让您的生活更轻松you@ControlAltDel我认为问题更多的是,在向语句添加参数时,必须指定类型-ie
Statement.setString、Statement.setInteger
,等等@ControlAltDel这是个好主意,但问题范围更广;我的意思是,可能的参数类型数量相当大,我正在寻找一种可以避免长if-else序列的解决方案。谢谢,但这对我没有帮助,因为我不使用自定义类型,而是使用主类型或“java”类型(如字符串)。好吧,这个解决方案似乎比“if-else”解决方案更重。。。不管怎样,谢谢你:)@douny是的,我同意我刚才的回答是因为我很无聊。:)if/else解决方案也是非常可读的——如果我对代码库不熟悉,我可以很容易地看到正在发生的事情。如果这些都是重构的,并且隐藏在其他类的后面,那么一眼就很难看出发生了什么。你介意在这个答案上再扩展一点吗?我对使用StoredProcedures非常陌生,并试图对这一点了如指掌。经过更多的搜索,我发现了这个实现,它是类似的吗?谢谢
    public class ProcedureParameter<E> {
        private String name;
        private E value;

        public ProcedureParameter(String name) {
            this.name = name;
        }

        public ProcedureParameter(String name, E value) {
            this.name = name;
            this.value = value;
        }

        // Getters and setters
    }
List<ProcedureParameter<?>> parameters = proc.getParameters();
CallableStatement statement = connection.prepareCall("{ call MY_PACKAGE.MY_PROCEDURE( ?, ?, ? ) }");

Map<Class<?>, String> methods = new HashMap<Class<?>, String>();
methods.put(String.class, "setString");
//...

for (int i = 0; i < parameters.size(); i++) {
  Object paramValue = parameters.get(i).getValue();
  Class<?> paramValueClass = paramValue.getClass();
  String stmtMethod = methods.get(paramValueClass);
  if (stmtMethod != null){
    Method method = statement.getClass().getMethod(stmtMethod, int.class, paramValueClass);
    method.invoke(statement, i+1, paramValue);
  } else {
    //error
  }
}