Python (PyMySQL) vs Java (JDBC) 数据库操作对比

学生管理系统 数据连接版本(java和python的区别)


Python (PyMySQL) vs Java (JDBC) 数据库操作对比

本文对比了使用 PyMySQL (Python)和 JDBC(Java)操作 MySQL 数据库的核心差异,帮助有 Java 经验的开发者快速掌握 Python 的数据库编程。


1. 环境准备与驱动加载

步骤 Python (PyMySQL) Java (JDBC)
安装驱动 pip install pymysql 下载 MySQL Connector/J(JAR 包),添加到 classpath
导入包 import pymysql import java.sql.*
加载驱动类 无需显式加载 ,pip install 后直接可用 Class.forName("com.mysql.cj.jdbc.Driver") (JDBC 4.0 后可省略)

2. 建立数据库连接

Python (PyMySQL)

python 复制代码
conn = pymysql.connect(
    host="localhost",
    port=3306,
    user="root",
    password="123456",
    database="student_db",
    charset="utf8mb4",
    cursorclass=pymysql.cursors.DictCursor   # 可选,返回字典
)

Java (JDBC)

java 复制代码
String url = "jdbc:mysql://localhost:3306/student_db?useSSL=false&serverTimezone=UTC";
String user = "root";
String password = "123456";
try (Connection conn = DriverManager.getConnection(url, user, password)) {
    // 连接对象
}
对比项 Python Java
连接字符串 命名参数形式 JDBC URL + 参数
自动关闭 使用 with 语句或手动 close() 使用 try-with-resources(推荐)
返回结果形状 可指定 DictCursor 返回字典 返回 ResultSet,需手动映射

3. 执行查询(SELECT)

Python 示例

python 复制代码
with conn.cursor() as cursor:
    sql = "SELECT sid, name, age, score FROM students WHERE sid = %s"
    cursor.execute(sql, ("S001",))
    row = cursor.fetchone()          # 返回字典
    # row = {"sid":"S001", "name":"张三", "age":20, "score":85.5}
    
    # 多条结果
    cursor.execute("SELECT * FROM students")
    all_rows = cursor.fetchall()     # 返回字典列表

Java 示例

java 复制代码
String sql = "SELECT sid, name, age, score FROM students WHERE sid = ?";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
    pstmt.setString(1, "S001");
    try (ResultSet rs = pstmt.executeQuery()) {
        while (rs.next()) {
            String sid = rs.getString("sid");
            String name = rs.getString("name");
            int age = rs.getInt("age");
            double score = rs.getDouble("score");
        }
    }
}
对比项 Python Java
参数占位符 %s(通用,不区分类型) ?(位置参数)
设置参数 通过元组 (value,) 传入 execute() pstmt.setXxx(index, value)
获取结果 fetchone() 返回字典或 None;fetchall() 返回列表 ResultSet 游标,需循环 next()
字段取值 字典方式:row['name'] rs.getString("name")
关闭资源 with 自动关闭 cursor 需要分别关闭 ResultSet、PreparedStatement(try-with-resources 自动)

4. 插入数据(INSERT)

Python

python 复制代码
sql = "INSERT INTO students (sid, name, age, score) VALUES (%s, %s, %s, %s)"
with conn.cursor() as cursor:
    cursor.execute(sql, ("S002", "李四", 21, 92.5))
conn.commit()

Java

java 复制代码
String sql = "INSERT INTO students (sid, name, age, score) VALUES (?, ?, ?, ?)";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
    pstmt.setString(1, "S002");
    pstmt.setString(2, "李四");
    pstmt.setInt(3, 21);
    pstmt.setDouble(4, 92.5);
    int affected = pstmt.executeUpdate();
    conn.commit();
}
对比项 Python Java
执行方法 cursor.execute() pstmt.executeUpdate()
返回值 影响行数(可通过 cursor.rowcount 获得) 返回 int 影响行数
自动提交 默认 关闭 (需手动 commit()) 默认 自动提交 (可设置 conn.setAutoCommit(false))

5. 更新与删除

Python (更新)

python 复制代码
sql = "UPDATE students SET name = %s, score = %s WHERE sid = %s"
with conn.cursor() as cursor:
    affected = cursor.execute(sql, ("王五", 88.0, "S001"))
    conn.commit()

Java (更新)

java 复制代码
String sql = "UPDATE students SET name = ?, score = ? WHERE sid = ?";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
    pstmt.setString(1, "王五");
    pstmt.setDouble(2, 88.0);
    pstmt.setString(3, "S001");
    int affected = pstmt.executeUpdate();
    conn.commit();
}

删除类似,只需改变 SQL 语句。


6. 事务管理

操作 Python Java
关闭自动提交 连接创建后自动为手动提交模式 conn.setAutoCommit(false)
提交事务 conn.commit() conn.commit()
回滚事务 conn.rollback() conn.rollback()
异常处理中回滚 except 块中执行 rollback() catch 块中执行 rollback()

Python 典型事务模板

python 复制代码
try:
    with conn.cursor() as cursor:
        cursor.execute(sql1, params1)
        cursor.execute(sql2, params2)
    conn.commit()
except pymysql.Error as e:
    conn.rollback()
    print(f"事务失败: {e}")

Java 典型事务模板

java 复制代码
try {
    conn.setAutoCommit(false);
    try (PreparedStatement pstmt1 = conn.prepareStatement(sql1);
         PreparedStatement pstmt2 = conn.prepareStatement(sql2)) {
        pstmt1.executeUpdate();
        pstmt2.executeUpdate();
        conn.commit();
    }
} catch (SQLException e) {
    conn.rollback();
    e.printStackTrace();
} finally {
    conn.setAutoCommit(true);
}

7. 异常处理

方面 Python Java
异常类 pymysql.Error(及其子类) SQLException
捕获方式 try...except... try...catch...
获取错误信息 str(e) 或 e.args e.getMessage()
资源清理 使用 with 自动管理 cursor 和 connection try-with-resources 自动管理 Connection、PreparedStatement、ResultSet

8. 连接池对比(进阶)

特性 Python Java
常用库 DBUtils, SQLAlchemy (内置池) HikariCP, Apache DBCP, C3P0
简单示例 pooled_db = PooledDB(pymysql, maxconnections=5, ...) HikariConfig + HikariDataSource
自动归还连接 支持 支持

9. 代码风格与习惯

习惯 Python Java
变量命名 蛇形命名法 student_id 驼峰命名法 studentId
上下文管理器 with 自动管理资源 try-with-resources
返回结果 更倾向于返回字典或对象列表 通常封装成 POJO 或返回 List<Entity>
SQL 拼接 永远使用参数化查询 (%s 占位符) 永远使用 PreparedStatement
获取自增主键 cursor.lastrowid pstmt.getGeneratedKeys()

10. 完整示例:查询并打印所有学生

Python 版本

python 复制代码
def show_all_students():
    conn = get_connection()
    try:
        with conn.cursor() as cursor:
            cursor.execute("SELECT sid, name, age, score FROM students")
            rows = cursor.fetchall()
            for row in rows:
                print(f"{row['sid']} {row['name']} {row['age']} {row['score']}")
    except pymysql.Error as e:
        print(e)
    finally:
        conn.close()

Java 版本

java 复制代码
public void showAllStudents() {
    String sql = "SELECT sid, name, age, score FROM students";
    try (Connection conn = getConnection();
         PreparedStatement pstmt = conn.prepareStatement(sql);
         ResultSet rs = pstmt.executeQuery()) {
        while (rs.next()) {
            String sid = rs.getString("sid");
            String name = rs.getString("name");
            int age = rs.getInt("age");
            double score = rs.getDouble("score");
            System.out.printf("%s %s %d %.2f%n", sid, name, age, score);
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

总结

操作 Python 优势 Java 优势
连接建立 命名参数更清晰 JDBC URL 标准统一
查询执行 fetchone()/fetchall() 直接返回字典,方便 强类型,编译期检查
参数设置 元组传参,自动匹配类型 需要按索引设置类型,繁琐但安全
事务管理 同样支持 commit/rollback 同样支持
资源关闭 with 语句极其简洁 try-with-resources 也很优雅
性能 纯 Python 略慢 JVM 优化,通常更快
生态 SQLAlchemy 等 ORM 强大 MyBatis, Hibernate 成熟

核心思想 :无论 Python 还是 Java,数据库编程的流程都是一致的:建立连接 → 创建语句 → 执行 SQL → 处理结果 → 提交/回滚 → 关闭资源。语法差异只是表面,理解事务、连接池、参数化防注入等概念才是关键。

对于从 Java 转 Python 的开发者,推荐使用 PyMySQL + 字典游标 ,并结合 with 语句管理资源,可以快速写出简洁、安全的数据库代码。

相关推荐
默_笙4 天前
🍙 给每个请求过安检:FastAPI 是怎么把校验写进类型注解的
python
小羊没烦恼!4 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
qq_426003964 天前
启动playwright录制codegen生成自动化测试脚本
python·自动化
虎头金猫4 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
长沙三为智能科技4 天前
家政小程序开发从0到上线:五阶段交付流程与验收清单
python
伞伞悦读4 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
只睡四小时4 天前
Canvas 弹道联机实战:700 行 + 固定时间步长
python·websocket·html5·游戏开发·canvas
C语言小火车4 天前
C/C++ 为什么需要编译器?
开发语言·c++
奇思妙想聪明勤奋的小羊4 天前
DeepAgents第5章:子Agent 与上下文隔离—让 Agent学会委派
人工智能·python·学习·语言模型
lpfasd1234 天前
2026年第38周GitHub趋势周报
python·科技·github