第一部分:SQL基础(SELECT/INSERT/UPDATE)

掌握SQL核心操作,为JDBC操作打下坚实基础

学习目标

理解并掌握SELECT查询、INSERT插入、UPDATE更新操作的基本语法和执行原理

1

SELECT查询

从数据库表中检索数据:

SELECT column1, column2, ...
FROM table_name
WHERE condition;

-- 示例:查询所有员工信息
SELECT * FROM employees;

-- 示例:查询特定部门的员工
SELECT id, name, department
FROM employees
WHERE department = 'IT';
2

INSERT插入

向数据库表中插入新记录:

INSERT INTO table_name (column1, column2, ...)
VALUES (value1, value2, ...);

-- 示例:插入新员工记录
INSERT INTO employees (name, email, department)
VALUES ('张三', 'zhangsan@example.com', 'HR');
3

UPDATE更新

修改数据库表中的现有记录:

UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;

-- 示例:更新员工部门
UPDATE employees
SET department = 'Marketing'
WHERE id = 101;

警告:UPDATE语句必须使用WHERE子句,否则会更新表中所有记录!

4

SQL操作最佳实践

  • 始终使用参数化查询防止SQL注入
  • 在UPDATE/DELETE操作前使用SELECT确认影响范围
  • 对常用查询列创建索引提高性能
  • 使用事务保证多个操作的原子性
  • 避免在WHERE子句中对列进行函数操作

第二部分:JDBC连接数据库(DriverManager)

掌握Java程序与数据库建立连接的核心方法

学习目标

理解JDBC架构,掌握使用DriverManager建立数据库连接的方法

Java应用

数据库

1

JDBC连接步骤

  1. 加载数据库驱动
  2. 使用DriverManager获取Connection对象
  3. 创建Statement或PreparedStatement
  4. 执行SQL查询或更新
  5. 处理结果集(ResultSet)
  6. 关闭所有资源
2

建立连接代码示例

import java.sql.*;

public class JdbcExample {
    public static void main(String[] args) {
        // 1. 数据库连接参数
        String url = "jdbc:mysql://localhost:3306/mydatabase";
        String user = "root";
        String password = "password";
        Connection conn = null;

        try {
            // 2. 加载驱动(JDBC 4.0+后自动加载)
            Class.forName("com.mysql.cj.jdbc.Driver");

            // 3. 建立连接
            conn = DriverManager.getConnection(url, user, password);
            System.out.println("成功连接到数据库!");
        }
        catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }
        finally {
            // 4. 关闭连接
            if (conn != null) {
                try { conn.close(); }
                catch (SQLException e) { e.printStackTrace(); }
            }
        }
    }
}

连接池的重要性

在生产环境中,建议使用连接池(如HikariCP、Apache DBCP)管理数据库连接。连接池可以:

  • 减少频繁创建连接的开销
  • 控制最大连接数防止资源耗尽
  • 提供连接健康检查机制
  • 支持自动重连功能

第三部分:Statement与PreparedStatement

掌握执行SQL语句的两种核心接口及其适用场景

学习目标

理解Statement与PreparedStatement的区别,掌握PreparedStatement防止SQL注入的原理

特性 Statement PreparedStatement
SQL注入防护 ❌ 不安全 ✅ 安全
性能 每次执行都需要编译 预编译,多次执行效率高
参数设置 字符串拼接(易出错) 使用setXxx()方法
适用场景 DDL操作、无参数SQL 带参数的DML操作
二进制数据处理 不直接支持 支持BLOB/CLOB
1

PreparedStatement使用示例

// 使用PreparedStatement安全查询
String sql = "SELECT * FROM users WHERE username = ? AND password = ?";

try (Connection conn = dataSource.getConnection();
        PreparedStatement pstmt = conn.prepareStatement(sql)) {

    // 设置参数(防止SQL注入)
    pstmt.setString(1, username);
    pstmt.setString(2, password);

    // 执行查询
    try (ResultSet rs = pstmt.executeQuery()) {
        if (rs.next()) {
            // 登录成功
        }
    }
}
2

PreparedStatement最佳实践

  • 始终使用try-with-resources确保资源关闭
  • 为每个参数使用正确的setXxx方法(setString, setInt等)
  • 批量操作时使用addBatch()和executeBatch()
  • 重用PreparedStatement对象提高性能
  • 使用setObject()处理不确定类型的数据

常见错误:在循环中创建PreparedStatement,导致大量对象创建,应复用PreparedStatement

第四部分:事务处理(ACID特性)

确保数据库操作的原子性、一致性、隔离性和持久性

学习目标

理解事务的ACID特性,掌握JDBC中事务管理的方法

原子性 (Atomicity)

事务中的所有操作要么全部成功,要么全部失败回滚

一致性 (Consistency)

事务执行前后,数据库必须保持一致状态

隔离性 (Isolation)

多个并发事务之间互相隔离,互不干扰

持久性 (Durability)

事务提交后,对数据库的改变是永久性的

1

JDBC事务管理代码

Connection conn = null;
try {
    conn = dataSource.getConnection();
    // 关闭自动提交,开启事务
    conn.setAutoCommit(false);

    // 执行多个SQL操作
    updateAccount(conn, "A", -100.0);
    updateAccount(conn, "B", 100.0);

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

} catch (SQLException e) {
    if (conn != null) {
        try {
            // 回滚事务
            conn.rollback();
        }
        catch (SQLException ex) {
            ex.printStackTrace();
        }
    }
    e.printStackTrace();
} finally {
    // 关闭连接
    if (conn != null) {
        try { conn.close(); }
        catch (SQLException e) { e.printStackTrace(); }
    }
}
2

事务隔离级别

JDBC支持的事务隔离级别:

  • TRANSACTION_READ_UNCOMMITTED - 读未提交
  • TRANSACTION_READ_COMMITTED - 读已提交(默认)
  • TRANSACTION_REPEATABLE_READ - 可重复读
  • TRANSACTION_SERIALIZABLE - 序列化

设置隔离级别

在事务开始前设置:

conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);

第五部分:DAO设计模式

实现数据访问逻辑与业务逻辑的分离

学习目标

掌握DAO设计模式的核心概念和实现方法

DAO模式结构

  • DAO接口 - 定义数据访问方法
  • DAO实现类 - 具体的数据库操作
  • 实体类 - 映射数据库表结构
  • 业务逻辑层 - 调用DAO进行业务处理

DAO模式优点

  • 分离数据访问逻辑与业务逻辑
  • 提高代码可维护性和可测试性
  • 便于切换数据源(SQL/NoSQL)
  • 实现数据访问的统一接口
1

DAO接口定义

public interface UserDao {
    User getUserById(int id);
    List<User> getAllUsers();
    void addUser(User user);
    void updateUser(User user);
    void deleteUser(int id);
}
2

DAO实现类示例

public class UserDaoImpl implements UserDao {
    private DataSource dataSource;

    // 构造函数注入DataSource
    public UserDaoImpl(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    @Override
    public User getUserById(int id) {
        String sql = "SELECT * FROM users WHERE id = ?";
        try (Connection conn = dataSource.getConnection();
                PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setInt(1, id);
            ResultSet rs = pstmt.executeQuery();
            if (rs.next()) {
                return new User(
                    rs.getInt("id"),
                    rs.getString("username"),
                    rs.getString("email"));
            }
        }
        catch (SQLException e) {
            throw new DataAccessException("Error fetching user", e);
        }
        return null;
    }

    // 其他方法实现...
}

DAO模式最佳实践

  • 为每个实体创建独立的DAO接口和实现
  • 使用依赖注入(如Spring)管理DAO依赖
  • 在DAO层处理SQL异常,转换为业务异常
  • 使用泛型创建基础DAO接口减少重复代码
  • 结合Spring的JdbcTemplate简化JDBC操作

第六部分:综合复习测试题

检验SQL与JDBC知识的掌握程度

1

SQL基础题

给定一个员工表(employees)结构如下:
id INT PRIMARY KEY,
name VARCHAR(50),
department VARCHAR(50),
salary DECIMAL(10,2)

请编写SQL语句完成以下操作:
a) 查询市场部(Marketing)所有员工的姓名和工资
b) 将技术部(IT)所有员工的工资增加10%
c) 插入一条新员工记录:姓名-李四,部门-销售(Sales),工资-8000
2

JDBC连接题

以下JDBC代码存在哪些问题?请指出并修正:
public void getUser(String username) {
    Connection conn = null;
    Statement stmt = null;
    String sql = "SELECT * FROM users WHERE username = '" + username + "'";

    try {
        conn = DriverManager.getConnection(DB_URL, USER, PASS);
        stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery(sql);

        while (rs.next()) {
            System.out.println("User: " + rs.getString("username"));
        }
    }
    catch (SQLException e) {
        e.printStackTrace();
    }
}
3

事务处理题

在一个银行转账场景中,需要从账户A向账户B转账100元:
a) 使用JDBC代码实现转账事务
b) 解释为什么需要事务处理
c) 如果第二步操作失败会发生什么?
4

DAO设计题

设计一个ProductDAO接口,要求包含以下功能:
- 根据ID获取产品
- 获取所有产品列表
- 添加新产品
- 更新产品信息
- 根据ID删除产品

请:
a) 定义ProductDAO接口
b) 编写一个方法实现获取所有产品列表

第七部分:学习总结

巩固SQL与JDBC核心知识,为后续学习打下基础

关键知识点回顾

  • SQL基础:SELECT查询、INSERT插入、UPDATE更新
  • JDBC核心:DriverManager建立连接、Statement/PreparedStatement执行SQL
  • ResultSet:遍历处理查询结果
  • 事务管理:ACID特性、commit/rollback操作
  • DAO模式:数据访问层抽象,分离业务与数据逻辑

常见问题总结

问题类型 描述 解决方案
连接问题 无法建立数据库连接 检查URL、用户名、密码;确认数据库服务运行;检查网络连接
SQL注入 使用字符串拼接导致的安全漏洞 始终使用PreparedStatement进行参数化查询
资源泄露 未关闭Connection、Statement等资源 使用try-with-resources自动关闭资源
事务管理 未处理事务导致数据不一致 正确使用commit/rollback;设置合适的隔离级别
性能问题 频繁创建数据库连接 使用连接池管理数据库连接