JDBC

一、 什么是JDBC

JDBC(Java DataBase Connectivity)是Java数据库连接技术的简称。它提供了连接和操作各种常用数据库的能力。JDBC只定义了Java应用程序访问数据库的标准接口层,而具体的实现由各数据库厂商提供(称为数据库驱动程序包)。

二、 JDBC工作原理

JDBC驱动程序包是对JDK JDBC API的具体实现。JDBC定义了与数据库通信的规范和协议,而这些规范的具体实现由数据库厂商负责。

三、 JDBC访问数据库的步骤

准备工作

将驱动程序包mysql-connector-j-8.2.0.jar引入项目依赖中。

  1. 注册数据库驱动程序

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    final String DRIVER = "com.mysql.cj.jdbc.Driver";
    final String URL = "jdbc:mysql://localhost:3306/scott";
    final String USERNAME = "root";
    final String PASSWORD = "123456";

    try {
    // 注册数据库驱动
    Class.forName(DRIVER);
    } catch (ClassNotFoundException e) {
    System.err.println("注册数据库驱动失败");
    }

    // 获取数据库连接
    Connection conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);

    // 创建语句对象
    Statement stmt = conn.createStatement();

    // 执行 SQL 语句
    ResultSet rs = stmt.executeQuery("SELECT * FROM emp");

    // 遍历查询结果集
    while (rs.next()) {
    // 处理每一行数据
    }

    // 关闭资源
    if (rs != null) rs.close();
    if (stmt != null) stmt.close();
    if (conn != null) conn.close();

    四、 JDBC API 类

    4.1 Connection 常用方法

    • close()
    • commit()
    • createStatement()
    • prepareStatement(String sql)
    • rollback()

    4.2 Statement 常用方法

    • execute(String sql)
    • executeQuery(String sql)
    • executeUpdate(String sql)

    4.3 ResultSet 常用方法

    • next()
    • close()
    • getXxx(int columnIndex)

    五、PreparedStatement

    PreparedStatementStatement的子类,它有以下优点:

    • 执行效率高
    • 安全
    • 支持参数占位符 ?
    1
    2
    3
    4
    PreparedStatement ps = conn.prepareStatement("INSERT INTO emp(ename, job) VALUES (?, ?)");
    ps.setString(1, "John");
    ps.setString(2, "Manager");
    ps.executeUpdate();

    六、存储过程调用

    可以通过 CallableStatement 调用存储过程。

    1
    2
    3
    4
    5
    CallableStatement cs = conn.prepareCall("{call get_job_sum_sal(?,?)}");
    cs.setString(1, "SALESMAN");
    cs.registerOutParameter(2, java.sql.Types.DOUBLE);
    cs.execute();
    double result = cs.getDouble(2);

    七、批量更新

    7.1 Statement 批量更新

    使用 Statement 对象进行批量更新,添加多个 SQL 语句到批处理中,然后执行批处理。

    1
    2
    3
    statement.addBatch("UPDATE people SET firstname='aaa' WHERE id=123");
    statement.addBatch("UPDATE people SET firstname='bbb' WHERE id=456");
    statement.executeBatch();

    7.2 PreparedStatement 批量更新

    使用 PreparedStatement 对象进行批量更新,设置参数并添加到批处理中,然后执行批处理。

    1
    2
    3
    4
    preparedStatement.setString(1, "james");
    preparedStatement.setLong(2, 123);
    preparedStatement.addBatch();
    preparedStatement.executeBatch();

    八、Java数据类型与SQL类型的映射

    8.1 Conversions by setObject(index, value)

    支持的Java到JDBC类型转换

    Java Type JDBC Type
    String VARCHAR
    Integer INTEGER
    Double DOUBLE

    8.2 Conversions by ResultSet.getXXX Methods

    JDBC Type getXxx Methods
    VARCHAR getString()
    INTEGER getInt()

    九、Apache DBUtils 组件库

    DBUtils是Apache提供的一个简化JDBC编程的工具组件库。

    9.1 ResultSetHandler 结果集处理器接口

    • BeanHandler:单行结果封装为JavaBean对象
    • BeanListHandler:多行结果封装为JavaBean列表
    • MapHandler:单行结果封装为Map
    • MapListHandler:多行结果封装为Map列表

    9.2 QueryRunner SQL 执行操作类

    所有数据库操作通过QueryRunner完成。

    普通查询

    1
    Employee e = runner.query(conn, sql, new BeanHandler<>(Employee.class));

    带占位符参数查询

    1
    List<Employee> list = runner.query(conn, sql, new BeanListHandler<>(Employee.class), "%A%", 1000.0, 5000.0);

    标量查询

    1
    Long rows = runner.query(conn, "SELECT COUNT(empno) AS r FROM emp", new ScalarHandler<>());

    保存

    1
    int i = runner.update(conn, "INSERT INTO emp(EMPNO,ENAME) VALUES(?,?)", 8136, "Alex");

    更新

    1
    int i = runner.update(conn, "UPDATE emp SET ENAME=? WHERE EMPNO=?", "Alex", 8136);

    删除

    1
    int i = runner.update(conn, "DELETE FROM emp WHERE EMPNO=?", 8136);