JDBC详解


一、JDBC基本使用

1、介绍

JDBC 是 SUM 公司提供的一套 Java 连接各种数据库的规范(接口),各大数据库产商通过该规范开发自己的数据库驱动。

JDBC中定义了操作数据库的各种接口和类型:

接口 作用
Driver 驱动接口,定义建立链接的方式
DriverManager 工具类,用于管理驱动,可以获取数据库的链接
Connection 表示Java与数据库建立的连接对象(接口)
PreparedStatement 发送SQL语句的工具
ResultSet 结果集,用于获取查询语句的结果

简单地说,JDBC 可做三件事:与数据库建立连接、发送 操作数据库的语句并处理结果。

2、JDBC连接数据库

(0)步骤

1. 加载驱动
2. 获取链接
3. 准备SQL以及发送SQL的工具
4. 执行SQL
5. 处理结果集
6. 释放资源

依赖

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.17</version>
</dependency>

完整代码

String url = "jdbc:mysql://127.0.0.1:3306/rewind_ms_dev?characterEncoding=UTF-8";
String user = "root";
String password = "root";

Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;

try{
    // 1、加载数据库驱动
    Class.forName("com.mysql.jdbc.Driver");

    // 2、过驱动管理类获取数据库连接
    connection = DriverManager.getConnection(url, user, password);

    // 3、定义sql语句,?表示占位符
    String sql = "select * from wx_user where nick_name = ?";

    // 4、获取预处理statement
    preparedStatement = connection.prepareStatement(sql);

    // 5、设置参数,第一个参数为sql中参数的序号(从1开始),第二个参数为设置的值
    preparedStatement.setString(1, "Rewind");

    // 6、向数据库发送sql执行查询,查询出结果集
    resultSet = preparedStatement.executeQuery();

    // 7、遍历出结果集
    while(resultSet.next()){
        int id = resultSet.getInt("id");
        String name = resultSet.getString("nick_name");

        // 封装结果集...
    }

}catch (Exception e){
    e.printStackTrace();
}finally {
    try {
        if (preparedStatement != null){
            preparedStatement.close();
        }
    } catch (SQLException throwables) {
        throwables.printStackTrace();
    } finally {
        try{
            if (connection != null){
                connection.close();
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
}

(1)加载驱动

加载JDBC驱动是通过调用方法 java.lang.Class.forName(),下面列出常用的几种数据库驱动程序加载语句的形式 :

Class.forName(“oracle.JDBC.driver.OracleDriver”)//使用Oracle的JDBC驱动程序
Class.forName(“com.microsoft.JDBC.sqlserver.SQLServerDriver”)//使用SQL Server的JDBC驱动程序
Class.forName(“com.ibm.db2.JDBC.app.DB2Driver”)//使用DB2的JDBC驱动程序
Class.forName(“com.mysql.JDBC.Driver”);//使用MySql的JDBC驱动程序

(2)创建数据库连接

与数据库建立连接的方法是调用DriverManager.getConnection(String url, String user, String password )方法

String url = "jdbc:mysql://114.116.86.101:3306/rewind_ms_dev?characterEncoding=UTF-8";
String user = "root";
String password = "root";

Connection connection = null;
connection = DriverManager.getConnection(url, user, password);

Connection 常用方法:

  • createStatement():创建向数据库发送sql的statement对象。
  • prepareStatement(sql) :创建向数据库发送预编译sql的PrepareSatement对象。
  • prepareCall(sql):创建执行存储过程的callableStatement对象。
  • setAutoCommit(boolean autoCommit):设置事务是否自动提交。
  • commit() :在链接上提交事务。
  • rollback() :在此链接上回滚事务。

(3)创建Statement

Statement 对象用于将 SQL 语句发送到数据库中,或者理解为执行sql语句

有三种 Statement对象:

  • Statement:用于执行不带参数的简单SQL语句;

  • PreparedStatement(从 Statement 继承):用于执行带或不带参数的预编译SQL语句;

  • CallableStatement(从PreparedStatement 继承):用于执行数据库存储过程的调用。

PreparedStatement preparedStatement = null;

// 定义sql语句,?表示占位符
String sql = "select * from wx_user where nick_name = ?";

// 获取预处理statement
preparedStatement = connection.prepareStatement(sql);

// 设置参数,第一个参数为sql中参数的序号(从1开始),第二个参数为设置的值
preparedStatement.setString(1, "Rewind");

(4)执行SQL

preparedStatement 可以通过以下方法执行 SQL

方法 作用
ResultSet executeQuery() 执行查询语句
int executeUpdate() 执行增、删、改
boolean execute() 可执行任何语句,返回值表示是否返回 ResultSet
//向数据库发送sql执行查询,查询出结果集
ResultSet resultSet = preparedStatement.executeQuery();

(5)处理结果集

ResultSet 对象是 executeQuery() 方法的返回值,它被称为结果集,它代表符合SQL语句条件的所有行,并且它通过一套 getXXX 方法(这些get方法可以访问当前行中的不同列)提供了对这些行中数据的访问。

ResultSet 里的数据一行一行排列,每行有多个字段,且有一个记录指针,指针所指的数据行叫做当前数据行,我们只能来操作当前的数据行。我们如果想要取得某一条记录,就要使用 ResultSetnext() 方法 ,如果我们想要得到 ResultSet 里的所有记录,就应该使用 while 循环。

ResultSet 对象自动维护指向当前数据行的游标。每调用一次 next() 方法,游标向下移动一行。

初始状态下记录指针指向第一条记录的前面,通过 next() 方法指向第一条记录。循环完毕后指向最后一条记录的后面。

// 将游标下移一行
boolean next();

// 将游标上移一行
boolean previous();

// 关闭 ResultSet 对象
void close();

// 以 String 的形式获取指定列号的值
String getString(int columnIndex);

// 以 String 的形式获取指定列名的值
String getString(String columnLabel);

// 还有 getBoolean()、getByte() ...

(6)关闭资源

应在不需要 Statement 对象和 Connection 对象时显式地关闭它们。

用户不必关闭 ResultSet。当它的 Statement 关闭、重新执行或用于从多结果序列中获取下一个结果时,该 ResultSet 将被自动关闭。

注意:要按先 ResultSet 结果集,后 Statement,最后Connection 的顺序关闭资源,因为StatementResultSet 是需要连接是才可以使用的,所以在使用结束之后有可能其他的Statement 还需要连接,所以不能先关闭 Connection

ResultSet → Statement → Connection

try {
    if (preparedStatement != null){
        preparedStatement.close();
    }
} catch (SQLException throwables) {
    throwables.printStackTrace();
} finally {
    try{
        if (connection != null){
            connection.close();
        }
    } catch (SQLException throwables) {
        throwables.printStackTrace();
    }
}

二、JDBC中重要的类和接口

JDBC API由 java.sqljavax.sql 两个包构成

其实java.sql中的类不算多,大致分为接口,异常,API,驱动,枚举类

除这几个部分,剩下的就是作为java开发人员需要掌握的API,主要包括下面几个:

  • java.sql.Wrapper
  • java.sql.Connection
  • java.sql.Statement
  • java.sql.CallableStatement
  • java.sql.PreparedStatement
  • java.sql.DatabaseMetaData
  • java.sql.ParameterMetaData
  • java.sql.ResultSet
  • java.sql.ResultSetMetaData

这些接口都继承了 java.sql.Wrapper 接口

/**
* JDBC类的接口,当实例实际上是代理类时,这些类提供检索委托实例的能力。
* 许多JDBC驱动程序实现都使用包装器模式来提供特定于数据源的传统JDBC API之外的扩展。
* 开发人员可能希望访问这些资源,这些资源被包装为代表实际资源的代理类实例(委托)。
* 此接口描述了一种标准机制,用于访问由其代理表示的这些包装资源,以允许直接访问资源委托。
*/
public interface Wrapper {

    /**
     * 返回一个对象,该对象实现给定接口以允许访问非标准方法或代理未公开的标准方法。
     * 如果接收方实现了接口,则结果是接收方或接收方的代理。
     * 如果接收者是一个包装器,并且包装的对象实现了接口,那么结果就是包装的对象或包装对象的代理。
     * 否则,返回对已包装对象或该结果的代理递归调用unwrap的结果。如果接收方不是包装器,也没有实现接口,则抛出SQLException。
     */
    <T> T unwrap(java.lang.Class<T> iface) throws java.sql.SQLException;

    /**
     * 如果this实现了接口参数,或者是直接或间接实现了接口参数的对象的包装器,则返回true。否则返回false。
     * 如果这实现了接口,则返回true,否则如果这是一个包装器,则返回对包装对象递归调用isWrapperFor的结果。
     * 如果这没有实现接口并且不是包装器,则返回false。
     * 与展开操作相比,应该将此方法实现为低成本操作,以便调用方可以使用此方法来避免可能失败的昂贵的展开调用。
     * 如果此方法返回true,则使用相同的参数调用unwrap应该成功。
     */
    boolean isWrapperFor(java.lang.Class<?> iface) throws java.sql.SQLException;

}

  目录