Java调用Oracle存储过程指南
在Java中调用Oracle存储过程有多种方式,以下是几种常见的方法:

(图片来源网络,侵删)
使用CallableStatement调用无返回值的存储过程
import java.sql.*;
public class CallOracleProcedure {
public static void main(String[] args) {
Connection conn = null;
CallableStatement cstmt = null;
try {
// 1. 获取数据库连接
conn = DriverManager.getConnection(
"jdbc:oracle:thin:@localhost:1521:ORCL",
"username",
"password");
// 2. 创建CallableStatement对象
// {? = call procedure_name(?, ?, ...)}
cstmt = conn.prepareCall("{call procedure_name(?, ?)}");
// 3. 设置输入参数
cstmt.setString(1, "参数1");
cstmt.setInt(2, 123);
// 4. 执行存储过程
cstmt.execute();
System.out.println("存储过程执行成功");
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 5. 关闭资源
try {
if (cstmt != null) cstmt.close();
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
调用有返回值的存储过程(OUT参数)
public class CallOracleProcedureWithOut {
public static void main(String[] args) {
Connection conn = null;
CallableStatement cstmt = null;
try {
conn = DriverManager.getConnection(
"jdbc:oracle:thin:@localhost:1521:ORCL",
"username",
"password");
// 使用?表示OUT参数
cstmt = conn.prepareCall("{call procedure_name(?, ?)}");
// 设置输入参数
cstmt.setString(1, "输入参数");
// 注册OUT参数类型
cstmt.registerOutParameter(2, Types.VARCHAR);
// 执行存储过程
cstmt.execute();
// 获取OUT参数值
String result = cstmt.getString(2);
System.out.println("存储过程返回值: " + result);
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 关闭资源
try {
if (cstmt != null) cstmt.close();
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
调用有返回值的存储过程(返回结果集)
如果存储过程返回结果集,需要使用REF CURSOR:
public class CallOracleProcedureWithResultSet {
public static void main(String[] args) {
Connection conn = null;
CallableStatement cstmt = null;
ResultSet rs = null;
try {
conn = DriverManager.getConnection(
"jdbc:oracle:thin:@localhost:1521:ORCL",
"username",
"password");
// 首先需要定义REF CURSOR类型
// Oracle中可以使用SYS_REFCURSOR类型
cstmt = conn.prepareCall("{call procedure_name(?, ?)}");
// 设置输入参数
cstmt.setString(1, "参数值");
// 注册输出参数为Oracle的REF CURSOR类型
cstmt.registerOutParameter(2, OracleTypes.CURSOR);
// 执行存储过程
cstmt.execute();
// 获取结果集
rs = (ResultSet) cstmt.getObject(2);
// 处理结果集
while (rs.next()) {
System.out.println(rs.getString("column_name"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 关闭资源
try {
if (rs != null) rs.close();
if (cstmt != null) cstmt.close();
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
使用Spring Data JPA调用存储过程
如果你使用Spring框架,可以通过JdbcTemplate或Repository接口调用存储过程:
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.SqlOutParameter;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.core.simple.SimpleJdbcCall;
import java.sql.Types;
import java.util.HashMap;
import java.util.Map;
public class SpringProcedureCall {
private JdbcTemplate jdbcTemplate;
public void callProcedure() {
// 方法1:使用SimpleJdbcCall
SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate)
.withSchemaName("schema_name")
.withCatalogName("package_name")
.withProcedureName("procedure_name")
.declareParameters(
new SqlParameter("input_param", Types.VARCHAR),
new SqlOutParameter("output_param", Types.VARCHAR)
);
Map<String, Object> inParams = new HashMap<>();
inParams.put("input_param", "test");
Map<String, Object> outParams = jdbcCall.execute(inParams);
String result = (String) outParams.get("output_param");
// 方法2:直接使用JdbcTemplate
jdbcTemplate.update("{call procedure_name(?, ?)}",
"input_value",
Types.VARCHAR);
}
}
注意事项
- 确保Oracle JDBC驱动(如ojdbc8.jar或ojdbc11.jar)已添加到项目中
- 根据Oracle版本和存储过程参数类型正确设置参数
- 对于大型应用,考虑使用连接池(如HikariCP)
- 处理SQLException时注意资源释放
- 对于复杂存储过程,可能需要调整SQL语法以匹配Oracle方言
方法涵盖了Java调用Oracle存储过程的主要场景,你可以根据实际需求选择合适的方式。

(图片来源网络,侵删)
