Java 作为一种广泛应用的编程语言,在企业级应用开发中扮演着重要角色。而数据库作为数据存储和管理的核心,与 Java 应用的交互至关重要。小编将详细介绍 Java 如何连接数据库、查询数据,以及如何调用 MySQL 存储过程,帮助开发者构建高效、可靠的数据库应用。
一、Java 连接数据库:JDBC 的力量
Java 通过 JDBC (Java Database Connectivity) API 来连接和操作各种数据库。JDBC 提供了一组接口和类,允许 Java 程序与数据库进行通信,执行 SQL 语句,并处理结果集。
1. JDBC 连接数据库的步骤:
加载数据库驱动: 首先,需要加载对应数据库的 JDBC 驱动程序。例如,连接 MySQL 数据库,需要加载 MySQL Connector/J 驱动。可以使用 Class.forName() 方法加载驱动。
try {
Class.forName("com.mysql.cj.jdbc.Driver"); // MySQL 8.0+
// Class.forName("com.mysql.jdbc.Driver"); // MySQL 5.x
} catch (ClassNotFoundException e) {
System.err.println("MySQL JDBC Driver not found!");
e.printStackTrace();
return; // 或抛出异常
}
建立数据库连接: 使用 DriverManager.getConnection() 方法建立与数据库的连接。需要提供数据库 URL、用户名和密码。
String url = "jdbc:mysql://localhost:3306/mydatabase?serverTimezone=UTC"; // 数据库 URL
String user = "myuser"; // 数据库用户名
String password = "mypassword"; // 数据库密码
Connection connection = null;
try {
connection = DriverManager.getConnection(url, user, password);
System.out.println("Connected to database!");
} catch (SQLException e) {
System.err.println("Failed to connect to database!");
e.printStackTrace();
return; // 或抛出异常
}
创建 Statement 或 PreparedStatement 对象: Statement 用于执行静态 SQL 语句,而 PreparedStatement 用于执行预编译的 SQL 语句,可以防止 SQL 注入攻击,并提高性能。
Statement statement = null;
PreparedStatement preparedStatement = null;
try {
statement = connection.createStatement();
String sql = "SELECT * FROM users";
ResultSet resultSet = statement.executeQuery(sql);
// 处理结果集
while (resultSet.next()) {
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
String email = resultSet.getString("email");
System.out.println("ID: " + id + ", Name: " + name + ", Email: " + email);
}
// 使用 PreparedStatement
String sqlPrepared = "SELECT * FROM users WHERE id = ?";
preparedStatement = connection.prepareStatement(sqlPrepared);
preparedStatement.setInt(1, 1); // 设置参数
ResultSet resultSetPrepared = preparedStatement.executeQuery();
// 处理结果集
while (resultSetPrepared.next()) {
int id = resultSetPrepared.getInt("id");
String name = resultSetPrepared.getString("name");
String email = resultSetPrepared.getString("email");
System.out.println("ID: " + id + ", Name: " + name + ", Email: " + email);
}
} catch (SQLException e) {
System.err.println("Failed to execute SQL query!");
e.printStackTrace();
} finally {
// 关闭资源
try {
if (statement != null) statement.close();
if (preparedStatement != null) preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
执行 SQL 语句: 使用 executeQuery() 方法执行 SELECT 语句,返回 ResultSet 对象。使用 executeUpdate() 方法执行 INSERT、UPDATE、DELETE 语句,返回受影响的行数。
处理结果集 (ResultSet): ResultSet 对象包含查询结果。可以使用 next() 方法遍历结果集,使用 getInt()、getString() 等方法获取每一列的值。
关闭连接和资源: 在使用完数据库连接后,务必关闭连接和相关的资源,如 Statement、PreparedStatement 和 ResultSet 对象,以释放资源并避免连接泄漏。
finally {
try {
if (resultSet != null) resultSet.close();
if (statement != null) statement.close();
if (preparedStatement != null) preparedStatement.close();
if (connection != null) connection.close();
System.out.println("Connection closed.");
} catch (SQLException e) {
e.printStackTrace();
}
}
2. 数据库连接池:提高性能
频繁地建立和关闭数据库连接会消耗大量资源。为了提高性能,可以使用数据库连接池。连接池维护一组数据库连接,当需要连接时,从连接池中获取一个连接,使用完后归还给连接池,避免了重复创建和销毁连接的开销。
常用的 Java 连接池有:
HikariCP: 高性能、轻量级的连接池。
Apache Commons DBCP: 稳定、成熟的连接池。
C3P0: 功能丰富的连接池。
二、Java 调用 MySQL 存储过程
存储过程是在数据库服务器上预先编译好的 SQL 语句集合,可以接受参数,执行复杂的业务逻辑,并返回结果。调用存储过程可以提高性能,减少网络传输,并增强安全性。
1. 创建 MySQL 存储过程:
DELIMITER //
CREATE PROCEDURE GetUserById(IN userId INT, OUT userName VARCHAR(255), OUT userEmail VARCHAR(255))
BEGIN
SELECT name, email INTO userName, userEmail FROM users WHERE id = userId;
END //
DELIMITER ;
这个存储过程 GetUserById 接受一个输入参数 userId,并返回两个输出参数 userName 和 userEmail。
2. Java 调用存储过程的步骤:
创建 CallableStatement 对象: 使用 Connection.prepareCall() 方法创建 CallableStatement 对象,指定存储过程的名称。
CallableStatement callableStatement = null;
try {
String sql = "{call GetUserById(?, ?, ?)}";
callableStatement = connection.prepareCall(sql);
} catch (SQLException e) {
System.err.println("Failed to create CallableStatement!");
e.printStackTrace();
return; // 或抛出异常
}
注册输出参数: 使用 registerOutParameter() 方法注册存储过程的输出参数,指定参数的位置和数据类型。
try {
callableStatement.setInt(1, 1); // 设置输入参数 userId
callableStatement.registerOutParameter(2, Types.VARCHAR); // 注册输出参数 userName
callableStatement.registerOutParameter(3, Types.VARCHAR); // 注册输出参数 userEmail
} catch (SQLException e) {
System.err.println("Failed to register output parameters!");
e.printStackTrace();
return; // 或抛出异常
}
执行存储过程: 使用 execute() 方法执行存储过程。
try {
callableStatement.execute();
} catch (SQLException e) {
System.err.println("Failed to execute stored procedure!");
e.printStackTrace();
return; // 或抛出异常
}
获取输出参数: 使用 getXXX() 方法获取存储过程的输出参数,例如 getString() 获取字符串类型的参数。
try {
String userName = callableStatement.getString(2); // 获取 userName
String userEmail = callableStatement.getString(3); // 获取 userEmail
System.out.println("User Name: " + userName + ", User Email: " + userEmail);
} catch (SQLException e) {
System.err.println("Failed to get output parameters!");
e.printStackTrace();
} finally {
// 关闭资源
try {
if (callableStatement != null) callableStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
3. 完整示例代码:
import java.sql.*;
public class StoredProcedureExample {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/mydatabase?serverTimezone=UTC";
String user = "myuser";
String password = "mypassword";
Connection connection = null;
CallableStatement callableStatement = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
connection = DriverManager.getConnection(url, user, password);
String sql = "{call GetUserById(?, ?, ?)}";
callableStatement = connection.prepareCall(sql);
callableStatement.setInt(1, 1); // 设置输入参数 userId
callableStatement.registerOutParameter(2, Types.VARCHAR); // 注册输出参数 userName
callableStatement.registerOutParameter(3, Types.VARCHAR); // 注册输出参数 userEmail
callableStatement.execute();
String userName = callableStatement.getString(2); // 获取 userName
String userEmail = callableStatement.getString(3); // 获取 userEmail
System.out.println("User Name: " + userName + ", User Email: " + userEmail);
} catch (ClassNotFoundException e) {
System.err.println("MySQL JDBC Driver not found!");
e.printStackTrace();
} catch (SQLException e) {
System.err.println("Failed to connect or execute stored procedure!");
e.printStackTrace();
} finally {
try {
if (callableStatement != null) callableStatement.close();
if (connection != null) connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
小编详细介绍了 Java 如何连接数据库、查询数据,以及如何调用 MySQL 存储过程。掌握这些技术,可以帮助开发者构建高效、可靠的数据库应用。在实际开发中,需要根据具体需求选择合适的连接方式、查询方式和存储过程调用方式,并遵循最佳实践,以提高应用的性能和安全性。