目标
通过追踪常用的jdbc方法去熟悉PGjdbc的执行流程
常见jdbc使用流程
Class.forName("org.postgresql.Driver");
Connection connectionPG = DriverManager.getConnection("jdbc:postgresql://localhost:5432/xxx","xxxxxx","xxxxxx");
Statement statement =connectionPG.createStatement();
statement.executeUpdate(sql);
追踪
查看引用
引入的包如下:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
java.sql包主要是定义了一些接口规范,具体实现由各个数据库的jdbc实现,因而我们需要去PGjdbc里找对应接口的实现类,继而追踪各个方法的实现过程
追踪Class.forName
首先在PGjdbc源码中找到org.postgresql.Driver,其位于pgjdbc-master\pgjdbc\src\main\java\org\postgresql\Driver.java,该类实现了java.sql.Driver接口,
通过观察源码可知,该类存在静态代码块,当执行Class.forName对其进行动态加载时,其将执行了该代码块,如下:
该register()方法如下:
由此可见,当执行动态加载时,将执行静态代码块里的语句,实现该驱动的自动加载和注册。
对DriverManager.registerDriver()进行追踪,其最终效果为将新建的Driver置于如下
数组中。
追踪DriverManager.getConnection
函数追踪如下:
可知该方法只是检查一下参数,继续追踪:
该方法较长,核心部分如下:
其遍历registeredDrivers(如上截图),并尝试使用每个驱动程序连接到数据库,从而获得目标连接。
我们发现该连接是通过Driver类的connect方法实现的,继续追踪:
值得注意的是,该方法中有如下代码块:
该部分调用了一个从本地加载配置文件的方法,在追踪过程中,并未发现该文件,不知是否会在某过程中生成。继续往下看,有关连接的核心部分如下:
因为我们未设置超时参数,故选择追踪 makeConnection
追踪到PGConnection的构造函数:
该函数结合了info对象和本地枚举类PGProperty里存储的一些枚举常量,对PGConnection里的各个属性进行了配置,
个人认为,该部分info对象和PGProperty的一些枚举常量的组合写法,是一种很妙的配置。
debug追踪
在之前的各个位置打上断点,选择org.postgresql.jdbc.ConnectionValidTest文件里的:
进行debug。