Java连接数据库靠的是jdbc驱动,各个数据库厂家有自己的驱动器实现,下面以mysql为例说明Java程序是如何实现数据库连接的。先看一段连接代码

public static void main(String [] args)
      {
          try {
              //初始化驱动类com.mysql.jdbc.Driver,就在 mysql-connector-java的jar包中
              //Class.forName是把这个类加载到JVM中,加载的时候,就会执行其中的静态初始化块,完成驱动的初始化的相关工作。
              Class.forName("com.mysql.jdbc.Driver");
              // 建立与数据库的Connection连接
              Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/xxxx?characterEncoding=utf-8",
                      "root", "123456");
              //Statement属于Java的包
              Statement statement = connection.createStatement();
              System.out.println("获取的statement对象:"+statement);

          } catch (ClassNotFoundException e) {
              e.printStackTrace();
          } catch (SQLException ex) {
              ex.printStackTrace();
          }
      }


Class.forName("com.mysql.jdbc.Driver");


此行代码会加载com.mysql.jdbc.Driver驱动器到jvm中,用到了本地函数。com.mysql.jdbc.Driver实现了jdk自己的Driver

java 连接数据库实验方案 java连接数据库原理_数据库

同时厂商的Driver会以静态代码块的形式注册到程序的驱动管理器中:

public class Driver extends NonRegisteringDriver implements java.sql.Driver {
    public Driver() throws SQLException {
    }

    static {
        try {
            DriverManager.registerDriver(new Driver());
        } catch (SQLException var1) {
            throw new RuntimeException("Can't register driver!");
        }
    }
}

通过DriverManager获得连接,本质是通过各自可用的驱动获取连接,同理Connection也是厂商自己实现了jdk里面的Connection接口。

java 连接数据库实验方案 java连接数据库原理_bc_02


在Connection的实现中,创建了一个叫MysqlIO对象,该对象会创建一个叫mysqlOutput输出流


BufferedOutputStream对象


java 连接数据库实验方案 java连接数据库原理_数据库_03

在MysqlIO构造方法里面已经建立了和mysql服务器连接的socket,由StandardSocketFactory实现

java 连接数据库实验方案 java连接数据库原理_java_04

接着调用doHandshake()方法与MySql服务器进行握手

java 连接数据库实验方案 java连接数据库原理_bc_05

这个doHandshake主要用来初始化与MySQL server的连接,负责登陆服务器和处理连接错误。在其中会分析所连接的mysql server的版本,根据不同的版本以及是否使用SSL加密数据都有不同的处理方式。在其中调用secureAuth411方法,把要传输给数据库server的数据都放在一个叫做packet的buffer中,调用send()方法,经过层层包装转换,往mysqlOutput中写入要发送的数据。 

this.send(packet, packet.getPosition());

各种增删改查的操作都要用到sendCommand方法

如果要进行查询操作,最后也要通过调用MysqlIO类的sqlQueryDirect方法执行,通过sendCommand方法,其最后得到一个resultPacket的Buffer,最后构造出一个ResultSet返回。

总结:JDBC 使用 SPI 机制加载数据库驱动。获取数据库连接对象 Connection,实际上是对数据库建立 Socket 连接。通过 Statement 来查询数据,底层是向 Socket 写入二进制数据,再从 Socket 读取二进制数据,最后封装在 Resultset 对象之中。