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 语句管理资源,可以快速写出简洁、安全的数据库代码。

相关推荐
冻柠檬飞冰走茶8 分钟前
字母移动游戏题解:贪心求最长可保留连续子串(附 C 实现)
c语言·开发语言·数据结构·算法·动态规划
FRing0324 分钟前
vue2干货总结7(自定义指令、插槽、单页应用程序、路由的使用(VueRouter))
开发语言·前端·vue.js·vue2
橙橙笔记25 分钟前
具身智能的学习 - 完成一个机械臂 第1节
python·学习·机械臂·具身智能
雪落漂泊28 分钟前
C++算法 二分查找篇(上)
开发语言·c++·算法
小小张说故事33 分钟前
Python 的 class 语句到底执行了什么?拆开 __prepare__、metaclass.__new__ 和那个被讲反的 __set_name__ 顺序
python
波力海苔夹心脆6752 小时前
C# WPF 资源字典详解:ResourceDictionary、MergedDictionaries 与自定义控件案例
开发语言·c#·wpf·入门教程·resource·资源字典
不会算法的笨小孩2 小时前
异常的使用以及会出现的问题
开发语言·c++·c++11·异常
天天被压力3 小时前
【A股分钟级高频数据完全手册 #07】北交所历史分钟K线接口:京市Pro版分时批量
java·人工智能·python
天天被压力3 小时前
【A股分钟级高频数据完全手册 #08】股票日、分时数据接口对比:普通分时与Pro版差异实测
java·人工智能·python
特立独行的猫A3 小时前
AI 时代,我为什么推荐用 cj-tauri 开发桌面应用
java·后端·python