首页...Java数据库编程基础——JDBC入门详解
Java语言程序设计第九章 Java数据库编程/第一节 JDBC基础

Java数据库编程基础——JDBC入门详解

2026-03-24

概述

Java数据库编程是Java应用程序与数据库交互的重要技术手段,而JDBC(Java Database Connectivity)作为Java语言访问关系型数据库的标准API,是实现数据库操作的基础。本节内容将全面介绍JDBC的基础知识,帮助考生理解JDBC的概念、组成、工作流程及基本操作方法,掌握使用JDBC进行数据库编程的核心技能。

通过本节学习,考生将能够:

  • 理解JDBC的定义和作用
  • 掌握JDBC的核心组件和使用步骤
  • 熟悉基本的数据库连接、查询、更新操作流程
  • 理解JDBC工作原理及其与数据库的交互机制
  • 通过实例掌握JDBC编程的具体写法和注意事项

核心概念

1. JDBC(Java Database Connectivity)

JDBC是Java语言访问数据库的标准API,是一组用于执行SQL语句的接口和类,能够实现Java程序与各种关系型数据库之间的通信。

2. 驱动程序(Driver)

驱动程序是JDBC连接数据库的桥梁,不同数据库厂商提供不同的驱动程序,用于实现Java程序与对应数据库的通信。

3. 连接对象(Connection)

表示与数据库的连接会话,是执行SQL操作的基础。

4. 语句对象(Statement)与预编译语句对象(PreparedStatement)

用于执行SQL语句,Statement适合执行静态SQL语句,PreparedStatement适合执行含参数的动态SQL语句,且性能更优。

5. 结果集对象(ResultSet)

用于存储和操作查询结果。

6. JDBC URL

数据库连接的地址字符串,包含数据库类型、IP地址、端口号、数据库实例名等信息。

原理分析

JDBC的工作原理基于Java应用程序通过JDBC API调用驱动程序提供的接口,驱动程序负责将Java调用转化为数据库可识别的操作命令,完成数据库的连接、SQL语句的发送、结果的返回等流程。

具体工作流程如下:

  1. 加载数据库驱动程序(DriverManager)
  2. 通过驱动管理器获取数据库连接(Connection)
  3. 创建语句对象(Statement或PreparedStatement)
  4. 执行SQL语句(查询或更新)
  5. 处理结果集(ResultSet)
  6. 关闭连接和释放资源

这种设计使得Java程序与数据库的耦合度较低,具备良好的平台移植性和扩展性。

详细内容

1. JDBC驱动类型

JDBC驱动根据实现方式分为四种类型:

  • 类型1驱动:JDBC-ODBC桥驱动

    • 通过ODBC连接数据库,需要安装ODBC驱动
    • 不同平台兼容性较差,效率低,一般不推荐使用
  • 类型2驱动:本地API驱动

    • 调用本地数据库客户端库实现连接
    • 性能较好,但受限于平台和数据库客户端环境
  • 类型3驱动:网络协议驱动

    • 通过中间服务器转发数据库请求
    • 适合分布式环境,灵活性较高
  • 类型4驱动:纯Java驱动(Thin驱动)

    • 直接实现数据库协议,纯Java实现
    • 跨平台,性能优良,是目前使用最广泛的驱动类型

2. JDBC编程基本步骤

Java程序使用JDBC访问数据库一般遵循以下步骤:

  1. 加载驱动程序
Class.forName("com.mysql.cj.jdbc.Driver");
  1. 建立数据库连接
Connection conn = DriverManager.getConnection(url, username, password);
  1. 创建语句对象
Statement stmt = conn.createStatement();

或使用预编译语句

PreparedStatement pstmt = conn.prepareStatement(sql);
  1. 执行SQL语句

查询

ResultSet rs = stmt.executeQuery(sql);

更新(增删改)

int count = stmt.executeUpdate(sql);
  1. 处理结果集

遍历ResultSet,获取数据

  1. 释放资源

关闭ResultSet、Statement、Connection,防止资源泄露

3. 数据库连接字符串(JDBC URL)

一个典型的JDBC URL格式:

jdbc:数据库类型://主机地址:端口号/数据库名?参数

示例:连接MySQL数据库

jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=UTC

参数说明:

  • useSSL=false:关闭SSL连接
  • serverTimezone=UTC:设置服务器时区,避免时区冲突

4. Statement与PreparedStatement区别

特性 Statement PreparedStatement
SQL编写方式 静态SQL语句 预编译SQL,支持参数占位符
性能 每次执行均需编译 编译一次,多次执行提高性能
安全性 易受SQL注入攻击 参数绑定,防止SQL注入
使用场景 简单SQL执行 动态参数、多次执行SQL

5. 处理查询结果

ResultSet对象用于存储查询结果,常用方法包括:

  • next():移动游标到下一条记录,返回boolean
  • getString(), getInt(), getDate()等:获取指定列的数据
  • 可以通过列名或列索引获取数据

示例:

while(rs.next()) {
    String name = rs.getString("name");
    int age = rs.getInt("age");
    System.out.println("Name: " + name + ", Age: " + age);
}

6. 事务处理基础

JDBC默认自动提交事务,使用conn.setAutoCommit(false);可以关闭自动提交,手动控制事务,执行多条SQL语句后通过conn.commit();提交或conn.rollback();回滚。

事务能够保证数据库操作的原子性,一致性,隔离性和持久性(ACID)。

实例分析

实例一:连接MySQL数据库并查询学生信息

背景

某学校有学生信息数据库,表结构如下:

字段 类型 说明
id int 学生编号
name varchar 学生姓名
age int 年龄

代码示例

import java.sql.*;

public class JdbcQueryExample {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/school?useSSL=false&serverTimezone=UTC";
        String user = "root";
        String password = "123456";

        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;

        try {
            // 1.加载驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            // 2.建立连接
            conn = DriverManager.getConnection(url, user, password);
            // 3.创建语句对象
            stmt = conn.createStatement();
            // 4.执行查询
            String sql = "SELECT id, name, age FROM students";
            rs = stmt.executeQuery(sql);

            // 5.处理结果集
            while(rs.next()) {
                int id = rs.getInt("id");
                String name = rs.getString("name");
                int age = rs.getInt("age");
                System.out.println("ID: " + id + ", Name: " + name + ", Age: " + age);
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 6.释放资源
            try { if(rs != null) rs.close(); } catch (Exception e) {}
            try { if(stmt != null) stmt.close(); } catch (Exception e) {}
            try { if(conn != null) conn.close(); } catch (Exception e) {}
        }
    }
}

结论

  • 成功连接数据库并查询到学生信息
  • 理解了JDBC连接、语句执行和结果处理的完整流程

实例二:使用PreparedStatement插入数据

背景

向上述学生表中添加新的学生记录,需要防止SQL注入,且提高性能。

代码示例

import java.sql.*;

public class JdbcInsertExample {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/school?useSSL=false&serverTimezone=UTC";
        String user = "root";
        String password = "123456";

        Connection conn = null;
        PreparedStatement pstmt = null;

        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection(url, user, password);

            String sql = "INSERT INTO students (id, name, age) VALUES (?, ?, ?)";
            pstmt = conn.prepareStatement(sql);

            pstmt.setInt(1, 1001);
            pstmt.setString(2, "张三");
            pstmt.setInt(3, 20);

            int rows = pstmt.executeUpdate();
            System.out.println("插入了 " + rows + " 条记录。");

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try { if(pstmt != null) pstmt.close(); } catch (Exception e) {}
            try { if(conn != null) conn.close(); } catch (Exception e) {}
        }
    }
}

结论

  • 使用PreparedStatement有效防止SQL注入
  • 编写参数化SQL语句,提升代码安全性和效率

实例三:JDBC事务控制示范

背景

在转账操作中,需要保证转出和转入两条SQL语句的原子性。

代码示例

import java.sql.*;

public class JdbcTransactionExample {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/bank?useSSL=false&serverTimezone=UTC";
        String user = "root";
        String password = "123456";

        Connection conn = null;
        PreparedStatement pstmt1 = null;
        PreparedStatement pstmt2 = null;

        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection(url, user, password);
            // 关闭自动提交
            conn.setAutoCommit(false);

            String sql1 = "UPDATE accounts SET balance = balance - ? WHERE account_id = ?";
            String sql2 = "UPDATE accounts SET balance = balance + ? WHERE account_id = ?";

            pstmt1 = conn.prepareStatement(sql1);
            pstmt2 = conn.prepareStatement(sql2);

            // 转出100元
            pstmt1.setDouble(1, 100);
            pstmt1.setInt(2, 1001);
            pstmt1.executeUpdate();

            // 转入100元
            pstmt2.setDouble(1, 100);
            pstmt2.setInt(2, 1002);
            pstmt2.executeUpdate();

            // 提交事务
            conn.commit();
            System.out.println("转账成功!");

        } catch (Exception e) {
            try {
                if (conn != null) {
                    conn.rollback();
                    System.out.println("转账失败,已回滚。");
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            e.printStackTrace();
        } finally {
            try { if(pstmt1 != null) pstmt1.close(); } catch (Exception e) {}
            try { if(pstmt2 != null) pstmt2.close(); } catch (Exception e) {}
            try { if(conn != null) conn.close(); } catch (Exception e) {}
        }
    }
}

结论

  • 通过关闭自动提交和手动提交,实现事务控制
  • 保证转账操作的原子性,防止部分执行导致数据不一致

常见误区

  1. 误区:不关闭数据库连接

    • 问题:未关闭Connection、Statement、ResultSet导致资源泄漏
    • 正确做法:使用try-with-resources或finally块确保资源关闭
  2. 误区:频繁加载驱动类

    • 问题:每次操作都调用Class.forName加载驱动,效率低
    • 正确做法:驱动加载一次即可,通常放在程序初始化阶段
  3. 误区:使用Statement执行动态SQL,易受SQL注入攻击

    • 问题:拼接SQL字符串传入用户输入,安全隐患大
    • 正确做法:使用PreparedStatement并绑定参数,防止注入
  4. 误区:忽略异常处理和事务控制

    • 问题:数据库操作异常未捕获,可能导致数据不一致
    • 正确做法:合理捕获异常,使用事务保证数据完整性
  5. 误区:未设置正确的时区和字符编码

    • 问题:连接字符串未指定时区,导致日期时间数据错误
    • 正确做法:在JDBC URL中添加相关参数,如serverTimezone=UTCcharacterEncoding=utf8

应用场景

  1. 企业级应用系统数据持久化

    • 使用JDBC实现Java后台与数据库之间的数据交互,完成用户信息管理、订单处理等功能。
  2. 数据采集与分析系统

    • 通过JDBC从数据库读取大量数据,进行统计分析和报表生成。
  3. Web应用后端

    • Servlet或Spring框架中使用JDBC操作数据库,实现动态网页数据展示。
  4. 桌面管理软件

    • 利用JDBC连接本地或远程数据库,实现库存管理、财务核算等功能。
  5. 事务处理系统

    • 在银行、电商等领域通过JDBC的事务控制保障数据一致性和可靠性。

知识拓展

  • JDBC连接池技术

    • 为提升性能,避免频繁建立连接,常使用连接池(如C3P0、Druid)管理数据库连接。
  • ORM框架简介

    • Hibernate、MyBatis等框架在JDBC基础上封装,简化数据库操作,支持对象关系映射。
  • JDBC4.0及以上新特性

    • 自动加载驱动、try-with-resources支持等,提升编程便利性。
  • SQL注入攻击原理及防范

    • 深入理解SQL注入攻击,学习如何通过PreparedStatement防御。
  • 跨数据库操作注意事项

    • 不同数据库SQL语法差异,JDBC驱动兼容性和性能优化策略。

总结回顾

本节内容系统讲解了Java数据库编程的基础——JDBC,包括其定义、核心组成、工作原理和编程步骤。通过对JDBC驱动类型的介绍,明确了类型4驱动的优势和广泛应用。重点掌握了数据库连接的建立、SQL语句的执行、结果集的处理和资源的释放。实例部分通过查询、插入和事务控制三个典型案例,帮助加深理解和应用能力。常见误区提醒考生注意资源管理、安全性和事务控制等关键点。结合应用场景和知识拓展,构建了完整的JDBC知识体系,为后续深入学习Java数据库编程和相关框架打下坚实基础。

通过本节学习,考生应能够熟练使用JDBC进行基础的数据库操作,理解底层原理及最佳实践,为全国计算机等级考试二级Java语言程序设计部分的数据库编程内容奠定坚实的理论与实战基础。

重点知识点

1

JDBC是Java语言访问数据库的标准API,提供统一的数据库操作接口

2

JDBC包括驱动程序、连接对象、语句对象、结果集等核心组件

3

JDBC的基本编程步骤包括加载驱动、建立连接、创建语句、执行SQL、处理结果、释放资源

4

类型4驱动(纯Java驱动)是当前最常用的JDBC驱动类型,跨平台性能优良

5

PreparedStatement相比Statement更安全高效,防止SQL注入

6

ResultSet用于存储和遍历查询结果,支持多种数据类型获取

7

JDBC支持事务控制,通过关闭自动提交实现原子性操作

8

常见误区包括资源未关闭、驱动频繁加载、SQL注入风险、异常处理不当、时区设置错误

9

JDBC广泛应用于企业系统、Web应用、数据分析和事务处理等场景

10

连接池和ORM框架是JDBC技术的重要延伸和优化手段