java访问oracle存储过程

存储过程语法见:存储过程语法

在开始做之前,试过用spring管理实现StoredProcedure的类,结果spring初始化必须要有sql,而且在构造函数里面declareParameter,一旦容器管理bean,再想declareParameter,就会报错查询已经编译,不能再declareParameter,所以这里直接用new创建。

建表语句:

create table TESTTABLE
(
  id  VARCHAR2(12),
  name VARCHAR2(32)
);
insert into TESTTABLE (ID, NAME)
values ('1', 'zhangsan');
insert into TESTTABLE (ID, NAME)
values ('2', 'lisi');
insert into TESTTABLE (ID, NAME)
values ('3', 'wangwu');
insert into TESTTABLE (ID, NAME)
values ('4', 'xiaoliu');
insert into TESTTABLE (ID, NAME)
values ('5', 'laowu');


访问代码中主要为以下几个方法,在方法上的注释为oracle proc的代码

toExecute1 StoredProcedure访问一个简单的proc;
toExecute2 同toExecute1,只不过proc稍微复杂一丢丢
toExecute3 StoredProcedure访问一个带游标的proc,返回一个list
testJdbcAccessProc 通过基本的jdbc访问oracle带游标的存储过程。
testJdbcTemplateAccessProc 用spring的JdbcTemplate 访问oracle带游标的存储过程。






package com.ilovestudy.forum.core.system;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.sql.DataSource;

import oracle.jdbc.OracleTypes;

import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.CallableStatementCallback;
import org.springframework.jdbc.core.CallableStatementCreator;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.SqlOutParameter;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.jdbc.object.StoredProcedure;

public class TestStoredProcedure extends StoredProcedure{
	
	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("spring-dao.xml");
    	BasicDataSource datasource = context.getBean(BasicDataSource.class);
    	JdbcTemplate jdbcTemplate = context.getBean(JdbcTemplate.class);
    	TestStoredProcedure test = new TestStoredProcedure(datasource);
    	test.testJdbcTemplateAccessProc(jdbcTemplate);
    	
//    	datasource = test.setDataSourceByFoot();//java中手动配置数据源,同样可用
    	test.toExecute1();
    	test = new TestStoredProcedure(datasource);//每个对象只能编译执行一次,不然再次declare会报错。
    	test.toExecute2();
    	test = new TestStoredProcedure(datasource);
    	test.toExecute3();
    	test = new TestStoredProcedure(datasource);
    	test.testJdbcAccessProc();
	}
	
    public TestStoredProcedure(DataSource dataSource) {
    	super(dataSource,"");//此处暂时设置为空,后面可以再次设置
//    	super();//调用此方法需要设置sql,dataSource/jdbcTemplate
//    	super(jdbcTemplate,procname);//同第一个方法
    }
    
    /**
     * 	测试访问简单的存储过程
	TIPs:
	sql:
		create or replace procedure test_param
			(p_id1 in VARCHAR2 default '0',p_id2 in VARCHAR2,v_name1 out varchar2,v_name2 out varchar2) 
		as
		 -- v_name1 varchar2(2000);--重复定义了
		 -- v_name2 varchar2(2000);--重复定义了
		begin
		  select t.name into v_name1 from TESTTABLE t where t.id = p_id1;
		  select t.name into v_name2 from TESTTABLE t where t.id = p_id2;
		  DBMS_OUTPUT.put_line('name1:' || v_name1||'    name2:'||v_name2);
		end; 
	plsql测试:
		declare v_name1 varchar2(200);
		begin
		test_param('1','3',v_name1,v_name1);
		end;
     */
    
    public Map
   
   
    
     toExecute1() {
    	String sql = "test_param";
    	setSql(sql);
    	/**declare顺序需要和存储过程参数顺序一致,名字无所谓,*/
    	declareParameter(new SqlParameter("p_id3", Types.VARCHAR));//不过输入参数(p_id3)在paramsIn.put时需要对应
    	declareParameter(new SqlParameter("p_id4", Types.VARCHAR));
    	declareParameter(new SqlOutParameter("name1", Types.VARCHAR));//name1作为返回map的键
    	declareParameter(new SqlOutParameter("name2", Types.VARCHAR));
        Map
    
    
     
      paramsIn = new HashMap
     
     
      
      ();
        paramsIn.put("p_id3", 1);
        paramsIn.put("p_id4", 3);
        Map
      
      
       
        rst = super.execute(paramsIn);
        System.out.println("sql:"+sql+"\r\nrst:"+rst);
        return rst ;
    }
    /**
     * 
     * 	稍微复杂点的,不过感觉更多的就是数据库编程了,又没去深入了。
	TIPs:
	sql:
		create or replace procedure test_more
			(p_id1 in VARCHAR2 default '0',p_id2 in number,v_name1 out varchar2,v_name2 out varchar2)
		as
		begin
			
  			select t.name into v_name1 from TESTTABLE t where t.id = p_id1;
  			--在利用select...into...语法时,必须先确保数据库中有该条记录,否则会报出"no data found"异常。
   			--可以在该语法之前,先利用select count(*) from 查看数据库中是否存在该记录,如果存在,再利用select...into...
  			update TESTTABLE set name = 'zhangsan2' where id = 5;
  			select t.name into v_name2 from TESTTABLE t where t.id = p_id2;
  			
    		if (v_name2='wangwu') then
       			select t.name into v_name2 from TESTTABLE t where t.id = p_id2+1;
       			Dbms_output.Put_line('打印信息1:'||v_name2);
    		elsif (v_name2='222') then
       			Dbms_output.Put_line('打印信息2:'||v_name2);
			Else
       			Raise NO_DATA_FOUND;
    		End if;
    		
    		Exception
       			When 
       				others 
    			then
			       v_name2:='3333';
			       Dbms_output.Put_line('打印信息3:'||v_name2);    
			       Rollback;

  			DBMS_OUTPUT.put_line('name1:' || v_name1||'    name2:'||v_name2);
		end;

	plsql测试:
		declare v_name1 varchar2(200);
		begin
		test_more('1','3',v_name1,v_name1);
		end;
     */
    public Map
       
       
         toExecute2() { String sql = "test_more"; setSql(sql); /**declare顺序需要和存储过程参数顺序一致,名字无所谓,*/ declareParameter(new SqlParameter("p_id3", Types.VARCHAR));//不过输入参数(p_id3)在paramsIn.put时需要对应 declareParameter(new SqlParameter("p_id4", Types.VARCHAR)); declareParameter(new SqlOutParameter("name1", Types.VARCHAR));//name1作为返回map的键 declareParameter(new SqlOutParameter("name2", Types.VARCHAR)); Map 
        
          paramsIn = new HashMap 
         
           (); paramsIn.put("p_id3", 1); paramsIn.put("p_id4", 3); Map 
          
            rst = super.execute(paramsIn); System.out.println("sql:"+sql+"\r\nrst:"+rst); return rst ; } /** * 测试获取游标 TIPs 包头和包体需要单独执行 sql: create or replace package MYPKG as type mycursor is ref cursor; procedure test(tid in number,mylist out mycursor); end MYPKG; --分割线-- create or replace package body MYPKG as procedure test(tid in number,mylist out mycursor) as begin open mylist for select * from testtable where id <= tid; end test; end MYPKG; plsql测试: * */ public Map 
           
             toExecute3() { String sql = "MYPKG.test"; setSql(sql); declareParameter(new SqlParameter("id", Types.VARCHAR)); declareParameter(new SqlOutParameter("list", OracleTypes.CURSOR,new RowMapper 
             
             
               >() { @Override public Map 
              
                mapRow(ResultSet rs, int i) throws SQLException { Map 
               
                 map = new HashMap 
                
                  (); map.put("id", rs.getString("ID")); map.put("name", rs.getString("NAME")); return map; } })); Map 
                 
                   paramsIn = new HashMap 
                  
                    (); paramsIn.put("id", 3); Map 
                   
                     rst = super.execute(paramsIn); System.out.println("sql:"+sql+"\r\nrst:"+rst); return rst ; } /** * jdbc 访问存储过程 */ public void testJdbcAccessProc(){ String[] strs = getDBdata(); String driver = strs[0], url = strs[1], acct = strs[2], pwd = strs[3]; try { Class.forName(driver); } catch (ClassNotFoundException e) { e.printStackTrace(); } Connection conn = null; CallableStatement proc = null; ResultSet rs = null; String sql = "{call MYPKG.test(?,?)}"; try { conn = DriverManager.getConnection(url, acct, pwd); proc = conn.prepareCall(sql); proc.setInt(1, 3); proc.registerOutParameter(2, OracleTypes.CURSOR); proc.execute(); rs = (ResultSet) proc.getObject(2);//如果不是游标,则直接就可以获取对应的数据! while(rs.next()){ System.out.println("id:"+rs.getString("id")+"\tname:"+rs.getString("name")); } } catch (SQLException e) { e.printStackTrace(); } finally{ try { if(rs!=null){ rs.close(); } if(proc!=null){ proc.close(); } if(conn!=null){ conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } } /** * jdbcTemplate访问proc * @param jdbcTemplate */ public void testJdbcTemplateAccessProc(JdbcTemplate jdbcTemplate) { List 
                     
                     
                       > resultList = (List 
                       
                       
                         >) jdbcTemplate.execute( new CallableStatementCreator() { @Override public CallableStatement createCallableStatement(Connection con) throws SQLException { String storedProc = "{call MYPKG.test(?,?)}";// 调用的sql CallableStatement cs = con.prepareCall(storedProc); cs.setString(1, "3");// 设置输入参数的值 cs.registerOutParameter(2, OracleTypes.CURSOR);// 注册输出参数的类型 return cs; } },new CallableStatementCallback 
                         
                          
                          
                            >>(){ @Override public List 
                            
                            
                              > doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException { List 
                              
                              
                                > list_rst = new ArrayList 
                                
                                
                                  >(); cs.execute(); ResultSet rs = (ResultSet) cs.getObject(2);// 获取游标一行的值 while (rs.next()) { Map 
                                 
                                   rowMap = new HashMap 
                                  
                                    (); rowMap.put("id", rs.getString("id")); rowMap.put("name", rs.getString("name")); System.out.println(rowMap); list_rst.add(rowMap); } rs.close(); return list_rst; } }); } /**手动设置datasource*/ public BasicDataSource setDataSourceByFoot(){ String[] strs = getDBdata(); String driver = strs[0], url = strs[1], acct = strs[2], pwd = strs[3]; BasicDataSource ds = new BasicDataSource(); ds.setDriverClassName(driver); ds.setUrl(url); ds.setUsername(acct); ds.setPassword(pwd); return ds; } /**获取链接数据库字符串*/ public String[] getDBdata(){ Properties p =new Properties(); try { p.load(new FileReader("xxxx//db.properties")); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } String driver = p.getProperty("oracle.driver"), url = p.getProperty("oracle.url"), acct = p.getProperty("oracle.username"), pwd = p.getProperty("oracle.password"); return new String[]{driver,url,acct,pwd}; } } 
                                   
                                  
                                 
                               
                             
                           
                         
                        
                      
                    
                   
                  
                 
                
               
              
            
           
          
         
       
      
      
     
     
    
    
   
   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值