Java调用MySQL存储过程的完整指南
在Java中调用MySQL存储过程可以通过JDBC实现,以下是详细的步骤和示例代码:

(图片来源网络,侵删)
准备工作
确保你已经:
- 添加了MySQL JDBC驱动依赖(如
mysql-connector-java) - 有MySQL数据库访问权限
- 已创建好要调用的存储过程
创建MySQL存储过程示例
首先创建一个简单的存储过程用于演示:
-- 带输入参数的存储过程
DELIMITER //
CREATE PROCEDURE get_user_by_id(IN user_id INT)
BEGIN
SELECT id, username, email, created_at
FROM users
WHERE id = user_id;
END //
DELIMITER ;
-- 带输入输出参数的存储过程
DELIMITER //
CREATE PROCEDURE update_user_email(
IN user_id INT,
IN new_email VARCHAR(100),
OUT affected_rows INT
)
BEGIN
UPDATE users
SET email = new_email
WHERE id = user_id;
SET affected_rows = ROW_COUNT();
END //
DELIMITER ;
Java调用存储过程的几种方式
1 调用无返回值的存储过程
import java.sql.*;
public class CallStoredProcedureExample {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/your_database";
String user = "username";
String password = "password";
try (Connection conn = DriverManager.getConnection(url, user, password)) {
// 调用无返回值的存储过程
CallableStatement cstmt = conn.prepareCall("{call some_procedure()}");
cstmt.execute();
System.out.println("存储过程执行成功");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
2 调用带输入参数的存储过程
// 调用get_user_by_id存储过程
try (Connection conn = DriverManager.getConnection(url, user, password)) {
int userId = 1;
CallableStatement cstmt = conn.prepareCall("{call get_user_by_id(?)}");
cstmt.setInt(1, userId); // 设置输入参数
ResultSet rs = cstmt.executeQuery();
while (rs.next()) {
System.out.println("ID: " + rs.getInt("id"));
System.out.println("Username: " + rs.getString("username"));
System.out.println("Email: " + rs.getString("email"));
}
} catch (SQLException e) {
e.printStackTrace();
}
3 调用带输入输出参数的存储过程
// 调用update_user_email存储过程
try (Connection conn = DriverManager.getConnection(url, user, password)) {
int userId = 1;
String newEmail = "newemail@example.com";
CallableStatement cstmt = conn.prepareCall("{call update_user_email(?, ?, ?)}");
cstmt.setInt(1, userId); // 设置输入参数1
cstmt.setString(2, newEmail); // 设置输入参数2
cstmt.registerOutParameter(3, Types.INTEGER); // 注册输出参数
cstmt.execute();
int affectedRows = cstmt.getInt(3); // 获取输出参数
System.out.println("影响的行数: " + affectedRows);
} catch (SQLException e) {
e.printStackTrace();
}
4 调用返回结果集的存储过程
// 调用返回结果集的存储过程
try (Connection conn = DriverManager.getConnection(url, user, password)) {
CallableStatement cstmt = conn.prepareCall("{call get_users_with_limit(?)}");
cstmt.setInt(1, 10); // 设置输入参数
boolean hasResult = cstmt.execute();
if (hasResult) {
ResultSet rs = cstmt.getResultSet();
while (rs.next()) {
System.out.println("ID: " + rs.getInt("id") +
", Username: " + rs.getString("username"));
}
}
} catch (SQLException e) {
e.printStackTrace();
}
使用try-with-resources的最佳实践
推荐使用try-with-resources语句确保资源自动关闭:
try (Connection conn = DriverManager.getConnection(url, user, password);
CallableStatement cstmt = conn.prepareCall("{call your_procedure(?, ?)}")) {
// 设置参数和执行逻辑
} catch (SQLException e) {
// 异常处理
}
注意事项
- 参数索引:参数索引从1开始,不是0
- 参数类型:确保设置的参数类型与存储过程定义一致
- 结果处理:调用
execute()后,可能需要处理多个结果集或更新计数 - 性能:存储过程通常比直接SQL执行更快,但过度使用可能影响代码可维护性
- 错误处理:妥善处理SQLException,特别是数据库连接问题
使用Spring框架的示例(可选)
如果你使用Spring框架,可以通过JdbcTemplate更简洁地调用存储过程:

(图片来源网络,侵删)
@Autowired
private JdbcTemplate jdbcTemplate;
public void callStoredProcedure() {
jdbcTemplate.call(con -> {
CallableStatement cs = con.prepareCall("{call get_user_by_id(?)}");
cs.setInt(1, 1);
return cs;
}, new ArrayList<>());
}
就是在Java中调用MySQL存储过程的完整指南,涵盖了各种常见场景和最佳实践。

(图片来源网络,侵删)
