Java中执行存储过程和函数(web基础学习笔记十四)
一、概述
如果想要执行存储过程,我们应该使用 CallableStatement 接口。
CallableStatement 接口继承自PreparedStatement 接口。所以CallableStatement 接口包含有Statement 接口和PreparedStatement 接口定义的全部方法,但是并不是所有的方法我们都要使用,主要使用的方法有这样几个:
CallableStatement 常用方法:
返回类型 | 方法签名 | 说明 |
boolean | execute() |
执行 SQL 语句,如果第一个结果是 ResultSet 对 |
void |
registerOutParameter(int parameterIndex,int sqlType) |
按顺序位置parameterIndex 将OUT 参数注册为 |
Type |
getType(int parameterIndex) |
根据参数的序号获取指定的 JDBC 参数的值。第一 |
我们可以使用execute()方法来执行存储过程。CallableStatement 为所有的数据库提供了一种统一的标准形式调用存储过程。所以,你将会看到我们使用execute()调用存储过程的语法与在Oracle 中会所有不同。
为了获得存储过程或函数的返回值,我们需要使用 registerOutParameter()方法将返回的参数注册为JDBC 的类型。 registerOutParameter()方法的第一个参数是参数的序号,第一个为1,第二个为2,以此类推。第二个参数需要一个int 值,用来标记JDBC 的类型,我们可以使用java.sql.Types 类中的常量来设置这个参数。比如VARCHAR、DOUBLE 等类型。如果类型不够用,也可以从具体数据库的驱动中寻找合适的类型常量。如果存储过程或函数有返回值,这个方法是必须要调用的,否则无法得到返回值,甚至会发生异常。
CallableStatement 接口中定义了很多get 方法,用于获取存储过程返回的值,根据值的类型不同,你可以使用不同get 方法,比如getInt()、getString()、getDouble()等等。
我们看一下使用CallableStatement 接口执行存储过程和函数的语法格式。
存储过程:{call <procedure-name>[(<arg1>,<arg2>, ...)]}
函数:{?= call <procedure-name>[(<arg1>,<arg2>, ...)]}
如果要调用存储过程,则使用第一种语法,就是开头不带问号的语法,call 后面是过程名,
如果没有参数,可以省略小括号。
如果要调用函数,则使用第二种语法,开头带有一个问号加等号,实际上这个问号就是一个占位符,这个问号总是调用函数的第一个占位符。其它部分与过程的语法相同
二、CallableStatement 执行存储过程
2.1、建立基类
package com.pb.emp.dao;import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException;import com.pb.emp.untily.ConfigManager;public class BaseDao {protected Connection conn;protected PreparedStatement ps;protected ResultSet rs;//建立连接public boolean getConnection(){String driver=ConfigManager.getInstance().getString("jdbc.driver_class");String url=ConfigManager.getInstance().getString("jdbc.connection.url");String username=ConfigManager.getInstance().getString("jdbc.connection.username");String password=ConfigManager.getInstance().getString("jdbc.connection.password");try {Class.forName(driver);conn=DriverManager.getConnection(url,username, password);} catch (ClassNotFoundException e) {// TODO Auto-generated catch block e.printStackTrace();return false;} catch (SQLException e) {// TODO Auto-generated catch block e.printStackTrace();return false;}return true;}//增加,修改,删除public int executeUpdate(String sql, Object[] params){getConnection();int updateRow=0;try {ps=conn.prepareStatement(sql);//填充占位符for(int i=0;i<params.length;i++){ps.setObject(i+1, params[i]);}updateRow = ps.executeUpdate();} catch (SQLException e) {// TODO Auto-generated catch block e.printStackTrace();}return updateRow;}////查询public ResultSet executeSQL(String sql, Object[] params){getConnection();try {ps=conn.prepareStatement(sql);//填充占位符for(int i=0;i<params.length;i++){ps.setObject(i+1, params[i]);}rs = ps.executeQuery();} catch (SQLException e) {// TODO Auto-generated catch block e.printStackTrace();}return rs;}// 关闭资源public boolean closeResource() {if(rs!=null){try {rs.close();} catch (SQLException e) {// TODO Auto-generated catch block e.printStackTrace();return false;}}if(ps!=null){try {ps.close();} catch (SQLException e) {// TODO Auto-generated catch block e.printStackTrace();return false;}}if(conn!=null){try {conn.close();} catch (SQLException e) {// TODO Auto-generated catch block e.printStackTrace();return false;}}return true;} }
2.2、执行不带参但是有返回值的存储过程
新建类来继承上面的类也可以继承,下面建立存储过程
--查询emp表记录数 CREATE OR REPLACE PROCEDURE getEmpCount(v_count OUT NUMBER) AS BEGINSELECT COUNT(*) INTO v_count FROM emp; END;
调用
//执行不带参但是有返回值的存储过程获取emp表总记录数public int getTotalCountProc(){//定义一个变量来接收结果int totalCount=0;//声明CallableStatement对象CallableStatement proc=null;String sql="{call getEmpCount(?)}";try {//建立连接 getConnection();//CallableStatement对象proc=conn.prepareCall(sql);//将数据库对象数据类型注册为java中的类型proc.registerOutParameter(1, Types.INTEGER);//执行 proc.execute();//接收返回值totalCount=proc.getInt(1);} catch (SQLException e) {// TODO Auto-generated catch block e.printStackTrace();}return totalCount;}
2.3、执行带参带返回值的存储过程
--根据部门编号和姓名查询人数 CREATE OR REPLACE PROCEDURE getEmpCount(v_deptno NUMBER, v_ename VARCHAR2,v_count OUT NUMBER) AS BEGIN SELECT COUNT(*) INTO v_count FROM emp WHERE ename LIKE '%'||v_ename||'%' AND deptno=v_deptno; END;
//执行带参带返回值的存储过程public int getTotalCountProc1(int deptno,String ename){//定义一个变量来接收结果int totalCount=0;//声明CallableStatement对象CallableStatement proc=null;String sql="{call getEmpCount(?,?,?)}";//建立连接 getConnection();//CallableStatement对象try {proc=conn.prepareCall(sql);//设置占位符//Object [] params={deptno,ename};//只设置输入参数即可proc.setInt(1, deptno);proc.setString(2, ename);//proc.setInt(3, totalCount);将数据库对象数据类型注册为java中的类型,将输出参数转换proc.registerOutParameter(3, Types.INTEGER);//执行 proc.execute();//获取结果totalCount=proc.getInt(3);} catch (SQLException e) {// TODO Auto-generated catch block e.printStackTrace();}finally{this.closeResource();if(proc!=null){try {proc.close();} catch (SQLException e) {// TODO Auto-generated catch block e.printStackTrace();}}}return totalCount;}
2.3、执行返回值为游标的存储过程
--查询员工所有信息 CREATE OR REPLACE PROCEDURE emp_cur(emp_cur OUT SYS_REFCURSOR) AS BEGINOPEN emp_cur FOR SELECT * FROM emp; END;
//执行返回值为游标的存储过程 游标名emp_curpublic List<Emp> getempProc1(){List<Emp> emplist=new ArrayList<Emp>();String sql="{call emp_cur(?) }";//声明CallableStatement对象CallableStatement proc=null;//建立连接getConnection();try {//执行proc=conn.prepareCall(sql);//注册类型为数据库游标类型proc.registerOutParameter(1, oracle.jdbc.OracleTypes.CURSOR);//接收结果集proc.execute();//获取结果第一个对象rs=(ResultSet) proc.getObject(1);while(rs.next()){int empno=rs.getInt("empno"); String ename=rs.getString("ename"); String job=rs.getString("job"); int mgr=rs.getInt("mgr"); Date hiredate=rs.getDate("hiredate"); double sal=rs.getDouble("sal"); double comm=rs.getDouble("comm"); int deptno=rs.getInt("deptno");//声明Emp对象Emp emp=new Emp();//将得到的值添加到对象中emp.setEmpno(empno);emp.setEname(ename);emp.setJob(job);emp.setMgr(mgr);emp.setHiredate(hiredate);emp.setSal(sal);emp.setComm(comm);emp.setDeptno(deptno);//将对象添加到集合emplist.add(emp);}} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{this.closeResource();if(proc!=null){try {proc.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}return emplist;}
以上看出,需要将输出的参数,和结果注册,输入的参数不要注册,
但输入参数需要设置占位符
三、执行函数
3.1 、函数功能为根据雇员id 返回姓名
CREATE OR REPLACE FUNCTION getename(v_empno NUMBER) RETURN VARCHAR2 AS v_ename VARCHAR2(20);BEGINSELECT ename INTO v_ename FROM emp WHERE empno=v_empno;RETURN v_ename; END;
public void getenamefun(int empno){//sqlString ename="";String sql="{?=call getename(?)}";CallableStatement fun=null;getConnection();try {fun=conn.prepareCall(sql);fun.setInt(2, empno);fun.registerOutParameter(1, Types.VARCHAR);fun.execute();ename=fun.getString(1);System.out.println(ename);} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}
其它的方法与过程一样,只是多了个返回值类型
转载于:https://www.cnblogs.com/liunanjava/p/4261242.html
Java中执行存储过程和函数(web基础学习笔记十四)相关推荐
- JSTL标签引入(web基础学习笔记十八)
一.JSTL包下载和引入 1.0.简介 JSTL全名为JavaServer Pages Standard Tag Library 1.1.下载包 下载地址:http://archive.apache. ...
- Java基础学习——第十四章 网络编程
Java基础学习--第十四章 网络编程 一.网络编程概述 计算机网络: 把分布在不同地理区域的计算机与专门的外部设备用通信线路互连成一个规模大.功能强的网络系统,从而使众多的计算机可以方便地互相传递信 ...
- Java web基础学习笔记
1.xml概述 1.1xml:xml一种数据存储格式,这种数据存储格式在存储数据内容的同时,还能够保存数据之间的关系 1.2xml保存数据的方法:xml利用标签来保存数据的内容,利用标签之间的嵌套关系 ...
- java中jquery怎么学,Jquery的基础学习
1.Jquery是Javascript的一个简单框架,它可以让我们写更少的代码,达到更高的效率,提供更完美的效果! 2.www.jquery.com(官网) → 下载(production版本即可.) ...
- java中预编译是啥意思_JAVA学习笔记预编译
JAVA学习笔记预编译 (2011-07-30 02:36:17) 标签: 杂谈 第顺次运行jsp时jsp将被改换成servlet(第顺次工夫较长,而尔后就会快许多) 搭配好的利用过程能够穿越设置js ...
- JSP常用标记——(web基础学习笔记)
include指令标记 语法: <%@ include file="文件的URL" %> 目的:在jsp页面内某处整体静态嵌入一个文件.include指令可以实现代码的 ...
- web中的cookies以及作用--web testing 学习笔记
Cookie 为 Web 应用程序保存用户相关信息提供了一种有用的方法.例如,当用户访问您的站点时,您可以利用 Cookie 保存用户首选项或其他信息,这样,当用户下次再访问您的站点时,应用程序就可以 ...
- java中人民币的符号怎么打_Java学习笔记---字符串操作(人民币大写转换的实现)...
向开始学习语言的的同学们推荐下,如果你想学习语言的某个特性,比方说数据库编程,或者网络编程,最好找一个实用的例子,然后不懂的去翻书,去查资料,这样目的性就很强了,个人感觉比对着语法书敲上面的例子效率要 ...
- java基础学习笔记(四、常用基础类)
Random类 主要有两个方法: Random r = new Random(); int i = r.nextInt(100); //[0,100)范围内的随机整数 double d = r.nex ...
最新文章
- Oracle Application R11i
- 演讲十忌(翻译并制作成PPT)
- 检测到的ASP.NET设置不适用于集成管理管道模式
- 双边滤波+ 通俗自己理解
- 各种ARM仿真器接口图
- 【vue】ios中从详情页中返回到列表页出现空白的问题
- mongo在哪创建管理员_MongoDB数据库创建管理员账户和数据库管理账户
- iOS开发证书和配置文件的使用
- matlab 图像分块及恢复
- 元素出现在页面时,添加动画,配合animate.css使用
- 浅谈 JSON 那些被转义的字符们
- add file in debian/source/include-binaries if you want to store the modified binary in the debian
- 如何将优酷独享视频kux格式转换成mp4视频
- 编译原理实验二【语法分析程序设计】
- 桌面右下角出现“测试模式 Windows7 内部版本7601”怎么回事?
- latch: cache buffers chains问题分析
- 【K-近邻】K-NN 实战分析 Facebook V Results: Predicting Check Ins
- 山东理工ACM 1115 C语言实验——交换两个整数的值(顺序结构)两种方法
- 白鲸优化算法(Beluga whale optimization,BWO)Python实现
- ftp文件缓存服务器,ftp服务器上的缓存在哪