spring storedProcedure 使用

来源:互联网 发布:java编译器eclipse 编辑:程序博客网 时间:2024/04/29 17:34

http://blog.csdn.net/xiao_jun_0820/article/details/7268219

 

StoredProcedure是一个抽象类,必须写一个子类来继承它,这个类是用来简化JDBCTemplate执行存储过程操作的。

首先我们写一个实现类:

[java] view plaincopyprint?
  1. package com.huaye.framework.dao;  
  2.   
  3. import java.sql.Types;  
  4. import java.util.HashMap;  
  5. import java.util.Map;  
  6.   
  7. import org.springframework.jdbc.core.RowMapper;  
  8. import org.springframework.jdbc.core.SqlOutParameter;  
  9. import org.springframework.jdbc.core.SqlParameter;  
  10. import org.springframework.jdbc.core.SqlReturnResultSet;  
  11. import org.springframework.jdbc.object.StoredProcedure;  
  12.   
  13. /** 
  14.  * Name:StoredProcedureTemplate User: HP Date: 2007-7-21 Time: 7:40:01 
  15.  * Description: 
  16.  */  
  17. public class StoredProcedureTemplate extends StoredProcedure {  
  18.   
  19.     private HashMap<String, Object> map = new HashMap<String, Object>();  
  20.   
  21.     public StoredProcedureTemplate() {  
  22.         super();  
  23.   
  24.     }  
  25.   
  26.       
  27.     public HashMap getMap()  
  28.     {  
  29.         return this.map;  
  30.     }  
  31.       
  32.     public void setValue(String key, Object obj) {  
  33.         map.put(key, obj);  
  34.     }  
  35.   
  36.     public Map execute() {  
  37.         if (this.getSql() == null || this.getSql().equals(""))  
  38.             return null;  
  39.         this.compile();  
  40.         return execute(map);  
  41.     }  
  42.   
  43.     public void setVarcharParam(String param) {  
  44.         this.declareParameter(new SqlParameter(param, Types.VARCHAR));  
  45.     }  
  46.   
  47.     public void setDoubleParam(String param) {  
  48.         this.declareParameter(new SqlParameter(param, Types.DOUBLE));  
  49.     }  
  50.   
  51.     public void setIntegerParam(String param) {  
  52.         this.declareParameter(new SqlParameter(param, Types.INTEGER));  
  53.     }  
  54.   
  55.     public void setVarcharOutParam(String param) {  
  56.         this.declareParameter(new SqlOutParameter(param, Types.VARCHAR));  
  57.     }  
  58.   
  59.     public void setDoubleOutParam(String param) {  
  60.         this.declareParameter(new SqlOutParameter(param, Types.DOUBLE));  
  61.     }  
  62.   
  63.     public void setIntegerOutParam(String param) {  
  64.         this.declareParameter(new SqlOutParameter(param, Types.INTEGER));  
  65.     }  
  66.   
  67.   
  68.     public void setInParam(String param,int valueType)  
  69.     {  
  70.         this.declareParameter(new SqlParameter(param, valueType));  
  71.           
  72.     }  
  73.       
  74.     public void setOutParam(String param,int valueType)  
  75.     {  
  76.         this.declareParameter(new SqlOutParameter(param, valueType));  
  77.           
  78.     }  
  79.       
  80.     public void setReturnParam(String param, RowMapper rowMapper) {  
  81.         this.declareParameter(new SqlReturnResultSet(param,rowMapper));  
  82.     }  
  83.   
  84. }  


写一个测试:

[java] view plaincopyprint?
  1. public void test2() {  
  2.         ApplicationContext context = new ClassPathXmlApplicationContext(  
  3.                 "classpath:spring/applicationContext-base.xml");  
  4.         JdbcTemplate jdbc = (JdbcTemplate) context.getBean("jdbcTemplate");  
  5.   
  6.         StoredProcedureTemplate template = new StoredProcedureTemplate();  
  7.           
  8.         template.setJdbcTemplate(jdbc);  
  9.         template.setSql("testproc");  
  10.         //注意有返回结果集的时候,第一个参数必须设置为返回结果集参数,不然会报错。  
  11.         template.setReturnParam("rows"new FirstReportRowMapper());  
  12.           
  13.         template.setIntegerParam("@parama");  
  14.           
  15.         template.setValue("@parama"9);  
  16.           
  17.         Map map = template.execute();  
  18.         Object o = map.get("rows");  
  19.         List<FirstReportVO> list = (List<FirstReportVO>)o;  
  20.         for (FirstReportVO vo : list) {  
  21.             System.out.println(vo.getSortID()+","+vo.getSortName());  
  22.         }  
  23.     }  


唯一要注意的地方就是测试里备注的地方,我测试了好久才发现,郁闷的一塌糊涂,老是莫名其妙的错,原来将参数互换一下位置就OK了,比如你把

template.setIntegerParam("@parama");写在前面然后再写template.setReturnParam("rows", new FirstReportRowMapper());的话,就会报空指针错误。

这个“rows”可以随便取名字,不过下面map.get("rows")要和你取的名字一致,因为StoredProcedureTemplate会将结果集以这个名字保存在map中返回。

还有要注意的就是设置sqlparamter的顺序要和存储过程中参数的顺序要一致,不然也会报错.

=======

http://www.w3china.org/blog/more.asp?name=hongrui&id=5156

[java语言]spring对oracle的clob和StoredProcedure 的处理
原创空间

邢红瑞 发表于 2005-4-21 9:16:20

使用spring后发现和oracle的驱动有了不解之缘,最初是spring的jdbc存取oracle的clob字段,出现

org.springframework.transaction.TransactionSystemException: Could not roll back JDBC transaction; nested exception is java.sql.SQLException: Io 异常: Software caused connection abort: socket write error

问了Juergen Hoeller几次,也没有知道原因所在。只有加入了hibernate解决此问题,hibernate如何解决oracle的clob字段,看我以前的帖子(http://blogger.org.cn/blog/more.asp?name=hongrui&id=1171)。

后来看到agilejava也遇到这类问题,原来是ojdbc14.jar驱动的问题,改为9.2.0.5.0,一切OK了。相关blog(http://agilejava.blogbus.com/logs/2005/02/1031034.html)

因为现在大量用到存储过程,打算使用spring的StoredProcedure 进行操作,发现运行到SQLErrorCodes loaded: [DB2, HSQL, MS-SQL, MySQL, Oracle, Informix, PostgreSQL, Sybase] 就停了,没有办法,问了Thomas Risberg,他说程序没有错误,我当时就晕了,后来听说虎子做过类似的工作,代码给虎子看,也说没错,而且在它那里运行正常,我生气了。听从他的建议,加入spring源码调试,也不知道问题所在。认为是数据库的问题,换了台数据库还是不行。最后把防火墙撤掉,让虎子直接访问数据库,他那里一切正常。问题明朗了,数据库一样的,代码一样的,唯一不同的是jdk和oracle驱动,他的jdk1.425,我得1.421,差别不大,那就是驱动的问题,我换了以前用的ojdbc14.jar,现在用的版本10.1.0.2.0,换到9.0.2.0.0,一切OK,此时,我已经出离愤怒了,建议oracle驱动最好是自己命名,把文件名加上版本信息,要不会死人的。

下面是我作测试的PLSQL代码

CREATE OR REPLACE package chapter_13 as
 TYPE rs IS REF CURSOR ;
procedure founder(oFields out rs);

end;
/CREATE OR REPLACE package body chapter_13 as

PROCEDURE founder(oFields out rs) IS
BEGIN
  open oFields for
   select * from dept;
END founder;
end;
java代码

package springtest;

import java.sql.*;
import java.util.*;

import javax.sql.*;
import oracle.jdbc.driver.OracleTypes;
import org.springframework.jdbc.core.*;
import org.springframework.jdbc.datasource.*;
import org.springframework.jdbc.object.*;

public class TestDao {
    public static void main(String[] args) throws Exception {
        new TestDao().execute();
    }

    public void execute() throws Exception {
        DataSource ds = new DriverManagerDataSource(
                "oracle.jdbc.driver.OracleDriver",
                "jdbc:oracle:thin:@localhost:1521:mydb",
                "scott", "tiger");

        DemoStoredProcedure proc = new DemoStoredProcedure(ds);
        Map params = new HashMap();

        proc.execute(params);

    }

    private class DemoStoredProcedure extends StoredProcedure {
        public static final String SQL = "chapter_13.founder";


        public DemoStoredProcedure(DataSource ds) {
            setDataSource(ds);
            setSql(SQL);
            setFunction(false);

            declareParameter(
                    new SqlOutParameter(
                            "obrief", OracleTypes.CURSOR, new RowMapper() {
                public Object mapRow(ResultSet rs, int rowNum) throws
                        SQLException {
                    System.out.println(rs.getString(1));

                    return rs.getString(1);
                }
            }
            ));

            compile();
        }
    }


}