本文适合 Java+MySQL 开发新手,系统梳理 JDBC 操作 MySQL 的核心知识点:事务隔离级别配置、索引优化实战、常见异常排查方案,附可直接运行的代码示例,学习 / 面试都能用!

一、前置知识:JDBC 操作 MySQL 基础

1.1 依赖引入(Maven)

使用 MySQL 8.0 + 驱动,注意驱动类和 URL 语法变化:

xml

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.30</version>
</dependency>

1.2 JDBC 连接 MySQL 固定模板

java

运行

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
​
public class JDBCUtil {
    // MySQL 8.0+ 连接参数
    private static final String URL = "jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true";
    private static final String USER = "root";
    private static final String PASSWORD = "123456";
​
    // 获取数据库连接
    public static Connection getConnection() {
        Connection conn = null;
        try {
            conn = DriverManager.getConnection(URL, USER, PASSWORD);
            System.out.println("数据库连接成功!");
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }
​
    // 关闭连接
    public static void close(Connection conn) {
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

二、MySQL 事务隔离级别(JDBC 配置 + 原理)

2.1 事务四大特性(ACID)

  1. 原子性:事务要么全部执行,要么全部回滚

  2. 一致性:执行前后数据完整性不变

  3. 隔离性:多个事务互不干扰

  4. 持久性:事务提交后数据永久生效

2.2 事务并发三大问题

  1. 脏读:一个事务读取到另一个未提交的事务数据

  2. 不可重复读:同一事务内,两次查询结果不一致(其他事务修改了数据)

  3. 幻读:同一事务内,两次查询行数不一致(其他事务插入 / 删除数据)

2.3 MySQL 四大隔离级别(从低到高)

表格

隔离级别 脏读 不可重复读 幻读 性能
读未提交(READ UNCOMMITTED) 最高
读已提交(READ COMMITTED)
可重复读(REPEATABLE READ)
串行化(SERIALIZABLE) 最低

默认级别:MySQL 默认使用可重复读(RR),Oracle 默认读已提交(RC)

2.4 JDBC 设置事务隔离级别

JDBC 通过Connection对象设置隔离级别,核心代码:

java

运行

public class TransactionTest {
    public static void main(String[] args) {
        Connection conn = JDBCUtil.getConnection();
        try {
            // 1. 关闭自动提交(开启事务)
            conn.setAutoCommit(false);
            
            // 2. 设置事务隔离级别:4种常量可选
            // Connection.TRANSACTION_READ_UNCOMMITTED  读未提交
            // Connection.TRANSACTION_READ_COMMITTED    读已提交
            // Connection.TRANSACTION_REPEATABLE_READ   可重复读(默认)
            // Connection.TRANSACTION_SERIALIZABLE      串行化
            conn.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
​
            // 3. 执行业务SQL(省略)
            System.out.println("事务执行中...");
​
            // 4. 提交事务
            conn.commit();
            System.out.println("事务提交成功!");
​
        } catch (SQLException e) {
            e.printStackTrace();
            try {
                // 5. 异常回滚事务
                conn.rollback();
                System.out.println("事务已回滚!");
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
        } finally {
            JDBCUtil.close(conn);
        }
    }
}

2.5 查看 / 修改 MySQL 全局隔离级别

sql

-- 查看当前隔离级别
SELECT @@transaction_isolation;
​
-- 设置当前会话隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

三、MySQL 索引优化实战(高频面试 + 工作必备)

3.1 索引是什么?

索引是优化查询速度的数据结构(默认 B + 树),相当于书的目录,能大幅减少查询 IO。

3.2 索引分类

  1. 主键索引PRIMARY KEY,唯一且非空,一张表只能有一个

  2. 唯一索引UNIQUE,列值唯一,允许 NULL

  3. 普通索引INDEX,仅加速查询

  4. 联合索引:多个字段组合索引,遵循最左前缀原则

  5. 全文索引FULLTEXT,用于文本搜索

3.3 索引创建 / 删除语法

sql

-- 1. 创建普通索引
CREATE INDEX idx_user_name ON user(name);
​
-- 2. 创建唯一索引
CREATE UNIQUE INDEX idx_user_phone ON user(phone);
​
-- 3. 创建联合索引(最常用!)
CREATE INDEX idx_user_name_age ON user(name, age);
​
-- 4. 删除索引
DROP INDEX idx_user_name ON user;

3.4 索引优化核心规则(必背)

  1. 最左前缀原则

    :联合索引必须从左到右使用,否则索引失效

    sql
    -- 有效:使用联合索引 idx(name,age) 
    SELECT * FROM user WHERE name='张三' AND age=20; 
    -- 失效:跳过name直接查age 
    SELECT * FROM user WHERE age=20;
  2. 避免索引列运算 / 函数

    :索引列上使用函数、计算会导致索引失效

    sql
    
    
    
    -- 失效 
    SELECT * FROM user WHERE age+1=20; 
    -- 有效 
    SELECT * FROM user WHERE age=19;
  3. 模糊查询以 % 开头失效

    sql
    
    -- 失效
    SELECT * FROM user WHERE name LIKE '%张三';
    -- 有效
    SELECT * FROM user WHERE name LIKE '张三%';
  4. ** 避免使用 SELECT ***:只查询需要的字段,减少回表

  5. order by/group by 遵循索引规则:排序字段最好建立索引

3.5 执行计划:EXPLAIN 分析索引

使用EXPLAIN查看 SQL 是否使用索引:

sql

EXPLAIN SELECT * FROM user WHERE name='张三';

关键字段:

  • type:最优const > ref > range > ALL(全表扫描)

  • key:显示使用的索引,NULL表示未使用索引

  • rows:扫描行数,越小越好


四、JDBC+MySQL 常见异常及解决方案

异常 1:Communications link failure(连接失败)

报错信息

Could not create connection to database server

原因

  1. MySQL 服务未启动

  2. 连接 URL / 账号密码错误

  3. MySQL 8.0 + 驱动类错误

    解决方案

  4. 启动 MySQL 服务

  5. 检查 URL:jdbc:mysql://localhost:3306/库名

  6. 驱动类:com.mysql.cj.jdbc.Driver(8.0 + 必须加 cj)

异常 2:java.sql.SQLException: 没有自动提交,不能执行更新

原因

autoCommit
commit/rollback

解决方案

  • 增删改操作必须手动调用conn.commit()

  • 异常时必须调用conn.rollback()

异常 3:Lock wait timeout exceeded; try restarting transaction(锁等待超时)

原因

解决方案

  1. 优化事务,缩短事务执行时间

  2. 检查未提交事务:SELECT * FROM information_schema.innodb_trx;

  3. kill 阻塞事务

异常 4:Duplicate entry 'xxx' for key 'PRIMARY'(主键冲突)

原因

解决方案

  1. 主键设置自增AUTO_INCREMENT

  2. 插入数据时不指定主键字段

异常 5:JDBC 中文乱码

原因

解决方案

plaintext

jdbc:mysql://localhost:3306/testdb?useUnicode=true&characterEncoding=utf8

异常 6:Too many connections(连接数过多)

原因

解决方案

  1. 必须在finally中关闭Connection

  2. 使用连接池(Druid/HikariCP)管理连接


五、总结

  1. 事务隔离级别:MySQL 默认可重复读,解决脏读、不可重复读、幻读,JDBC 通过Connection配置

  2. 索引优化:核心是避免索引失效,联合索引遵循最左前缀,用 EXPLAIN 分析 SQL

  3. 异常处理:重点关注连接失败、事务未提交、中文乱码、连接泄漏问题


📌 补充建议

  1. 生产环境必须使用连接池(Druid 推荐),不要手动创建连接

  2. 事务不要嵌套,避免长事务

  3. 高频查询字段必须建索引,低频率字段不建索引(降低写入性能)

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐