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() 返回字典或 Nonefetchall() 返回列表 ResultSet 游标,需循环 next()
字段取值 字典方式:row['name'] rs.getString("name")
关闭资源 with 自动关闭 cursor 需要分别关闭 ResultSetPreparedStatement(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 自动管理 cursorconnection try-with-resources 自动管理 ConnectionPreparedStatementResultSet

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

相关推荐
牛大了20237 分钟前
场景题:数据迁移解决方案
开发语言
认真的酒窝8 小时前
自己动手开发编译器(十一)语义分析
java·开发语言
Lyn_Li8 小时前
扫描 PDF 歪了怎么办?用 6 种检测方法做本地批量扶正(附开源工具)
python·pdf·ocr·tesseract·开源工具·文档处理·本地处理·扫描件纠偏
金銀銅鐵8 小时前
费马小定理
python·数学·算法
wbs_scy9 小时前
Linux C++ 高并发编程:线程池全链路深度解析,从原理到手撕实现
java·开发语言
JAVA面经实录9179 小时前
Linux 常用命令完整知识体系
java·linux·开发语言·汇编
贪玩的蛋挞10 小时前
C#与闭包
开发语言·c#
端庄的战斗机10 小时前
javascript 设计模式(文章很长,请自备瓜子,水果和眼药水)
开发语言·javascript·设计模式
Full Stack Developme11 小时前
Java LRU 与 LFU 算法及应用
java·开发语言·算法
疋瓞12 小时前
python和C++对比(1)_数据类型和数据结构
数据结构·c++·python