Calling MySQL Stored Procedures from JDBC

在本教程中,您将学习如何使用 CallableStatement 对象从 JDBC 调用 MySQL 存储过程。

在你开始之前

为了演示,我们将创建一个名为get_candidate_skill的新存储过程,该过程接受candidate_id作为 IN 参数,并返回包含候选人技能的结果集。

DELIMITER $$
CREATE PROCEDURE get_candidate_skill(IN candidate_id INT)
BEGIN
	SELECT candidates.id, first_name,last_name, skills.name AS skill 
	FROM candidates
	INNER JOIN candidate_skills ON candidates.id = candidate_skills.candidate_id
	INNER JOIN skills ON skills.id = candidate_skills.skill_id
	WHERE candidates.id = candidate_id;
    END$$
DELIMITER ;Code language: SQL (Structured Query Language) (sql)

我们针对值为 122 的候选人 id 调用此存储过程。

CALL get_candidate_skill(122);Code language: SQL (Structured Query Language) (sql)
jdbc mysql 存储过程

CallableStatement 和存储过程调用语法简介

要从 JDBC 调用 MySQL 中的存储过程或存储函数,可以使用CallableStatement对象,该对象继承自PreparedStatement 对象。调用存储过程的一般语法如下:

{?= call procedure_name(param1,param2,...)}Code language: SQL (Structured Query Language) (sql)

将存储过程调用括在大括号 ({}) 内。如果存储过程有返回值,则需要在call关键字前添加问号和等号(?=)。如果存储过程不返回任何值,则只需省略?=符号即可。如果存储过程接受任何参数,则将它们列在存储过程名称后面的左括号和右括号内。

以下是在不同上下文中使用调用存储过程的语法的示例:

句法商店程序
{ 调用 procedure_name() }不接受任何参数并且不返回任何值
{ 调用 procedure_name(?,?) }接受两个参数并且不返回任何值
{?= 调用 procedure_name() }不接受参数并返回值
{?= 调用 procedure_name(?) }接受一个参数并返回值

请注意,问号占位符 (?) 可用于 IN 、OUT 和 INOUT 参数。有关存储过程中不同参数类型的详细信息,请查看MySQL 存储过程参数教程

JDBC MySQL 存储过程示例

首先,通过创建一个新的Connection对象来打开与 MySQL 服务器的连接。

Connection conn = DriverManager.getConnection();Code language: Java (java)

然后,准备存储过程调用并通过调用Connection对象的prepareCall()方法创建CallableStatement对象。

String query = "{CALL get_candidate_skill(?)}";
CallableStatement stmt = conn.prepareCall(query)Code language: Java (java)

接下来,将所有参数传递给存储过程。在这种情况下, get_candidate_skill存储过程仅接受一个 IN 参数。

stmt.setInt(1, candidateId);Code language: Java (java)

之后,通过调用CallableStatement对象的executeQuery()方法执行存储过程。在这种情况下它返回一个结果集。

ResultSet rs = stmt.executeQuery();Code language: Java (java)

最后遍历ResultSet显示结果。

while (rs.next()) {
   System.out.println(String.format("%s - %s",
                      rs.getString("first_name") + " "
                      + rs.getString("last_name"),
                      rs.getString("skill")));
}Code language: Java (java)

以下是从 JDBC 调用 MySQL 存储过程的完整示例。

package org.mysqltutorial;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.CallableStatement;

/**
 *
 * @author mysqltutorial.org
 */
public class Main {

    /**
     * Get skills by candidate id
     *
     * @param candidateId
     */
    public static void getSkills(int candidateId) {
        // 
        String query = "{ call get_candidate_skill(?) }";
        ResultSet rs;

        try (Connection conn = MySQLJDBCUtil.getConnection();
                CallableStatement stmt = conn.prepareCall(query)) {

            stmt.setInt(1, candidateId);

            rs = stmt.executeQuery();
            while (rs.next()) {
                System.out.println(String.format("%s - %s",
                        rs.getString("first_name") + " "
                        + rs.getString("last_name"),
                        rs.getString("skill")));
            }
        } catch (SQLException ex) {
            System.out.println(ex.getMessage());
        }
    }

    /**
     *
     * @param args
     */
    public static void main(String[] args) {
        getSkills(122);
    }
}Code language: Java (java)

让我们运行该程序。

jdbc mysql 存储过程示例

该程序按预期工作。

在本教程中,我们向您展示了如何使用 JDBC CallableStatement 对象从 Java 程序调用 MySQL 数据库中的存储过程。

本教程有帮助吗?