java怎么得到oracle的游标
- 后端开发
- 2025-09-01
- 7
Java中获取Oracle的游标(Cursor)通常涉及使用JDBC(Java Database Connectivity)来与Oracle数据库进行交互,以下是详细的步骤和示例代码,帮助你理解如何在Java中获取和使用Oracle的游标。
准备工作
确保你已经具备以下条件:
- Oracle数据库:确保你有一个可访问的Oracle数据库实例,并且有相应的权限执行SQL查询。
- JDBC驱动:下载并添加Oracle JDBC驱动到你的项目中,你可以从Oracle官方网站下载适合你数据库版本的JDBC驱动。
- Java开发环境:确保你的Java开发环境已经配置好,可以使用IDE如IntelliJ IDEA、Eclipse等。
引入必要的库
在你的Java项目中,需要引入Oracle JDBC驱动,假设你使用的是Maven项目,可以在pom.xml中添加以下依赖:

如果不是Maven项目,确保将ojdbc8.jar添加到项目的类路径中。
建立数据库连接
使用JDBC建立与Oracle数据库的连接,你需要提供数据库的URL、用户名和密码。

执行查询并获取游标
在建立连接后,可以执行SQL查询并获取结果集(ResultSet),这类似于获取游标,以下是一个简单的查询示例:
import java.sql.Statement; import java.sql.ResultSet; // 在建立连接后的try块内添加以下代码 Statement statement = null; ResultSet resultSet = null; try { // 创建Statement对象 statement = connection.createStatement(); // 执行SQL查询 String sql = "SELECT employee_id, first_name, last_name FROM employees"; resultSet = statement.executeQuery(sql); // 处理结果集 while (resultSet.next()) { int id = resultSet.getInt("employee_id"); String firstName = resultSet.getString("first_name"); String lastName = resultSet.getString("last_name"); System.out.println("ID: " + id + ", 姓名: " + firstName + " " + lastName); } } catch (SQLException e) { e.printStackTrace(); } finally { // 关闭资源 if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } }
使用预编译语句(PreparedStatement)
为了提高安全性和性能,推荐使用PreparedStatement来执行参数化查询,以下是使用PreparedStatement的示例:
import java.sql.PreparedStatement; // 在建立连接后的try块内添加以下代码 PreparedStatement preparedStatement = null; try { // 创建PreparedStatement对象 String sql = "SELECT department_id, department_name FROM departments WHERE department_id = ?"; preparedStatement = connection.prepareStatement(sql); // 设置参数 preparedStatement.setInt(1, 10); // 查询department_id为10的部门 // 执行查询 resultSet = preparedStatement.executeQuery(); // 处理结果集 while (resultSet.next()) { int deptId = resultSet.getInt("department_id"); String deptName = resultSet.getString("department_name"); System.out.println("部门ID: " + deptId + ", 部门名称: " + deptName); } } catch (SQLException e) { e.printStackTrace(); } finally { // 关闭资源 if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } if (preparedStatement != null) { try { preparedStatement.close(); } catch (SQLException e) { e.printStackTrace(); } } }
使用存储过程和调用者(CallableStatement)
你可能需要调用存储过程并获取游标作为输出参数,以下是一个示例,展示如何调用存储过程并处理返回的游标。

假设有以下存储过程:
CREATE OR REPLACE PROCEDURE get_employees_cursor ( p_department_id IN NUMBER, p_employees OUT SYS_REFCURSOR ) AS BEGIN OPEN p_employees FOR SELECT employee_id, first_name, last_name FROM employees WHERE department_id = p_department_id; END;
Java代码调用该存储过程并处理游标:
import java.sql.CallableStatement; import java.sql.Array; import java.sql.ResultSet; // 在建立连接后的try块内添加以下代码 CallableStatement callableStatement = null; ResultSet rs = null; try { // 创建CallableStatement对象 String sql = "{call get_employees_cursor(?, ?)}"; callableStatement = connection.prepareCall(sql); // 设置输入参数 callableStatement.setInt(1, 10); // 部门ID为10 // 注册输出参数(REF_CURSOR) callableStatement.registerOutParameter(2, java.sql.Types.REF_CURSOR); // 执行存储过程 callableStatement.execute(); // 获取游标 rs = (ResultSet) callableStatement.getObject(2); // 处理结果集 while (rs.next()) { int id = rs.getInt("employee_id"); String firstName = rs.getString("first_name"); String lastName = rs.getString("last_name"); System.out.println("员工ID: " + id + ", 姓名: " + firstName + " " + lastName); } } catch (SQLException e) { e.printStackTrace(); } finally { // 关闭资源 if (rs != null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if (callableStatement != null) { try { callableStatement.close(); } catch (SQLException e) { e.printStackTrace(); } } }
使用RowSet和Caching机制(高级)
对于更复杂的场景,如需要在应用层缓存数据或支持滚动更新,可以使用RowSet接口及其实现类,如CachedRowSet,以下是一个简单的示例:
import javax.sql.rowset.CachedRowSet; import javax.sql.rowset.RowSetProvider; // 在建立连接后的try块内添加以下代码 CachedRowSet rowSet = null; try { // 创建CachedRowSet对象 rowSet = RowSetProvider.newFactory().createCachedRowSet(); // 设置命令和参数(可选) rowSet.setCommand("SELECT employee_id, first_name, last_name FROM employees WHERE department_id = ?"); rowSet.setInt(1, 10); // 设置参数值 // 执行查询并填充RowSet rowSet.execute(connection); // 处理RowSet中的数据 while (rowSet.next()) { int id = rowSet.getInt("employee_id"); String firstName = rowSet.getString("first_name"); String lastName = rowSet.getString("last_name"); System.out.println("员工ID: " + id + ", 姓名: " + firstName + " " + lastName); } } catch (SQLException e) { e.printStackTrace(); } finally { // CachedRowSet不需要显式关闭,但可以将其关闭以释放资源 if (rowSet != null) { try { rowSet.close(); } catch (SQLException e) { e.printStackTrace(); } } }
完整示例代码汇总
以下是将上述各部分整合在一起的完整示例代码:
import java.sql.; import javax.sql.rowset.CachedRowSet; import javax.sql.rowset.RowSetProvider; public class OracleCursorExample { public static void main(String[] args) { // 数据库连接参数 String url = "jdbc:oracle:thin:@//localhost:1521/orcl"; // 根据实际情况修改 String username = "your_username"; String password = "your_password"; Connection connection = null; try { // 加载Oracle JDBC驱动 Class.forName("oracle.jdbc.driver.OracleDriver"); // 建立连接 connection = DriverManager.getConnection(url, username, password); System.out.println("数据库连接成功!"); // ================================== // 示例1:使用Statement执行查询 // ================================== Statement statement = null; ResultSet resultSet = null; try { // 创建Statement对象 statement = connection.createStatement(); // 执行SQL查询 String sql = "SELECT employee_id, first_name, last_name FROM employees"; resultSet = statement.executeQuery(sql); // 处理结果集 while (resultSet.next()) { int id = resultSet.getInt("employee_id"); String firstName = resultSet.getString("first_name"); String lastName = resultSet.getString("last_name"); System.out.println("[Statement] ID: " + id + ", 姓名: " + firstName + " " + lastName); } } catch (SQLException e) { e.printStackTrace(); } finally { // 关闭资源 if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } } // ================================== // 示例2:使用PreparedStatement执行参数化查询 // ================================== PreparedStatement preparedStatement = null; try { // 创建PreparedStatement对象 String sql = "SELECT department_id, department_name FROM departments WHERE department_id = ?"; preparedStatement = connection.prepareStatement(sql); // 设置参数 preparedStatement.setInt(1, 10); // 查询department_id为10的部门 // 执行查询 resultSet = preparedStatement.executeQuery(); // 处理结果集 while (resultSet.next()) { int deptId = resultSet.getInt("department_id"); String deptName = resultSet.getString("department_name"); System.out.println("[PreparedStatement] 部门ID: " + deptId + ", 部门名称: " + deptName); } } catch (SQLException e) { e.printStackTrace(); } finally { // 关闭资源 if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } if (preparedStatement != null) { try { preparedStatement.close(); } catch (SQLException e) { e.printStackTrace(); } } } // ================================== // 示例3:调用存储过程并获取游标 // ================================== CallableStatement callableStatement = null; ResultSet rs = null; try { // 创建CallableStatement对象 String sql = "{call get_employees_cursor(?, ?)}"; // 确保存储过程存在且正确命名 callableStatement = connection.prepareCall(sql); // 设置输入参数 callableStatement.setInt(1, 10); // 部门ID为10 // 注册输出参数(REF_CURSOR) callableStatement.registerOutParameter(2, java.sql.Types.REF_CURSOR); // 执行存储过程 callableStatement.execute(); // 获取游标 rs = (ResultSet) callableStatement.getObject(2); // 处理结果集 while (rs.next()) { int id = rs.getInt("employee_id"); String firstName = rs.getString("first_name"); String lastName = rs.getString("last_name"); System.out.println("[CallableStatement] 员工ID: " + id + ", 姓名: " + firstName + " " + lastName); } } catch (SQLException e) { e.printStackTrace(); } finally { // 关闭资源 if (rs != null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if (callableStatement != null) { try { callableStatement.close(); } catch (SQLException e) { e.printStackTrace(); } } } // ================================== // 示例4:使用CachedRowSet处理数据 // ================================== CachedRowSet rowSet = null; try { // 创建CachedRowSet对象 rowSet = RowSetProvider.newFactory().createCachedRowSet(); // 设置命令和参数(可选) rowSet.setCommand("SELECT employee_id, first_name, last_name FROM employees WHERE department_id = ?"); rowSet.setInt(1, 10); // 设置参数值 // 执行查询并填充RowSet rowSet.execute(connection); // 处理RowSet中的数据(支持滚动) while (rowSet.next()) { int id = rowSet.getInt("employee_id"); String firstName = rowSet.getString("first_name"); String lastName = rowSet.getString("last_name"); System.out.println("[CachedRowSet] 员工ID: " + id + ", 姓名: " + firstName + " " + lastName); } // 可以向前或向后滚动,支持多次遍历等特性 rowSet.beforeFirst(); // 重置指针到开始位置,方便再次遍历或其他操作,这里仅作示例展示功能可用性,实际应用根据需求决定是否需要此步操作,如果不需要多次遍历,则无需调用此方法,还可以使用其他RowSet的方法进行更复杂的操作,如同步、过滤等。