Java 多次执行StoredProcess
我有下面的代码,它创建了Java 多次执行StoredProcess,java,spring,oracle,function,Java,Spring,Oracle,Function,我有下面的代码,它创建了StoredProcedure的子类并执行它。我想要实现的是将同一对象与新SQL和新参数一起使用多次。不幸的是,当我设置新SQL并声明新参数时,我得到了一个异常 是否有可能“泛化”类以使用新参数执行多个SQL在我的特定示例中,不止一个问题 代码 package procedures; import org.springframework.jdbc.core.SqlOutParameter; import org.springframework.jdbc.core.Sql
StoredProcedure
的子类并执行它。我想要实现的是将同一对象与新SQL和新参数一起使用多次。不幸的是,当我设置新SQL并声明新参数时,我得到了一个异常
是否有可能“泛化”类以使用新参数执行多个SQL在我的特定示例中,不止一个问题
代码
package procedures;
import org.springframework.jdbc.core.SqlOutParameter;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.object.StoredProcedure;
import javax.sql.DataSource;
import java.sql.Types;
import java.util.HashMap;
import java.util.Map;
public class MyProcedure extends StoredProcedure {
private static String SQL = "hr.get_size";
public MyProcedure(DataSource dataSource) {
super(dataSource, SQL);
declareParameter(new SqlOutParameter("param_out", Types.NUMERIC));
declareParameter(new SqlParameter("param_in", Types.VARCHAR));
setFunction(true);
compile();
}
public Object execute(String tableName) {
Map in = new HashMap();
in.put("param_in", tableName);
Map out = execute(in);
if (!out.isEmpty()) {
return out.get("param_out");
} else {
return null;
}
}
}
引发异常的调用:
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(ApplicationConfig.class);
MyProcedure myProcedure = applicationContext.getBean(MyProcedure.class);
System.out.println(myProcedure.execute("employees"));
myProcedure.setSql("hr.get_all_tables");
myProcedure.declareParameter(new SqlOutParameter("param_out", Types.VARCHAR));
myProcedure.setFunction(true);
myProcedure.compile();
System.out.println(myProcedure.execute());
}
Exception in thread "main" org.springframework.dao.InvalidDataAccessApiUsageException: Cannot add parameters once the query is compiled
at org.springframework.jdbc.object.RdbmsOperation.declareParameter(RdbmsOperation.java:278)
at org.springframework.jdbc.object.StoredProcedure.declareParameter(StoredProcedure.java:99)
at main.Main.main(Main.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
例外情况:
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(ApplicationConfig.class);
MyProcedure myProcedure = applicationContext.getBean(MyProcedure.class);
System.out.println(myProcedure.execute("employees"));
myProcedure.setSql("hr.get_all_tables");
myProcedure.declareParameter(new SqlOutParameter("param_out", Types.VARCHAR));
myProcedure.setFunction(true);
myProcedure.compile();
System.out.println(myProcedure.execute());
}
Exception in thread "main" org.springframework.dao.InvalidDataAccessApiUsageException: Cannot add parameters once the query is compiled
at org.springframework.jdbc.object.RdbmsOperation.declareParameter(RdbmsOperation.java:278)
at org.springframework.jdbc.object.StoredProcedure.declareParameter(StoredProcedure.java:99)
at main.Main.main(Main.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
您的
MyProcedure
类不应扩展StoredProcedure
,而应委托给它
我认为您所做的是滥用类扩展的一个例子。如果您的子类要尊重超类的行为,则只应扩展类或接口(请参阅)。
StoredProcedure
类封装了单个过程,并且是只读的,这为使用它的类提供了一定的保证。您的类可以在后台更改过程和参数,因此这是另一回事
您应该将StoredProcedure
设置为类的私有成员,并委派对它的调用(请参阅)
当您需要访问一个新的存储过程时,只需扔掉旧的StoredProcedure
对象和另一个new
对象。如果需要,您可以创建一个匿名内部类:
StoredProcedure sp = new StoredProcedure(ds, SQL) {
public Object execute(String tableName) {
Map in = new HashMap();
in.put("param_in", tableName);
Map out = execute(in);
if (!out.isEmpty()) {
return out.get("param_out");
} else {
return null;
}
}
};
如果代码中的某些内容需要访问实际的存储过程对象,则可以提供一个getter来公开它
另请参阅本文:
StoredProcess
类是抽象类-我无法创建它的实例。我添加了一个创建匿名类的示例。但最后,您必须为每个过程创建一个新的StoredProcedure
对象。我不会浪费时间试图找到避免这样做的方法。