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
同时厂商的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接口。
在Connection的实现中,创建了一个叫MysqlIO对象,该对象会创建一个叫mysqlOutput输出流
BufferedOutputStream对象
在MysqlIO构造方法里面已经建立了和mysql服务器连接的socket,由StandardSocketFactory实现
接着调用doHandshake()方法与MySql服务器进行握手
这个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 对象之中。