在后端开发中,MySQL 作为主流关系型数据库,其与编程语言的高效连接是数据交互的核心。本文将详细讲解 Java 和 Python 两种语言操作 MySQL 的完整流程,从基础连接、SQL 执行,到连接池优化(重点解析 HikariCP 和 Druid),帮你轻松搞定数据库交互需求。
一、Python 操作 MySQL:简洁高效的 pymysql 实战
Python 通过pymysql库实现与 MySQL 的交互,语法简洁,适合快速开发和脚本编写。
1. 环境准备
首先安装第三方依赖库:
bash
运行
pip install pymysql2. 核心操作流程
Python 操作 MySQL 的核心步骤为:创建连接→创建游标→执行 SQL→处理结果→关闭资源,完整示例如下:
python
运行
import pymysql # 1. 创建数据库连接 # 核心参数:主机地址、端口、用户名、密码、目标数据库 conn = pymysql.connect( host='localhost', # 本地主机可填'localhost',远程需填IP port=3306, # MySQL默认端口3306 user='root', # 数据库用户名 passwd='123456', # 数据库密码 db='stu_test' # 要操作的数据库名称 ) # 2. 创建游标(用于执行SQL语句) cursor = conn.cursor() try: # 3. 执行SQL语句(查询示例) sql = ''' SELECT t1.sid, t1.sname, t2.score FROM ( SELECT sid, sname FROM Student WHERE sid IN ( SELECT t1.sid FROM (SELECT sid, score FROM SC WHERE cid = '01') t1 LEFT JOIN (SELECT sid, score FROM SC WHERE cid = '02') t2 ON t1.sid = t2.sid WHERE t1.score > IFNULL(t2.score, 0) ) ) t1 LEFT JOIN SC t2 ON t1.sid = t2.sid ''' cursor.execute(sql) # 执行SQL # 4. 处理查询结果 print("获取单条数据:", cursor.fetchone()) # 取1条结果 print("-" * 50) print("获取剩余所有数据:", cursor.fetchall()) # 取剩余全部结果 print("-" * 50) print("获取指定条数数据:", cursor.fetchmany(10)) # 取指定数量结果 # 增删改操作需提交事务 # sql_insert = "INSERT INTO Student(sid, sname) VALUES ('001', '张三')" # cursor.execute(sql_insert) # conn.commit() # 提交事务 # conn.rollback() # 异常时回滚 except Exception as e: print("SQL执行失败:", str(e)) finally: # 5. 关闭资源(先关游标,再关连接) cursor.close() conn.close()3. 关键注意事项
- 执行增删改操作后必须调用
conn.commit()提交事务,否则修改不生效; - 异常场景下需调用
conn.rollback()回滚事务,避免数据不一致; - 游标获取结果后,指针会移动,
fetchone()/fetchall()/fetchmany(n)需按需使用。
二、Java 操作 MySQL:JDBC 基础连接
Java 通过 JDBC(Java Database Connectivity)规范实现与 MySQL 的连接,是 Java 操作数据库的标准方式,适用于企业级应用开发。
1. 环境准备
添加 MySQL 驱动依赖(Maven 项目):
xml
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.49</version> <!-- 稳定版本,适配多数场景 --> </dependency>2. JDBC 核心操作流程
JDBC 操作分为 6 步:加载驱动→创建连接→创建执行器→执行 SQL→处理结果→关闭资源,完整示例:
java
运行
package com.shujia; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; public class MySQLJDBCDemo { public static void main(String[] args) throws Exception { // 1. 加载MySQL驱动(MySQL 5.x版本驱动类) Class.forName("com.mysql.jdbc.Driver"); // 2. 创建数据库连接 // URL格式:jdbc:mysql://主机:端口/数据库名?参数 String url = "jdbc:mysql://localhost:3306/db1?useSSL=false"; String username = "root"; String password = "123456"; Connection conn = DriverManager.getConnection(url, username, password); // 3. 创建Statement执行器(用于执行SQL语句) Statement st = conn.createStatement(); // 4. 执行查询SQL,返回结果集 String sql = "SELECT * FROM student"; ResultSet rs = st.executeQuery(sql); // 5. 遍历结果集 while (rs.next()) { int id = rs.getInt("id"); // 按列名获取int类型 String name = rs.getString("name");// 按列名获取String类型 int age = rs.getInt("age"); String gender = rs.getString("gender"); String clazz = rs.getString("clazz"); System.out.printf("%d,%s,%d,%s,%s%n", id, name, age, gender, clazz); } // 6. 关闭资源(逆序关闭:ResultSet→Statement→Connection) rs.close(); st.close(); conn.close(); } }3. JDBC 核心要点
- URL 参数
useSSL=false:关闭 SSL 连接,避免开发环境 SSL 验证报错; - 结果集
ResultSet需通过rs.next()移动指针,初始指针在第一条数据前; - 资源关闭必须执行,否则会导致数据库连接泄露,建议用
try-with-resources自动关闭。
三、连接池优化:解决 JDBC 性能瓶颈
1. 为什么需要连接池?
传统 JDBC 每次操作数据库都要创建和关闭连接,存在两大问题:
- 性能开销大:连接创建 / 关闭是耗时操作,频繁执行会严重影响系统性能;
- 资源泄露风险:未及时关闭的连接会占用数据库资源,导致资源耗尽;
- 连接池通过 “缓存连接” 实现资源重用,解决上述问题,核心优势:
- 资源重用:连接复用,减少创建 / 关闭开销;
- 响应更快:预初始化连接,无需等待连接创建;
- 统一管理:控制最大连接数,避免资源独占;
- 防止泄露:超时自动回收空闲连接。
2. 主流连接池对比
| 连接池 | 核心特点 | 性能排名 | 适用场景 |
|---|---|---|---|
| HikariCP | 轻量高效,锁竞争少,SpringBoot2 默认推荐 | 1 | 追求高性能的企业级应用 |
| Druid | 功能全面,支持 SQL 监控、拦截,扩展性强 | 2 | 需要监控和扩展的复杂应用 |
| tomcat-jdbc | Tomcat 内置,配置简单,稳定性好 | 3 | Tomcat 部署的 Web 应用 |
| DBCP | Apache 出品,Tomcat 早期使用,功能基础 | 4 | 简单应用,不追求极致性能 |
| C3P0 | 历史悠久,代码复杂,性能较差 | 5 | legacy 系统兼容 |
3. 实战 1:HikariCP 连接池(高性能首选)
步骤 1:添加 Maven 依赖
xml
<dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifactId> <version>4.0.3</version> <!-- 稳定版本 --> </dependency>步骤 2:初始化连接池并使用
java
运行
import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; public class HikariCPDemo { public static void main(String[] args) { // 1. 配置连接池参数 HikariConfig config = new HikariConfig(); config.setJdbcUrl("jdbc:mysql://localhost:3306/db1?useSSL=false"); config.setUsername("root"); config.setPassword("123456"); // 核心配置 config.setConnectionTimeout(1000); // 连接超时:1秒 config.setIdleTimeout(60000); // 空闲超时:60秒 config.setMaximumPoolSize(16); // 最大连接数:16(根据CPU核心数调整) config.setMinimumIdle(4); // 最小空闲连接数:4 // 2. 创建连接池实例 HikariDataSource dataSource = new HikariDataSource(config); // 3. 获取连接并操作数据库(try-with-resources自动关闭资源) try (Connection conn = dataSource.getConnection()) { String sql = "SELECT name, age FROM student WHERE id = ?"; PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setInt(1, 1); // 预处理SQL,避免SQL注入 ResultSet rs = pstmt.executeQuery(); if (rs.next()) { System.out.println("姓名:" + rs.getString("name") + ",年龄:" + rs.getInt("age")); } } catch (Exception e) { e.printStackTrace(); } } }4. 实战 2:Druid 连接池(功能全面)
步骤 1:添加 Maven 依赖
xml
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.16</version> </dependency>步骤 2:初始化连接池
java
运行
import com.alibaba.druid.pool.DruidDataSource; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; public class DruidDemo { public static void main(String[] args) throws Exception { // 1. 配置连接池 DruidDataSource dataSource = new DruidDataSource(); dataSource.setUrl("jdbc:mysql://localhost:3306/db1?useSSL=false"); dataSource.setUsername("root"); dataSource.setPassword("123456"); dataSource.setMaxActive(16); // 最大连接数 dataSource.setMinIdle(4); // 最小空闲连接 dataSource.setMaxWait(1000); // 最大等待时间 dataSource.setValidationQuery("SELECT 1"); // 连接校验SQL // 2. 获取连接 Connection conn = dataSource.getConnection(); Statement st = conn.createStatement(); ResultSet rs = st.executeQuery("SELECT * FROM student LIMIT 5"); // 3. 处理结果 while (rs.next()) { System.out.println(rs.getString("name")); } // 4. 关闭资源 rs.close(); st.close(); conn.close(); // 归还连接到池,并非真正关闭 } }四、核心优化建议
- 连接池参数调优:
- 最大连接数(maximumPoolSize):建议设为 CPU 核心数 ×2+1,避免连接过多导致数据库压力;
- 空闲超时(idleTimeout):根据业务场景设置(30-60 秒),避免空闲连接占用资源。
- SQL 执行优化:
- Python 使用参数化查询避免 SQL 注入:
cursor.execute("INSERT INTO Student VALUES (%s, %s)", ('002', '李四')); - Java 使用
PreparedStatement替代Statement,预处理 SQL 提升性能并防注入。
- Python 使用参数化查询避免 SQL 注入:
- 资源关闭规范:
- Python 用
finally块强制关闭游标和连接; - Java 优先使用
try-with-resources自动关闭Connection/Statement/ResultSet。
- Python 用
五、总结
- Python+pymysql:适合快速开发、脚本工具,语法简洁,上手成本低;
- Java+JDBC:企业级应用标准方案,稳定性强,配合连接池可满足高性能需求;
- 连接池选择:追求性能选 HikariCP,需要监控和扩展选 Druid;
- 核心原则:无论哪种语言,都要保证 “资源重用、事务安全、防止注入”,才能实现高效稳定的数据库交互。
掌握以上内容,即可应对大部分开发场景中的 MySQL 操作需求,从简单脚本到企业级应用都能游刃有余。