1、储过程
1.1、有简单输出参数的存储过程
存储过程
create or replace procedure pro_simple_out(v_id in number,v_name out varchar2) is
begin
select name into v_name from t_owners where id=v_id;
end;
调用存储过程
public static String getOwnerName(int id){
String name= "";
java.sql.Connection conn = null;
java.sql.CallableStatement stmt = null;
try {
conn = BaseDao.getConnection();
stmt = conn.prepareCall("{call pro_simple_out(?,?)}");
stmt.setInt(1, id);
stmt.registerOutParameter(2, OracleTypes.VARCHAR);//注册传出参数类型
stmt.execute();
name = stmt.getString(2);//提取传出参数
} catch (SQLException e) {
e.printStackTrace();
} finally {
BaseDao.closeAll(null, stmt, conn);
}
return name;
}
获取连接BaseDao
package com.francis.waterboos.dao;
import java.sql.*;
/**
* @author Francis
* @create 2021-08-25 14:48
*/
public class BaseDao {
//加载驱动
static {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获取数据库连接
*
* @return
* @throws SQLException
*/
public static Connection getConnection() throws SQLException {
//thin:瘦客户端的连接方式,采用这种连接方式不需要安装oracle客户端,只要求包含jdbc驱动的jar包就行。
//oci:oci是一种胖客户端的连接方式,采用这种连接方式需要安装oracle客户端。
//oci是Oracle Call Interface的首字母缩写,是ORACLE公司提供了访问接口。
//使用Java来调用本机的Oracle客户端,然后再访问数据库,优点是速度 快,但是需要安装和配置数据库。
//oci必须在客户机上安装oracle客户端或才能连接,而thin就不需要,因此从使用上来讲thin还是更加方便,
// 这也是thin比较常见的原因。
return DriverManager.getConnection(
"jdbc:oracle:thin:@127.0.0.1:1521:orcl",
"wateruser", "root");
}
/**
* 关闭资源
*
* @param rs
* @param stmt
* @param conn
*/
public static void closeAll(ResultSet rs, Statement stmt, Connection conn) {
//关闭结果集
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
//关闭执行对象
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
//关闭执行对象
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
测试
package com.francis.waterboos.test;
import com.francis.waterboos.dao.OwnersProDao;
import com.francis.waterboos.entity.Owners;
import java.util.Date;
/**
* @author Francis
* @create 2021-08-25 15:39
*/
public class OwnersTest {
public static void main(String[] args) {
// Owners owners = new Owners();
// owners.setId(31L);
// owners.setName("曾阿牛");
// owners.setAddressid(1L);
// owners.setHousenumber("1-1");
// owners.setWatermeter("22263");
// owners.setAdddate(new Date());
// owners.setOwnertypeid(1L);
// long id = OwnersProDao.add1(owners);
// System.out.println(id);
String ownerName = OwnersProDao.getOwnerName(33);
System.out.println(ownerName);
}
}
1.2、返回为结果集的存储过程
由于oracle的存储过程没有return返回值,它的所有返回值都是通过out参数来替代的,列表同样也不例外,但由于是集合,所以不能用一般的参数必须要用package,所以要分两部分。
1.2.1、创建包
create or replace package testpackage as
type p_sursor is ref cursor;
end testpackage;
1.2.2、在包中创建存储过程
create or replace procedure pro_getowners(v_addressid in number,
outcursor out testpackage.p_sursor) is
begin
open outcursor for select * from t_owners where addressid= v_addressid;
end;
jdbc调用该存储过程
public static void getOwners(int addressId){
ResultSet owners=null;
java.sql.Connection conn = null;
java.sql.CallableStatement stmt = null;
try {
conn = BaseDao.getConnection();
stmt = conn.prepareCall("{call pro_getowners(?,?)}");
stmt.setInt(1, addressId);
stmt.registerOutParameter(2, OracleTypes.CURSOR);//注册传出参数类型
stmt.execute();
owners =(ResultSet) stmt.getObject(2);//提取传出参数
while(owners.next()){
System.out.println(owners.getInt(1)+owners.getString(2)
+owners.getString(4));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
BaseDao.closeAll(null, stmt, conn);
}
}
其实,不用定义包也可以,游标类型也不用定义成指定包下的类型,同样可以掉用成功,至于具体的区别,还在探索中
create or replace procedure pro_getowners1(v_addressid in number,
outcursor out sys_refcursor) is
begin
open outcursor for select * from t_owners where addressid= v_addressid;
end;