当前位置: 首页 > 技术教程

Java如何调用数据库数据:连接、查询与存储过程调用

  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 注入攻击,并提高性能。

Java4.png

  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 存储过程。掌握这些技术,可以帮助开发者构建高效、可靠的数据库应用。在实际开发中,需要根据具体需求选择合适的连接方式、查询方式和存储过程调用方式,并遵循最佳实践,以提高应用的性能和安全性。


猜你喜欢