5 月 28 日数据库学习笔记

一、JDBC 的事务管理
(一)事务管理的重要性
在 JDBC 中,事务管理用于确保数据库操作的完整性和一致性。通过事务,可以将多个数据库操作组合在一起,要么全部成功,要么全部失败,从而避免部分操作成功导致的数据不一致问题。
(二)事务的基本操作
设置事务的自动提交模式
默认情况下,JDBC 的 Connection 对象处于自动提交模式(auto-commit),每个单独的 SQL 语句都会自动提交并作为一个独立的事务执行。
如果要手动管理事务,需要将连接设置为非自动提交模式:
java

conn.setAutoCommit(false);
提交事务
当所有操作都成功完成时,可以调用 commit() 方法提交事务,使事务中的更改永久生效:
java

conn.commit();
回滚事务
如果在事务执行过程中发生异常或错误,可以调用 rollback() 方法回滚事务,撤销事务中的所有更改,恢复到事务开始前的状态:
java

conn.rollback();
恢复自动提交模式
在事务处理完成后,通常需要将连接恢复为自动提交模式,以便后续的单个 SQL 语句可以自动提交:

conn.setAutoCommit(true);
(三)事务管理的示例
以下是一个完整的事务管理示例,展示如何在 JDBC 中使用事务来确保数据的一致性:
java

public void transferMoney(Connection conn, int fromAccountId, int toAccountId, double amount) throws SQLException {
try {
// 禁用自动提交
conn.setAutoCommit(false);

    // 创建 Statement 对象
    Statement stmt = conn.createStatement();

    // 从 fromAccountId 账户中扣除金额
    stmt.executeUpdate("UPDATE accounts SET balance = balance - " + amount + " WHERE account_id = " + fromAccountId);

    // 向 toAccountId 账户中增加金额
    stmt.executeUpdate("UPDATE accounts SET balance = balance + " + amount + " WHERE account_id = " + toAccountId);

    // 提交事务
    conn.commit();

    System.out.println("Money transfer successful.");
} catch (SQLException e) {
    // 回滚事务
    conn.rollback();
    System.out.println("Money transfer failed. Transaction rolled back.");
    throw e;
} finally {
    // 恢复自动提交模式
    conn.setAutoCommit(true);
}

}
二、JDBC 的批处理操作
(一)批处理的概念
批处理(Batch Processing)用于一次性执行多个 SQL 语句,可以显著提高数据库操作的效率,减少网络通信次数和数据库连接的开销。
(二)使用批处理
添加批处理语句
使用 Statement 或 PreparedStatement 的 addBatch() 方法将 SQL 语句添加到批处理中:
java

Statement stmt = conn.createStatement();
stmt.addBatch("INSERT INTO users (name, age) VALUES ('Alice', 25)");
stmt.addBatch("INSERT INTO users (name, age) VALUES ('Bob', 30)");
执行批处理
调用 executeBatch() 方法执行批处理中的所有 SQL 语句,返回一个整型数组,表示每个语句影响的行数:
java

int[] updateCounts = stmt.executeBatch();
for (int count : updateCounts) {
System.out.println("Rows affected: " + count);
}
(三)批处理的示例
以下是一个完整的批处理操作示例,展示如何在 JDBC 中使用批处理来提高数据插入的效率:
java

public void insertUsers(Connection conn, List users) throws SQLException {
// 创建 PreparedStatement 对象
String sql = "INSERT INTO users (name, age) VALUES (?, ?)";
PreparedStatement pstmt = conn.prepareStatement(sql);

try {
    // 禁用自动提交
    conn.setAutoCommit(false);

    // 添加批处理语句
    for (User user : users) {
        pstmt.setString(1, user.getName());
        pstmt.setInt(2, user.getAge());
        pstmt.addBatch();
    }

    // 执行批处理
    int[] updateCounts = pstmt.executeBatch();

    // 提交事务
    conn.commit();

    System.out.println("Batch insert successful. Rows affected: " + Arrays.toString(updateCounts));
} catch (SQLException e) {
    // 回滚事务
    conn.rollback();
    System.out.println("Batch insert failed. Transaction rolled back.");
    throw e;
} finally {
    // 恢复自动提交模式
    conn.setAutoCommit(true);
    pstmt.close();
}

}
三、JDBC 的存储过程调用
(一)存储过程的概念
存储过程(Stored Procedure)是存储在数据库中的一组预编译的 SQL 语句,可以通过 JDBC 调用。存储过程可以提高数据库操作的效率和安全性,同时减少网络通信次数。
(二)调用存储过程
创建存储过程
在数据库中创建存储过程,例如:
sql

DELIMITER //
CREATE PROCEDURE AddUser(IN name VARCHAR(50), IN age INT)
BEGIN
INSERT INTO users (name, age) VALUES (name, age);
END //
DELIMITER ;
调用存储过程
使用 CallableStatement 对象调用存储过程:
java

CallableStatement cstmt = conn.prepareCall("{CALL AddUser(?, ?)}");
cstmt.setString(1, "Alice");
cstmt.setInt(2, 25);
cstmt.execute();
(三)存储过程调用的示例
以下是一个完整的存储过程调用示例,展示如何在 JDBC 中调用存储过程来插入用户数据:
java

public void addUserWithProcedure(Connection conn, String name, int age) throws SQLException {
// 创建 CallableStatement 对象
String sql = "{CALL AddUser(?, ?)}";
CallableStatement cstmt = conn.prepareCall(sql);

try {
    // 设置输入参数
    cstmt.setString(1, name);
    cstmt.setInt(2, age);

    // 执行存储过程
    cstmt.execute();

    System.out.println("User added successfully.");
} finally {
    cstmt.close();
}

}
四、JDBC 的连接池管理
(一)连接池的概念
连接池(Connection Pool)是一种管理数据库连接的技术,用于提高数据库操作的性能和资源利用率。连接池预先创建并维护一定数量的数据库连接,当应用程序需要连接时,直接从连接池中获取,使用完毕后归还到连接池,避免了频繁创建和销毁连接的开销。
(二)常用的连接池实现
HikariCP
HikariCP 是一个高性能的 Java 数据库连接池,以其简单、高效和低延迟而闻名。以下是使用 HikariCP 的示例:
java

HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/mydatabase");
config.setUsername("username");
config.setPassword("password");
config.setMaximumPoolSize(10); // 设置最大连接数
config.setMinimumIdle(5); // 设置最小空闲连接数
HikariDataSource ds = new HikariDataSource(config);

// 获取连接
Connection conn = ds.getConnection();
C3P0
C3P0 是一个开源的 Java 数据库连接池实现,支持自动重连、连接测试等功能。以下是使用 C3P0 的示例:
java

ComboPooledDataSource cpds = new ComboPooledDataSource();
cpds.setJdbcUrl("jdbc:mysql://localhost:3306/mydatabase");
cpds.setUser("username");
cpds.setPassword("password");
cpds.setMinPoolSize(5); // 设置最小连接数
cpds.setMaxPoolSize(20); // 设置最大连接数

// 获取连接
Connection conn = cpds.getConnection();

posted @ 2025-05-28 23:38  头发少的文不识  阅读(36)  评论(0)    收藏  举报