JDBC 调用自定义函数(常说的存储过程)的步骤
平常说的存储过程(Procedure),严格意义上是自定义函数,所以这里以【自定义函数】为名,简称【函数(function)】。
package com.joyupx.jdbc;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
/**
* 存储过程严格意义上叫【自定义函数】更适宜。
* 我们这里就叫【自定义函数】,即在数据库中创建的函数,与数据库提供的函数并列。
*/
@Slf4j
public class JDBC_Call_SelfDefinedFunction {
/**
* 调用自定义的函数
*/
@Test
public void test_call_selfDefined_function () {
/**
* 第一步、获取数据库的配置
*/
InputStream databaseConfigInputStream = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties") ; // 从【类路径】中获取配置文件
Properties databaseConfigProperties = new Properties();
try {
databaseConfigProperties.load(databaseConfigInputStream); // 加载【数据库】配置文件
} catch (IOException e) {
log.error("加载【数据库配置文件】失败!", e);
return;
}
String username = databaseConfigProperties.getProperty("username");
String password = databaseConfigProperties.getProperty("password");
String jdbcURL = databaseConfigProperties.getProperty("jdbcURL");
String jdbcDriver = databaseConfigProperties.getProperty("jdbcDriver");
/**
* 第二步、注册驱动
*/
try {
Class.forName(jdbcDriver);
} catch (ClassNotFoundException e) {
log.error("没有找到数据库的驱动!", e);
return ;
}
/**
* 第三步、获取数据库的连接
*/
Connection connection = null;
try {
connection = DriverManager.getConnection(jdbcURL, username, password);
} catch (SQLException e) {
log.error("获取 Java 程序与数据库服务端程序的连接对象 - 失败!", e);
return ;
}
/**
* 第四步、编写(与业务密切相关的)SQL,具体到这里是插入数据的 SQL。
*/
String functionSQL = "{ call `artron-trade`.`firstSDF` }"; // 如果无参数可省略末尾的小括号(小括号表示的函数)。
/**
* 第五步、创建 SQL 的【可调用的声明】对象,用于对 SQL 语句做准备工作。
*/
CallableStatement callableStatement = null;
try {
callableStatement = connection.prepareCall(functionSQL);
} catch (SQLException e) {
log.error("创建 SQL【可调用的声明】对象 - 失败!", e);
return;
}
/**
* 第六步:为参数值填充参数据。
*/
int updatedCount = 0;
int count = 0;
/**
* 第七步、执行 SQL 更新操作并获取受影响的行数,具体到此处为执行向数据表中添加数据操作并获取添加成功的行数。
*/
try {
callableStatement.execute();
} catch (SQLException e) {
log.error("执行 SQL 更新(具体到这里是向数据表中添加数据) - 失败!", e);
return;
}
ResultSet resultSet = null;
try {
resultSet = callableStatement.getResultSet();
} catch (SQLException e) {
throw new RuntimeException(e);
}
/**
* 第七步、解析结果;具体到此处是解析查询到的结果集。
*/
if (null != resultSet) {
try {
while (resultSet.next()) {
count = resultSet.getInt(1);
log.info("记录数 = {}", count);
}
} catch (Exception e) {
log.error("迭代结果集出错了!", e);
}
}
/**
* 第八步:解析结果,具体到这里为显示插入成功的记录数
*/
if (0 < updatedCount)
log.info("成功插入 {} 条数据。", updatedCount);
/**
* 第九步、关闭 SQL 的【可调用的声明】对象。
*/
try {
callableStatement.close();
} catch (SQLException e) {
log.error("关闭 SQL【可调用的声明】对象 - 失败!", e);
return;
}
/**
* 第十步、断开与数据库的连接。
*/
try {
connection.close();
} catch (SQLException e) {
log.error("关闭 Java 程序与数据库服务端程序的连接 - 失败!", e);
}
}
/**
* 调用自定义的函数
*/
@Test
public void test_call_selfDefined_function_2 () {
/**
* 第一步、获取数据库的配置
* DELIMITER $$
*
* USE `数据库名`$$
*
* DROP PROCEDURE IF EXISTS `queryChinaRegion`$$
*
* CREATE DEFINER=`用户名`@`%` PROCEDURE `queryChinaRegion`(parentId INT)
* BEGIN
* SELECT * FROM `数据库名`.`t_china_region` r WHERE r.`parentId` = parentId;
* END$$
*
* DELIMITER ;
*/
InputStream databaseConfigInputStream = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties") ; // 从【类路径】中获取配置文件
Properties databaseConfigProperties = new Properties();
try {
databaseConfigProperties.load(databaseConfigInputStream); // 加载【数据库】配置文件
} catch (IOException e) {
log.error("加载【数据库配置文件】失败!", e);
return;
}
String username = databaseConfigProperties.getProperty("username");
String password = databaseConfigProperties.getProperty("password");
String jdbcURL = databaseConfigProperties.getProperty("jdbcURL");
String jdbcDriver = databaseConfigProperties.getProperty("jdbcDriver");
/**
* 第二步、注册驱动
*/
try {
Class.forName(jdbcDriver);
} catch (ClassNotFoundException e) {
log.error("没有找到数据库的驱动!", e);
return ;
}
/**
* 第三步、获取数据库的连接
*/
Connection connection = null;
try {
connection = DriverManager.getConnection(jdbcURL, username, password);
} catch (SQLException e) {
log.error("获取 Java 程序与数据库服务端程序的连接对象 - 失败!", e);
return ;
}
/**
* 第四步、编写(与业务密切相关的)SQL,具体到这里是插入数据的 SQL。
*/
String functionSQL = "{ call `数据库名`.`queryChinaRegion`( ? ) }";
/**
* 第五步、创建 SQL 的【可调用的声明】对象,用于对 SQL 语句做准备工作。
*/
CallableStatement callableStatement = null;
try {
callableStatement = connection.prepareCall(functionSQL);
} catch (SQLException e) {
log.error("创建 SQL【可调用的声明】对象 - 失败!", e);
return;
}
/**
* 第六步:为参数值填充参数据。
*/
int id = 1;
id = 2;
id = 3;
id = 38;
try {
callableStatement.setInt(1, id);
} catch (SQLException e) {
log.error("为参数值填充数据 - 失败!", e);
return;
}
/**
* 第七步、执行 SQL 更新操作并获取受影响的行数,具体到此处为执行向数据表中添加数据操作并获取添加成功的行数。
*/
try {
callableStatement.execute();
} catch (SQLException e) {
log.error("执行 SQL 更新(具体到这里是向数据表中添加数据) - 失败!", e);
return;
}
/**
* 第八步、获取结果
*/
ResultSet resultSet = null;
try {
resultSet = callableStatement.getResultSet();
} catch (SQLException e) {
throw new RuntimeException(e);
}
/**
* 第九步、解析结果;具体到此处是解析查询到的结果集。
*/
if (null != resultSet) {
try {
while (resultSet.next()) {
int id_ = resultSet.getInt(1);
int parentId = resultSet.getInt("parentId");
byte type = resultSet.getByte("type");
String code = resultSet.getString("code");
String name = resultSet.getString("name");
log.info("ID = {}, \t父 ID = {}, \t类别 = {}, \t编号:{}, \t名称:{}"
, id_, parentId, type, code, name);
}
} catch (Exception e) {
log.error("迭代结果集出错了!", e);
}
}
/**
* 第十步、关闭 SQL 的【可调用的声明】对象。
*/
try {
callableStatement.close();
} catch (SQLException e) {
log.error("关闭 SQL【可调用的声明】对象 - 失败!", e);
return;
}
/**
* 第十一步、断开与数据库的连接。
*/
try {
connection.close();
} catch (SQLException e) {
log.error("关闭 Java 程序与数据库服务端程序的连接 - 失败!", e);
}
}
/**
* 调用自定义的【加法】函数
*
* <note>
* USE `数据库名`;
* SELECT DATABASE();
* DROP PROCEDURE IF EXISTS `add`;
* CREATE DEFINER=`用户名`@`%` PROCEDURE `add`(number1 INT, number2 INT, OUT result INT) BEGIN SET result = number1 + number2 ; END;
* SELECT `SPECIFIC_NAME` FROM `INFORMATION_SCHEMA`.`ROUTINES` WHERE `ROUTINE_SCHEMA` = '数据库名' AND ROUTINE_TYPE = 'PROCEDURE';
* </note>
*/
@Test
public void test_call_function_add () {
/**
* 第一步、获取数据库的配置
*/
InputStream databaseConfigInputStream = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties") ; // 从【类路径】中获取配置文件
Properties databaseConfigProperties = new Properties();
try {
databaseConfigProperties.load(databaseConfigInputStream); // 加载【数据库】配置文件
} catch (IOException e) {
log.error("加载【数据库配置文件】失败!", e);
return;
}
String username = databaseConfigProperties.getProperty("username");
String password = databaseConfigProperties.getProperty("password");
String jdbcURL = databaseConfigProperties.getProperty("jdbcURL");
String jdbcDriver = databaseConfigProperties.getProperty("jdbcDriver");
/**
* 第二步、注册驱动
*/
try {
Class.forName(jdbcDriver);
} catch (ClassNotFoundException e) {
log.error("没有找到数据库的驱动!", e);
return ;
}
/**
* 第三步、获取数据库的连接
*/
Connection connection = null;
try {
connection = DriverManager.getConnection(jdbcURL, username, password);
} catch (SQLException e) {
log.error("获取 Java 程序与数据库服务端程序的连接对象 - 失败!", e);
return ;
}
/**
* 第四步、编写(与业务密切相关的)SQL,具体到这里是调用【加法】自定义函数(常被称为存储过程)的 SQL。
*/
String functionSQL = "{ call `数据库名`.`add`( ?, ?, ? ) }";
/**
* 第五步、创建 SQL 的【可调用的声明】对象,用于对 SQL 语句做准备工作。
*/
CallableStatement callableStatement = null;
try {
callableStatement = connection.prepareCall(functionSQL);
} catch (SQLException e) {
log.error("创建 SQL【可调用的声明】对象 - 失败!", e);
return;
}
/**
* 第六步:为参数值填充参数据。
*/
int number1 = 2;
int number2 = 3;
try {
callableStatement.setInt(1, number1);
callableStatement.setInt(2, number2);
callableStatement.registerOutParameter(3, Types.INTEGER);
} catch (SQLException e) {
log.error("为参数值填充数据 - 失败!", e);
return;
}
/**
* 第七步、执行 SQL 更新操作并获取受影响的行数,具体到此处为执行向数据表中添加数据操作并获取添加成功的行数。
*/
try {
callableStatement.execute();
} catch (SQLException e) {
log.error("执行 SQL 更新(具体到这里是向数据表中添加数据) - 失败!", e);
return;
}
/**
* 第八步、获取结果
*/
int sum = 0;
try {
sum = callableStatement.getInt(3);
} catch (SQLException e) {
log.error("获取整型结果 - 失败!", e);
}
/**
* 第九步、解析结果;具体到此处是解析查询到的结果集。
*/
log.info("和 = {}", sum);
/**
* 第十步、关闭 SQL 的【可调用的声明】对象。
*/
try {
callableStatement.close();
} catch (SQLException e) {
log.error("关闭 SQL【可调用的声明】对象 - 失败!", e);
return;
}
/**
* 第十一步、断开与数据库的连接。
*/
try {
connection.close();
} catch (SQLException e) {
log.error("关闭 Java 程序与数据库服务端程序的连接 - 失败!", e);
}
}
/**
* 调用自定义的【减法】函数
*
* <note>
* SHOW PROCEDURE STATUS WHERE db = '数据库名' AND NAME = 'subtract';
* CREATE PROCEDURE `数据库名`.`subtract`( IN minuend FLOAT, IN subtrahend FLOAT, OUT difference FLOAT ) BEGIN SET difference = minuend - subtrahend ; END;
* SELECT `SPECIFIC_NAME` FROM `INFORMATION_SCHEMA`.`ROUTINES` WHERE `ROUTINE_SCHEMA` = '数据库名' AND ROUTINE_TYPE = 'PROCEDURE';
* SHOW CREATE PROCEDURE `数据库名`.`subtract`;
* </note>
*/
@Test
public void test_call_function_subtract () {
/**
* 第一步、获取数据库的配置
*/
InputStream databaseConfigInputStream = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties") ; // 从【类路径】中获取配置文件
Properties databaseConfigProperties = new Properties();
try {
databaseConfigProperties.load(databaseConfigInputStream); // 加载【数据库】配置文件
} catch (IOException e) {
log.error("加载【数据库配置文件】失败!", e);
return;
}
String username = databaseConfigProperties.getProperty("username");
String password = databaseConfigProperties.getProperty("password");
String jdbcURL = databaseConfigProperties.getProperty("jdbcURL");
String jdbcDriver = databaseConfigProperties.getProperty("jdbcDriver");
/**
* 第二步、注册驱动
*/
try {
Class.forName(jdbcDriver);
} catch (ClassNotFoundException e) {
log.error("没有找到数据库的驱动!", e);
return ;
}
/**
* 第三步、获取数据库的连接
*/
Connection connection = null;
try {
connection = DriverManager.getConnection(jdbcURL, username, password);
} catch (SQLException e) {
log.error("获取 Java 程序与数据库服务端程序的连接对象 - 失败!", e);
return ;
}
/**
* 第四步、编写(与业务密切相关的)SQL,具体到这里是调用【减法】自定义函数(常被称为存储过程)的 SQL。
*/
String functionSQL = "{ call `数据库名`.`subtract`( ?, ?, ? ) }";
/**
* 第五步、创建 SQL 的【可调用的声明】对象,用于对 SQL 语句做准备工作。
*/
CallableStatement callableStatement = null;
try {
callableStatement = connection.prepareCall(functionSQL);
} catch (SQLException e) {
log.error("创建 SQL【可调用的声明】对象 - 失败!", e);
return;
}
/**
* 第六步:为参数值填充参数据。
*/
float minuend = 2.3f;
float subtrahend = 3.5f;
try {
callableStatement.setFloat(1, minuend);
callableStatement.setFloat(2, subtrahend);
callableStatement.registerOutParameter(3, Types.FLOAT);
} catch (SQLException e) {
log.error("为参数值填充数据 - 失败!", e);
return;
}
/**
* 第七步、执行 SQL 更新操作并获取受影响的行数,具体到此处为执行向数据表中添加数据操作并获取添加成功的行数。
*/
try {
callableStatement.execute();
} catch (SQLException e) {
log.error("执行 SQL 更新(具体到这里是向数据表中添加数据) - 失败!", e);
return;
}
/**
* 第八步、获取结果
*/
float difference = 0;
try {
difference = callableStatement.getFloat(3);
} catch (SQLException e) {
log.error("获取整型结果 - 失败!", e);
}
/**
* 第九步、解析结果;具体到此处是解析查询到的结果集。
*/
log.info("差 = {}", difference);
/**
* 第十步、关闭 SQL 的【可调用的声明】对象。
*/
try {
callableStatement.close();
} catch (SQLException e) {
log.error("关闭 SQL【可调用的声明】对象 - 失败!", e);
return;
}
/**
* 第十一步、断开与数据库的连接。
*/
try {
connection.close();
} catch (SQLException e) {
log.error("关闭 Java 程序与数据库服务端程序的连接 - 失败!", e);
}
}
/**
* 调用自定义的【乘法】函数
*
* <note>
* SHOW PROCEDURE STATUS WHERE db = '数据库名' AND NAME = 'multiply';
*
* CREATE PROCEDURE `数据库名`.`multiply`( IN multiplicand DOUBLE, IN multiplier DOUBLE, OUT product DOUBLE) BEGIN SET product = multiplicand * multiplier ; END;
*
* SELECT `SPECIFIC_NAME` FROM `INFORMATION_SCHEMA`.`ROUTINES` WHERE `ROUTINE_SCHEMA` = '数据库名' AND ROUTINE_TYPE = 'PROCEDURE';
* </note>
*/
@Test
public void test_call_function_multiply () {
/**
* 第一步、获取数据库的配置
*/
InputStream databaseConfigInputStream = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties") ; // 从【类路径】中获取配置文件
Properties databaseConfigProperties = new Properties();
try {
databaseConfigProperties.load(databaseConfigInputStream); // 加载【数据库】配置文件
} catch (IOException e) {
log.error("加载【数据库配置文件】失败!", e);
return;
}
String username = databaseConfigProperties.getProperty("username");
String password = databaseConfigProperties.getProperty("password");
String jdbcURL = databaseConfigProperties.getProperty("jdbcURL");
String jdbcDriver = databaseConfigProperties.getProperty("jdbcDriver");
/**
* 第二步、注册驱动
*/
try {
Class.forName(jdbcDriver);
} catch (ClassNotFoundException e) {
log.error("没有找到数据库的驱动!", e);
return ;
}
/**
* 第三步、获取数据库的连接
*/
Connection connection = null;
try {
connection = DriverManager.getConnection(jdbcURL, username, password);
} catch (SQLException e) {
log.error("获取 Java 程序与数据库服务端程序的连接对象 - 失败!", e);
return ;
}
/**
* 第四步、编写(与业务密切相关的)SQL,具体到这里是调用【乘法】自定义函数(常被称为存储过程)的 SQL。
*/
String functionSQL = "{ call `数据库名`.`multiply`( ?, ?, ? ) }";
/**
* 第五步、创建 SQL 的【可调用的声明】对象,用于对 SQL 语句做准备工作。
*/
CallableStatement callableStatement = null;
try {
callableStatement = connection.prepareCall(functionSQL);
} catch (SQLException e) {
log.error("创建 SQL【可调用的声明】对象 - 失败!", e);
return;
}
/**
* 第六步:为参数值填充参数据。
*/
double multiplicand = 2.3f;
double multiplier = 3.5f;
try {
callableStatement.setDouble(1, multiplicand);
callableStatement.setDouble(2, multiplier);
callableStatement.registerOutParameter(3, Types.DOUBLE);
} catch (SQLException e) {
log.error("为参数值填充数据 - 失败!", e);
return;
}
/**
* 第七步、执行 SQL 更新操作并获取受影响的行数,具体到此处为执行向数据表中添加数据操作并获取添加成功的行数。
*/
try {
callableStatement.execute();
} catch (SQLException e) {
log.error("执行 SQL 更新(具体到这里是向数据表中添加数据) - 失败!", e);
return;
}
/**
* 第八步、获取结果
*/
double product = 0;
try {
product = callableStatement.getDouble(3);
} catch (SQLException e) {
log.error("获取整型结果 - 失败!", e);
}
/**
* 第九步、解析结果;具体到此处是解析查询到的结果集。
*/
log.info("积 = {}", product);
/**
* 第十步、关闭 SQL 的【可调用的声明】对象。
*/
try {
callableStatement.close();
} catch (SQLException e) {
log.error("关闭 SQL【可调用的声明】对象 - 失败!", e);
return;
}
/**
* 第十一步、断开与数据库的连接。
*/
try {
connection.close();
} catch (SQLException e) {
log.error("关闭 Java 程序与数据库服务端程序的连接 - 失败!", e);
}
}
/**
* 调用自定义的【除法】函数
*
* <note>
* CREATE PROCEDURE `数据库名`.`divide`( IN dividend BIGINT, IN divisor BIGINT, OUT quotient BIGINT) BEGIN SET quotient = dividend / divisor ; END;
*
* SELECT `SPECIFIC_NAME` FROM `INFORMATION_SCHEMA`.`ROUTINES` WHERE `ROUTINE_SCHEMA` = '数据库名' AND ROUTINE_TYPE = 'PROCEDURE';
* </note>
*/
@Test
public void test_call_function_divide () {
/**
* 第一步、获取数据库的配置
*/
InputStream databaseConfigInputStream = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties") ; // 从【类路径】中获取配置文件
Properties databaseConfigProperties = new Properties();
try {
databaseConfigProperties.load(databaseConfigInputStream); // 加载【数据库】配置文件
} catch (IOException e) {
log.error("加载【数据库配置文件】失败!", e);
return;
}
String username = databaseConfigProperties.getProperty("username");
String password = databaseConfigProperties.getProperty("password");
String jdbcURL = databaseConfigProperties.getProperty("jdbcURL");
String jdbcDriver = databaseConfigProperties.getProperty("jdbcDriver");
/**
* 第二步、注册驱动
*/
try {
Class.forName(jdbcDriver);
} catch (ClassNotFoundException e) {
log.error("没有找到数据库的驱动!", e);
return ;
}
/**
* 第三步、获取数据库的连接
*/
Connection connection = null;
try {
connection = DriverManager.getConnection(jdbcURL, username, password);
} catch (SQLException e) {
log.error("获取 Java 程序与数据库服务端程序的连接对象 - 失败!", e);
return ;
}
/**
* 第四步、编写(与业务密切相关的)SQL,具体到这里是调用【除法】自定义函数(常被称为存储过程)的 SQL。
*/
String functionSQL = "{ call `数据库名`.`divide`( ?, ?, ? ) }";
/**
* 第五步、创建 SQL 的【可调用的声明】对象,用于对 SQL 语句做准备工作。
*/
CallableStatement callableStatement = null;
try {
callableStatement = connection.prepareCall(functionSQL);
} catch (SQLException e) {
log.error("创建 SQL【可调用的声明】对象 - 失败!", e);
return;
}
/**
* 第六步:为参数值填充参数据。
*/
long dividend = 6;
long divisor = 3;
try {
callableStatement.setLong(1, dividend);
callableStatement.setLong(2, divisor);
callableStatement.registerOutParameter(3, Types.BIGINT);
} catch (SQLException e) {
log.error("为参数值填充数据 - 失败!", e);
return;
}
/**
* 第七步、执行 SQL 更新操作并获取受影响的行数,具体到此处为执行向数据表中添加数据操作并获取添加成功的行数。
*/
try {
callableStatement.execute();
} catch (SQLException e) {
log.error("执行 SQL 更新(具体到这里是向数据表中添加数据) - 失败!", e);
return;
}
/**
* 第八步、获取结果
*/
long quotient = 0;
try {
quotient = callableStatement.getLong(3);
} catch (SQLException e) {
log.error("获取整型结果 - 失败!", e);
}
/**
* 第九步、解析结果;具体到此处是解析查询到的结果集。
*/
log.info("商 = {}", quotient);
/**
* 第十步、关闭 SQL 的【可调用的声明】对象。
*/
try {
callableStatement.close();
} catch (SQLException e) {
log.error("关闭 SQL【可调用的声明】对象 - 失败!", e);
return;
}
/**
* 第十一步、断开与数据库的连接。
*/
try {
connection.close();
} catch (SQLException e) {
log.error("关闭 Java 程序与数据库服务端程序的连接 - 失败!", e);
}
}
/**
* 调用自定义的【除法】函数
*
* <note>
* SHOW PROCEDURE STATUS WHERE db = '数据库名' AND NAME = 'mod';
*
* DELIMITER ;
*
* CREATE PROCEDURE `数据库名`.`mod`( IN n1 TINYINT, IN n2 TINYINT, OUT n3 TINYINT) BEGIN SET n3 = n1 % n2 ; END;
*
* DELIMITER ;
*
* SELECT `SPECIFIC_NAME` FROM `INFORMATION_SCHEMA`.`ROUTINES` WHERE `ROUTINE_SCHEMA` = '数据库名' AND ROUTINE_TYPE = 'PROCEDURE';
*
* SHOW CREATE PROCEDURE `数据库名`.`mod`;
* </note>
*/
@Test
public void test_call_function_mod () {
/**
* 第一步、获取数据库的配置
*/
InputStream databaseConfigInputStream = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties") ; // 从【类路径】中获取配置文件
Properties databaseConfigProperties = new Properties();
try {
databaseConfigProperties.load(databaseConfigInputStream); // 加载【数据库】配置文件
} catch (IOException e) {
log.error("加载【数据库配置文件】失败!", e);
return;
}
String username = databaseConfigProperties.getProperty("username");
String password = databaseConfigProperties.getProperty("password");
String jdbcURL = databaseConfigProperties.getProperty("jdbcURL");
String jdbcDriver = databaseConfigProperties.getProperty("jdbcDriver");
/**
* 第二步、注册驱动
*/
try {
Class.forName(jdbcDriver);
} catch (ClassNotFoundException e) {
log.error("没有找到数据库的驱动!", e);
return ;
}
/**
* 第三步、获取数据库的连接
*/
Connection connection = null;
try {
connection = DriverManager.getConnection(jdbcURL, username, password);
} catch (SQLException e) {
log.error("获取 Java 程序与数据库服务端程序的连接对象 - 失败!", e);
return ;
}
/**
* 第四步、编写(与业务密切相关的)SQL,具体到这里是调用【求余】自定义函数(常被称为存储过程)的 SQL。
*/
String functionSQL = "{ call `数据库名`.`mod`( ?, ?, ? ) }";
/**
* 第五步、创建 SQL 的【可调用的声明】对象,用于对 SQL 语句做准备工作。
*/
CallableStatement callableStatement = null;
try {
callableStatement = connection.prepareCall(functionSQL);
} catch (SQLException e) {
log.error("创建 SQL【可调用的声明】对象 - 失败!", e);
return;
}
/**
* 第六步:为参数值填充参数据。
*/
byte n1 = 99;
byte n2 = 10;
try {
callableStatement.setByte(1, n1);
callableStatement.setByte(2, n2);
callableStatement.registerOutParameter(3, Types.TINYINT);
} catch (SQLException e) {
log.error("为参数值填充数据 - 失败!", e);
return;
}
/**
* 第七步、执行 SQL 更新操作并获取受影响的行数,具体到此处为执行向数据表中添加数据操作并获取添加成功的行数。
*/
try {
callableStatement.execute();
} catch (SQLException e) {
log.error("执行 SQL 更新(具体到这里是向数据表中添加数据) - 失败!", e);
return;
}
/**
* 第八步、获取结果
*/
byte n3 = 0;
try {
n3 = callableStatement.getByte(3);
} catch (SQLException e) {
log.error("获取整型结果 - 失败!", e);
}
/**
* 第九步、解析结果;具体到此处是解析查询到的结果集。
*/
log.info("余 = {}", n3);
/**
* 第十步、关闭 SQL 的【可调用的声明】对象。
*/
try {
callableStatement.close();
} catch (SQLException e) {
log.error("关闭 SQL【可调用的声明】对象 - 失败!", e);
return;
}
/**
* 第十一步、断开与数据库的连接。
*/
try {
connection.close();
} catch (SQLException e) {
log.error("关闭 Java 程序与数据库服务端程序的连接 - 失败!", e);
}
}
}