第十五周总结

Java 学习第十五周总结
一、学习概述
本周学习聚焦数据库与 JDBC 高级技术,深入掌握 JDBC 事务管理、批处理操作、存储过程调用及连接池技术,同时学习数据库设计规范、索引优化、事务特性与隔离级别等核心知识。通过理论与实践结合,提升数据库设计与操作能力,为开发高性能、可靠的数据库应用奠定基础。
二、JDBC 高级技术

  1. 事务管理
    事务特性与操作

public void transferMoney(Connection conn, int fromId, int toId, double amount) throws SQLException {
try {
// 禁用自动提交,开启事务
conn.setAutoCommit(false);

    // 创建Statement 
    Statement stmt = conn.createStatement(); 
     
    // 扣除转出账户金额 
    stmt.executeUpdate("UPDATE accounts SET balance = balance - " + amount + " WHERE id = " + fromId); 
    // 增加转入账户金额 
    stmt.executeUpdate("UPDATE accounts SET balance = balance + " + amount + " WHERE id = " + toId); 
     
    // 提交事务 
    conn.commit(); 
    System.out.println("转账成功"); 
} catch (SQLException e) { 
    // 回滚事务 
    conn.rollback(); 
    System.out.println("转账失败,事务回滚"); 
    throw e; 
} finally { 
    // 恢复自动提交模式 
    conn.setAutoCommit(true); 
} 

}
事务隔离级别设置

public void setTransactionIsolation(Connection conn) throws SQLException {
// 设置隔离级别为可重复读
conn.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
System.out.println("当前隔离级别: " + conn.getTransactionIsolation());
}
2. 批处理操作
批量插入示例

public void batchInsert(Connection conn, List users) throws SQLException {
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[] results = pstmt.executeBatch(); 
    conn.commit(); 
     
    System.out.println("批量插入成功,影响行数: " + Arrays.toString(results)); 
} catch (SQLException e) { 
    conn.rollback(); 
    System.out.println("批量插入失败,事务回滚"); 
    throw e; 
} finally { 
    conn.setAutoCommit(true); 
    pstmt.close(); 
} 

}
3. 存储过程调用
存储过程调用示例

-- 数据库中创建存储过程
DELIMITER //
CREATE PROCEDURE AddUser(IN name VARCHAR(50), IN age INT)
BEGIN
INSERT INTO users (name, age) VALUES (name, age);
END //
DELIMITER ;

public void callStoredProcedure(Connection conn, String name, int age) throws SQLException {
String sql = "{CALL AddUser(?, ?)}";
CallableStatement cstmt = conn.prepareCall(sql);

try { 
    cstmt.setString(1, name); 
    cstmt.setInt(2, age); 
    cstmt.execute(); 
     
    System.out.println("调用存储过程成功,用户 " + name + " 已添加"); 
} finally { 
    cstmt.close(); 
} 

}
4. 连接池管理
HikariCP 连接池示例

public class HikariCPDemo {
private HikariDataSource dataSource;

public HikariCPDemo() { 
    HikariConfig config = new HikariConfig(); 
    config.setJdbcUrl("jdbc:mysql://localhost:3306/testdb"); 
    config.setUsername("root"); 
    config.setPassword("password"); 
    config.setMaximumPoolSize(10); 
    config.setMinimumIdle(5); 
    config.setConnectionTimeout(30000); 
    config.setIdleTimeout(600000); 
     
    dataSource = new HikariDataSource(config); 
} 
 
public void queryData() throws SQLException { 
    try (Connection conn = dataSource.getConnection(); 
         Statement stmt = conn.createStatement(); 
         ResultSet rs = stmt.executeQuery("SELECT * FROM users LIMIT 5")) { 
         
        while (rs.next()) { 
            System.out.println("ID: " + rs.getInt("id") + ", 姓名: " + rs.getString("name")); 
        } 
    } 
} 

}
三、数据库设计与优化

  1. 数据库设计规范
    三范式设计示例
  2. 第一范式 (1NF):确保列的原子性,如学生表中姓名不可再分
  3. 第二范式 (2NF):选课表 (enrollments) 依赖于学生 ID 和课程 ID 组合主键
  4. 第三范式 (3NF):学生表不直接存储学院地址,通过学院 ID 关联学院表

-- 学生表(students)
CREATE TABLE students (
student_id INT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
age INT,
class_id INT,
FOREIGN KEY (class_id) REFERENCES classes(class_id)
);
-- 班级表(classes)
CREATE TABLE classes (
class_id INT PRIMARY KEY,
class_name VARCHAR(50) NOT NULL
);
-- 选课表(enrollments)
CREATE TABLE enrollments (
enrollment_id INT PRIMARY KEY,
student_id INT,
course_id INT,
grade FLOAT,
FOREIGN KEY (student_id) REFERENCES students(student_id),
FOREIGN KEY (course_id) REFERENCES courses(course_id)
);
2. 索引设计与优化
索引类型与使用

-- 单列索引
CREATE INDEX idx_name ON students(name);
-- 组合索引
CREATE INDEX idx_student_course ON enrollments(student_id, course_id);
-- 唯一索引
CREATE UNIQUE INDEX idx_email ON students(email);
-- 全文索引(MySQL)
CREATE FULLTEXT INDEX idx_content ON articles(content);
索引优化建议

  1. 为 WHERE 条件、JOIN 条件列创建索引
  2. 避免对低选择性列 (如性别) 创建索引
  3. 定期重建索引以优化碎片
  4. 组合索引遵循 "最左前缀" 原则
  5. 数据库优化策略
    查询优化示例

-- 优化前:使用SELECT *
SELECT * FROM users WHERE age > 30;
-- 优化后:只查询需要的列
SELECT id, name, email FROM users WHERE age > 30;
-- 优化前:子查询
SELECT * FROM users WHERE id IN (SELECT user_id FROM orders);
-- 优化后:连接查询
SELECT u.* FROM users u INNER JOIN orders o ON u.id = o.user_id;
-- 分页查询优化
SELECT * FROM users ORDER BY id LIMIT 10 OFFSET 100;
结构优化策略
5. 表分区:按日期分区大表
6. 垂直拆分:将大字段独立成表
7. 归档旧数据:将历史数据迁移到归档表
四、事务与并发控制

  1. 事务特性 (ACID)
    事务特性示例
  2. 原子性:转账操作要么全成功,要么全回滚
  3. 一致性:库存更新后数量仍为非负数
  4. 隔离性:多事务并发执行互不干扰
  5. 持久性:事务提交后数据永久保存
  6. 事务隔离级别
    隔离级别对比

隔离级别 脏读 不可重复读 幻读 性能
READ UNCOMMITTED 可能 可能 可能 最高
READ COMMITTED 不可能 可能 可能 高
REPEATABLE READ 不可能 不可能 可能 中
SERIALIZABLE 不可能 不可能 不可能 最低
隔离级别设置

-- 设置会话隔离级别为可重复读
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
3. 并发问题与解决方案
并发问题处理
12. 脏读:设置隔离级别为 READ COMMITTED 或更高
13. 不可重复读:设置隔离级别为 REPEATABLE READ 或更高
14. 幻读:设置隔离级别为 SERIALIZABLE
五、本周学习总结与反思

  1. 学习成果
  2. 掌握 JDBC 事务管理,能实现复杂事务场景
  3. 熟练使用批处理操作提升数据库操作效率
  4. 掌握存储过程调用与连接池配置
  5. 理解数据库设计范式,能设计规范的数据库结构
  6. 掌握索引设计与查询优化策略
  7. 理解事务 ACID 特性与隔离级别,能处理并发问题
  8. 存在问题
  9. 复杂事务场景下的隔离级别选择经验不足
  10. 大型数据库优化中的表分区与分库分表实践较少
  11. 高并发场景下的事务性能调优缺乏实战经验
  12. 改进方向
  13. 通过实际项目练习不同隔离级别的应用场景
  14. 学习分库分表技术,实践大型数据库架构
  15. 研究高并发事务优化策略,如乐观锁与悲观锁应用
  16. 下周计划
  17. 学习 MyBatis 框架,掌握 ORM 映射技术
  18. 研究 Spring 事务管理,整合 JDBC 与 Spring
  19. 实践数据库分库分表,实现水平拆分
  20. 学习数据库监控与性能调优工具使用
posted @ 2025-06-15 21:19  执笔诉相思  阅读(12)  评论(0)    收藏  举报