第十五周总结
Java 学习第十五周总结
一、学习概述
本周学习聚焦数据库与 JDBC 高级技术,深入掌握 JDBC 事务管理、批处理操作、存储过程调用及连接池技术,同时学习数据库设计规范、索引优化、事务特性与隔离级别等核心知识。通过理论与实践结合,提升数据库设计与操作能力,为开发高性能、可靠的数据库应用奠定基础。
二、JDBC 高级技术
- 事务管理
事务特性与操作
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
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"));
}
}
}
}
三、数据库设计与优化
- 数据库设计规范
三范式设计示例 - 第一范式 (1NF):确保列的原子性,如学生表中姓名不可再分
- 第二范式 (2NF):选课表 (enrollments) 依赖于学生 ID 和课程 ID 组合主键
- 第三范式 (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);
索引优化建议
- 为 WHERE 条件、JOIN 条件列创建索引
- 避免对低选择性列 (如性别) 创建索引
- 定期重建索引以优化碎片
- 组合索引遵循 "最左前缀" 原则
- 数据库优化策略
查询优化示例
-- 优化前:使用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. 归档旧数据:将历史数据迁移到归档表
四、事务与并发控制
- 事务特性 (ACID)
事务特性示例 - 原子性:转账操作要么全成功,要么全回滚
- 一致性:库存更新后数量仍为非负数
- 隔离性:多事务并发执行互不干扰
- 持久性:事务提交后数据永久保存
- 事务隔离级别
隔离级别对比
隔离级别 脏读 不可重复读 幻读 性能
READ UNCOMMITTED 可能 可能 可能 最高
READ COMMITTED 不可能 可能 可能 高
REPEATABLE READ 不可能 不可能 可能 中
SERIALIZABLE 不可能 不可能 不可能 最低
隔离级别设置
-- 设置会话隔离级别为可重复读
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
3. 并发问题与解决方案
并发问题处理
12. 脏读:设置隔离级别为 READ COMMITTED 或更高
13. 不可重复读:设置隔离级别为 REPEATABLE READ 或更高
14. 幻读:设置隔离级别为 SERIALIZABLE
五、本周学习总结与反思
- 学习成果
- 掌握 JDBC 事务管理,能实现复杂事务场景
- 熟练使用批处理操作提升数据库操作效率
- 掌握存储过程调用与连接池配置
- 理解数据库设计范式,能设计规范的数据库结构
- 掌握索引设计与查询优化策略
- 理解事务 ACID 特性与隔离级别,能处理并发问题
- 存在问题
- 复杂事务场景下的隔离级别选择经验不足
- 大型数据库优化中的表分区与分库分表实践较少
- 高并发场景下的事务性能调优缺乏实战经验
- 改进方向
- 通过实际项目练习不同隔离级别的应用场景
- 学习分库分表技术,实践大型数据库架构
- 研究高并发事务优化策略,如乐观锁与悲观锁应用
- 下周计划
- 学习 MyBatis 框架,掌握 ORM 映射技术
- 研究 Spring 事务管理,整合 JDBC 与 Spring
- 实践数据库分库分表,实现水平拆分
- 学习数据库监控与性能调优工具使用
浙公网安备 33010602011771号