JDBC调用存储过程与存储函数

67 篇文章 16 订阅

在JDBC API中提供了调用存储过程的方法,通过CallableStatement对象进行操作。CallableStatement对象位于java.sql包中,它继承于PreparedStatement对象,PreparedStatement对象又继承于Statement对象。CallableStatement对象主要用于执行数据库中定义的存储过程和存储函数,其调用方法如下:

调用存储过程:{call <procedure-name>[(<arg1>,<arg2>, ...)]}

调用存储函数:{?= call <procedure-name>[(<arg1>,<arg2>, ...)]} 

CallableStatement对象的常用方法:

下面将以调用MySQL数据的存储过程和存储函数为示例。

1、创建数据库连接与关闭

1.1 获取MySQL数据库的连接

import java.sql.*; //导入java.sql包
// 数据库驱动
public static final String DRIVER_CLASS = "com.mysql.cj.jdbc.Driver";

// 数据库连接地址
public static final String DB_URL = "jdbc:mysql://localhost:3306/db_admin?serverTimezone=Hongkong&useUnicode=true&characterEncoding=utf8&useSSL=false";

// 数据库用户名称
public static final String DB_USER = "root";

// 数据库用户密码
public static final String DB_PASSWORD = "123456";

/**
 * 获取数据库连接
 * 
 * @author pan_junbiao
 * @return 数据库连接对象
 */
public static Connection getConnection()
{
	Connection conn = null;

	try
	{
		// 加载数据库驱动类
		Class.forName(DRIVER_CLASS);
		System.out.println("数据库驱动加载成功");

		// 获取数据库连接对象
		conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
		System.out.println("数据库连接成功");

	} catch (ClassNotFoundException cnfe)
	{
		cnfe.printStackTrace();
	} catch (SQLException sqle)
	{
		sqle.printStackTrace();
	} catch (Exception ex)
	{
		ex.printStackTrace();
	}

	return conn;
}

1.2 关闭相关数据操作对象

/**
 * 关闭数据库操作对象
 * 
 * @author pan_junbiao
 * @param res  ResultSet对象
 * @param stmt Statement对象
 * @param conn Connection对象
 */
public static void closeOperate(ResultSet res, Statement stmt, Connection conn)
{
	try
	{
		// 关闭ResultSet对象
		if (res != null)
		{
			res.close();
		}

		// 关闭Statement对象
		if (stmt != null)
		{
			stmt.close();
		}

		// 关闭Connection对象
		if (conn != null)
		{
			conn.close();
		}

		System.out.println("关闭数据库操作对象完成");

	} catch (SQLException sqle)
	{
		sqle.printStackTrace();
	}
}

 

2、调用存储过程

示例:通过调用存储过程,获取用户分页列表,数据总数和总页数。

2.1 创建存储过程

/*
  -- 存储过程:分页查询用户列表
  -- 输入参数:page_index:当前页码
  -- 输入参数:page_size:分页大小
  -- 输出参数:total_count:数据总数
  -- 输出参数:total_page:总页数
*/
DROP PROCEDURE IF EXISTS proc_search_user;
CREATE PROCEDURE proc_search_user(IN page_index INT,IN page_size INT, OUT total_count INT, OUT total_page INT)
BEGIN
		DECLARE begin_no INT;
		SET begin_no = (page_index-1)*page_size;
 
		-- 分页查询列表
		SELECT * FROM tb_user
		WHERE id >= (
			SELECT id FROM tb_user
			ORDER BY id ASC
			LIMIT begin_no,1
		)
		ORDER BY id ASC
		LIMIT page_size;

		-- 计算数据总数
		SELECT COUNT(1) INTO total_count FROM tb_user;

		-- 计算总页数
		SET total_page = FLOOR((total_count + page_size - 1) / page_size);

END;

2.2 调用存储过程

/**
 * 调用存储过程
 * 
 * @author pan_junbiao
 */
public static void execProcedure()
{
	Connection conn = null; // 数据库连接对象
	CallableStatement clbStmt = null; // CallableStatement对象
	ResultSet res = null; // 结果集对象
	try
	{
		// 获取数据库连接
		conn = getConnection();

		// 创建CallableStatement对象
		clbStmt = conn.prepareCall("{CALL proc_search_user(?,?,?,?)}");

		// 设置输入参数
		clbStmt.setInt(1, 3); // 查询第3页数据
		clbStmt.setInt(2, 10); // 每页10条数据

		// 注册输出参数
		clbStmt.registerOutParameter(3, Types.INTEGER);
		clbStmt.registerOutParameter(4, Types.INTEGER);

		// 执行调用存储过程,并获取结果集
		res = clbStmt.executeQuery();

		// 循环遍历结果集
		while (res.next())
		{
			// 获取列值
			int id = res.getInt("id");
			String name = res.getString("name");
			Timestamp createTime = res.getTimestamp("create_time");

			// 输出列值
			System.out.println("编号:" + id + "  姓名:" + name + "  创建时间:" + createTime);
		}

		// 获取输出参数值
		int totalCount = clbStmt.getInt(3);
		int totalPage = clbStmt.getInt(4);
		System.out.println("数据总数:" + totalCount + " 总页数:" + totalPage);

	} catch (SQLException sqle)
	{
		sqle.printStackTrace();
	} finally
	{
		// 关闭数据库操作对象
		closeOperate(res, clbStmt, conn);
	}
}

执行结果:

 

3、调用存储函数

示例:通过调用存储函数,根据用户编号,获取用户姓名。

3.1 创建存储函数

/*
    -- 存储函数:根据用户编号,获取用户姓名
    -- 输入参数:用户编号
    -- 返回结果:用户姓名
*/
DROP FUNCTION IF EXISTS func_get_user_name;
CREATE FUNCTION func_get_user_name(in_id INT)
RETURNS VARCHAR(30)
BEGIN
	DECLARE out_name VARCHAR(30);
 
	SELECT name INTO out_name FROM tb_user
	WHERE id = in_id;
 
	RETURN out_name;
END;

3.2 调用存储函数

/**
 * 调用存储函数
 * 
 * @author pan_junbiao
 */
public static void execFunction()
{
	Connection conn = null; // 数据库连接对象
	CallableStatement clbStmt = null; // CallableStatement对象
	try
	{
		// 获取数据库连接
		conn = getConnection();

		// 创建CallableStatement对象
		clbStmt = conn.prepareCall("{?=CALL func_get_user_name(?)}");

		// 注册输出结果参数
		clbStmt.registerOutParameter(1, Types.VARCHAR);

		// 设置输入参数
		clbStmt.setInt(2, 5);

		// 执行调用存储函数
		clbStmt.execute();

		// 获取输出参数值
		String userName = clbStmt.getString(1);
		System.out.println("用户名称:" + userName);

	} catch (SQLException sqle)
	{
		sqle.printStackTrace();
	} finally
	{
		// 关闭数据库操作对象
		closeOperate(null, clbStmt, conn);
	}
}

执行结果:

 

  • 32
    点赞
  • 112
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
存储过程存储函数)是一段预先编译好的SQL代码,可被多次调用。它通常用于执行一些复杂的操作,如数据验证、数据转换、数据计算和数据访问等,可以提高数据库的性能和安全性。 触发器是一种数据库对象,它是与特定表相关联的一个程序,可以在特定的数据库事件(如插入、更新或删除)发生时自动执行。触发器通常用于维护数据一致性和完整性,可以执行一些验证、转换、计算和访问操作等。 在Java程序中,可以通过JDBC调用存储过程存储函数),一般步骤如下: 1. 加载数据库驱动程序:使用`Class.forName()`方法加载数据库驱动程序。 2. 建立数据库连接:使用`DriverManager.getConnection()`方法建立数据库连接,需要提供数据库的URL、用户名和密码。 3. 创建CallableStatement对象:使用`Connection.prepareCall()`方法创建CallableStatement对象,用于调用存储过程存储函数)。 4. 设置参数:使用`CallableStatement.setXXX()`方法设置存储过程存储函数)的输入参数和输出参数。 5. 执行存储过程存储函数):使用CallableStatement对象的`execute()`或`executeQuery()`方法执行存储过程存储函数)。 6. 处理输出结果:如果存储过程存储函数)有输出参数,则需要使用CallableStatement对象的`getXXX()`方法获取输出参数的值。 7. 关闭数据库连接:使用`Connection.close()`方法关闭数据库连接。 需要注意的是,在调用存储过程存储函数)时,需要使用存储过程存储函数)的完整名称(包括数据库名称、模式名称和对象名称)。例如,如果存储过程的名称为`SP_INSERT_USER`,则需要使用完整名称来调用它,如`{call database.schema.SP_INSERT_USER(?, ?, ?)}`。同时,需要根据存储过程存储函数)的输入参数和输出参数的类型来设置对应的`setXXX()`和`getXXX()`方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pan_junbiao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值