日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

Java中执行存储过程和函数(web基础学习笔记十四)

發(fā)布時(shí)間:2025/3/15 java 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java中执行存储过程和函数(web基础学习笔记十四) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、概述

如果想要執(zhí)行存儲(chǔ)過(guò)程,我們應(yīng)該使用 CallableStatement 接口。

CallableStatement 接口繼承自PreparedStatement 接口。所以CallableStatement 接口包含有Statement 接口和PreparedStatement 接口定義的全部方法,但是并不是所有的方法我們都要使用,主要使用的方法有這樣幾個(gè):

CallableStatement 常用方法:

返回類(lèi)型方法簽名說(shuō)明
booleanexecute()

執(zhí)行 SQL 語(yǔ)句,如果第一個(gè)結(jié)果是 ResultSet 對(duì)
象,則返回 true;如果第一個(gè)結(jié)果是更新計(jì)數(shù)或者沒(méi)
有結(jié)果,則返回 false

void

registerOutParameter(int parameterIndex,int sqlType)

按順序位置parameterIndex 將OUT 參數(shù)注冊(cè)為
JDBC 類(lèi)型sqlType,sqlType 為T(mén)ypes 類(lèi)中的常量

Type

getType(int?parameterIndex)

根據(jù)參數(shù)的序號(hào)獲取指定的 JDBC 參數(shù)的值。第一
個(gè)參數(shù)是 1,第二個(gè)參數(shù)是 2,依此類(lèi)推

我們可以使用execute()方法來(lái)執(zhí)行存儲(chǔ)過(guò)程。CallableStatement 為所有的數(shù)據(jù)庫(kù)提供了一種統(tǒng)一的標(biāo)準(zhǔn)形式調(diào)用存儲(chǔ)過(guò)程。所以,你將會(huì)看到我們使用execute()調(diào)用存儲(chǔ)過(guò)程的語(yǔ)法與在Oracle 中會(huì)所有不同。

為了獲得存儲(chǔ)過(guò)程或函數(shù)的返回值,我們需要使用 registerOutParameter()方法將返回的參數(shù)注冊(cè)為JDBC 的類(lèi)型。 registerOutParameter()方法的第一個(gè)參數(shù)是參數(shù)的序號(hào),第一個(gè)為1,第二個(gè)為2,以此類(lèi)推。第二個(gè)參數(shù)需要一個(gè)int 值,用來(lái)標(biāo)記JDBC 的類(lèi)型,我們可以使用java.sql.Types 類(lèi)中的常量來(lái)設(shè)置這個(gè)參數(shù)。比如VARCHAR、DOUBLE 等類(lèi)型。如果類(lèi)型不夠用,也可以從具體數(shù)據(jù)庫(kù)的驅(qū)動(dòng)中尋找合適的類(lèi)型常量。如果存儲(chǔ)過(guò)程或函數(shù)有返回值,這個(gè)方法是必須要調(diào)用的,否則無(wú)法得到返回值,甚至?xí)l(fā)生異常。

CallableStatement 接口中定義了很多get 方法,用于獲取存儲(chǔ)過(guò)程返回的值,根據(jù)值的類(lèi)型不同,你可以使用不同get 方法,比如getInt()、getString()、getDouble()等等。
我們看一下使用CallableStatement 接口執(zhí)行存儲(chǔ)過(guò)程和函數(shù)的語(yǔ)法格式。

存儲(chǔ)過(guò)程:{call <procedure-name>[(<arg1>,<arg2>, ...)]}
函數(shù):{?= call <procedure-name>[(<arg1>,<arg2>, ...)]}

如果要調(diào)用存儲(chǔ)過(guò)程,則使用第一種語(yǔ)法,就是開(kāi)頭不帶問(wèn)號(hào)的語(yǔ)法,call 后面是過(guò)程名,
如果沒(méi)有參數(shù),可以省略小括號(hào)。

如果要調(diào)用函數(shù),則使用第二種語(yǔ)法,開(kāi)頭帶有一個(gè)問(wèn)號(hào)加等號(hào),實(shí)際上這個(gè)問(wèn)號(hào)就是一個(gè)占位符,這個(gè)問(wèn)號(hào)總是調(diào)用函數(shù)的第一個(gè)占位符。其它部分與過(guò)程的語(yǔ)法相同

二、CallableStatement 執(zhí)行存儲(chǔ)過(guò)程

2.1、建立基類(lèi)

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;}////查詢(xún)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;}// 關(guān)閉資源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、執(zhí)行不帶參但是有返回值的存儲(chǔ)過(guò)程

新建類(lèi)來(lái)繼承上面的類(lèi)也可以繼承,下面建立存儲(chǔ)過(guò)程

--查詢(xún)emp表記錄數(shù) CREATE OR REPLACE PROCEDURE getEmpCount(v_count OUT NUMBER) AS BEGINSELECT COUNT(*) INTO v_count FROM emp; END;

調(diào)用

//執(zhí)行不帶參但是有返回值的存儲(chǔ)過(guò)程獲取emp表總記錄數(shù)public int getTotalCountProc(){//定義一個(gè)變量來(lái)接收結(jié)果int totalCount=0;//聲明CallableStatement對(duì)象CallableStatement proc=null;String sql="{call getEmpCount(?)}";try {//建立連接 getConnection();//CallableStatement對(duì)象proc=conn.prepareCall(sql);//將數(shù)據(jù)庫(kù)對(duì)象數(shù)據(jù)類(lèi)型注冊(cè)為java中的類(lèi)型proc.registerOutParameter(1, Types.INTEGER);//執(zhí)行 proc.execute();//接收返回值totalCount=proc.getInt(1);} catch (SQLException e) {// TODO Auto-generated catch block e.printStackTrace();}return totalCount;}

2.3、執(zhí)行帶參帶返回值的存儲(chǔ)過(guò)程

--根據(jù)部門(mén)編號(hào)和姓名查詢(xún)?nèi)藬?shù) 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; //執(zhí)行帶參帶返回值的存儲(chǔ)過(guò)程public int getTotalCountProc1(int deptno,String ename){//定義一個(gè)變量來(lái)接收結(jié)果int totalCount=0;//聲明CallableStatement對(duì)象CallableStatement proc=null;String sql="{call getEmpCount(?,?,?)}";//建立連接 getConnection();//CallableStatement對(duì)象try {proc=conn.prepareCall(sql);//設(shè)置占位符//Object [] params={deptno,ename};//只設(shè)置輸入?yún)?shù)即可proc.setInt(1, deptno);proc.setString(2, ename);//proc.setInt(3, totalCount);將數(shù)據(jù)庫(kù)對(duì)象數(shù)據(jù)類(lèi)型注冊(cè)為java中的類(lèi)型,將輸出參數(shù)轉(zhuǎn)換proc.registerOutParameter(3, Types.INTEGER);//執(zhí)行 proc.execute();//獲取結(jié)果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、執(zhí)行返回值為游標(biāo)的存儲(chǔ)過(guò)程

--查詢(xún)員工所有信息 CREATE OR REPLACE PROCEDURE emp_cur(emp_cur OUT SYS_REFCURSOR) AS BEGINOPEN emp_cur FOR SELECT * FROM emp; END; //執(zhí)行返回值為游標(biāo)的存儲(chǔ)過(guò)程 游標(biāo)名emp_curpublic List<Emp> getempProc1(){List<Emp> emplist=new ArrayList<Emp>();String sql="{call emp_cur(?) }";//聲明CallableStatement對(duì)象CallableStatement proc=null;//建立連接getConnection();try {//執(zhí)行proc=conn.prepareCall(sql);//注冊(cè)類(lèi)型為數(shù)據(jù)庫(kù)游標(biāo)類(lèi)型proc.registerOutParameter(1, oracle.jdbc.OracleTypes.CURSOR);//接收結(jié)果集proc.execute();//獲取結(jié)果第一個(gè)對(duì)象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對(duì)象Emp emp=new Emp();//將得到的值添加到對(duì)象中emp.setEmpno(empno);emp.setEname(ename);emp.setJob(job);emp.setMgr(mgr);emp.setHiredate(hiredate);emp.setSal(sal);emp.setComm(comm);emp.setDeptno(deptno);//將對(duì)象添加到集合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;}

以上看出,需要將輸出的參數(shù),和結(jié)果注冊(cè),輸入的參數(shù)不要注冊(cè),

但輸入?yún)?shù)需要設(shè)置占位符

三、執(zhí)行函數(shù)

3.1 、函數(shù)功能為根據(jù)雇員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();}}

其它的方法與過(guò)程一樣,只是多了個(gè)返回值類(lèi)型

?

轉(zhuǎn)載于:https://www.cnblogs.com/liunanjava/p/4261242.html

總結(jié)

以上是生活随笔為你收集整理的Java中执行存储过程和函数(web基础学习笔记十四)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。