最近在研究Mybatis框架,由于该框架基于JDBC,想要很好地理解和学习Mybatis,必须要对JDBC有较深入的了解。所以便把JDBC 这个东东翻出来,好好总结一番,作为自己的笔记,也是给读者一个参考~~~

概述

一般情况下,在应用程序中进行数据库连接,调用JDBC接口,首先要将特定厂商的JDBC驱动实现加载到系统内存中,然后供系统使用。基本结构图如下:

老调重弹:JDBC系列之<驱动加载原理全面解析) ----转

驱动加载入内存的过程

这里所谓的驱动,其实就是实现了java.sql.Driver接口的类。如oracle的驱动类是 oracle.jdbc.driver.OracleDriver.class(此类可以在oracle提供的JDBC jar包中找到),此类实现了java.sql.Driver接口。

由于驱动本质上还是一个class,将驱动加载到内存和加载普通的class原理是一样的:使用Class.forName("driverName")。以下是将常用的数据库驱动加载到内存中的代码:

 

1
2
3
4
5
6
7
8
//加载Oracle数据库驱动
Class.forName("oracle.jdbc.driver.OracleDriver");
 
//加载SQL Server数据库驱动
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
 
//加载MySQL 数据库驱动
Class.forName("com.mysql.jdbc.Driver");

 

注意:Class.forName()将对应的驱动类加载到内存中,然后执行内存中的static静态代码段,代码段中,会创建一个驱动Driver的实例,放入DriverManager中,供DriverManager使用。

例如,在使用Class.forName() 加载oracle的驱动oracle.jdbc.driver.OracleDriver时,会执行OracleDriver中的静态代码段,创建一个OracleDriver实例,然后调用DriverManager.registerDriver()注册:

1
2
3
4
5
6
7
8
9
10
11
12
static {
    Timestamp localTimestamp = Timestamp.valueOf("2000-01-01 00:00:00.0");
    try {
        if (defaultDriver == null) {
            //创建一个OracleDriver实例,然后注册到DriverManager中
                            defaultDriver = new OracleDriver();
            DriverManager.registerDriver(defaultDriver);
        }
 
    } catch (RuntimeException localRuntimeException) {
    } catch (SQLException localSQLException) {
    }

Driver的功能

java.sql.Driver接口规定了Driver应该具有以下功能:

老调重弹:JDBC系列之<驱动加载原理全面解析) ----转

其中:

acceptsURL(String url) 方法用来测试对指定的url,该驱动能否打开这个url连接。driver对自己能够连接的url会制定自己的协议,只有符合自己的协议形式的url才认为自己能够打开这个url,如果能够打开,返回true,反之,返回false;

例如:oracle定义的自己的url协议如下:

jdbc:oracle:thin:@//<host>:<port>/ServiceName

jdbc:oracle:thin:@<host>:<port>:<SID>

oracle自己的acceptsURL(String url)方法如下:

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
31
32
33
34
35
36
37
38
39
40
public boolean acceptsURL(String paramString) {
    if (paramString.startsWith("jdbc:oracle:")) {
        return (oracleDriverExtensionTypeFromURL(paramString) > -2);
    }
 
    return false;
}
 
private int oracleDriverExtensionTypeFromURL(String paramString) {
    int i = paramString.indexOf(58) + 1;
 
    if (i == 0) {
        return -2;
    }
    int j = paramString.indexOf(58, i);
 
    if (j == -1) {
        return -2;
    }
    if (!(paramString.regionMatches(true, i, "oracle", 0, j - i))) {
        return -2;
    }
    ++j;
 
    int k = paramString.indexOf(58, j);
 
    if (k == -1) {
        return -3;
    }
    String str = paramString.substring(j, k);
 
    if (str.equals("thin")) {
        return 0;
    }
    if ((str.equals("oci8")) || (str.equals("oci"))) {
        return 2;
    }
 
    return -3;
}

由上可知oracle定义了自己应该接收什么类型的URL,自己能打开什么类型的URL连接(注意:这里acceptsURL(url)只会校验url是否符合协议,不会尝试连接判断url是否有效) 。拓展阅读:常用数据库 JDBC URL格式

connect(String url,Properties info)方法,创建Connection对象,用来和数据库的数据操作和交互,而Connection则是真正数据库操作的开始(在此方法中,没有规定是否要进行acceptsURL()进行校验)。

手动加载驱动 Driver 并实例化进行数据库操作的例子

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
public static void driverTest(){
    try {
        //1.加载oracle驱动类,并实例化
        Driver driver = (Driver) Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
 
        //2.判定指定的URL oracle驱动能否接受(符合oracle协议规则)
        boolean flag = driver.acceptsURL("jdbc:oracle:thin:@127.0.0.1:1521:xe");
        //标准协议测试
        boolean standardFlag1 = driver.acceptsURL("jdbc:oracle:thin:@//<host>:<port>/ServiceName");
        boolean standardFlag2 = driver.acceptsURL("jdbc:oracle:thin:@<host>:<port>:<SID>");
        System.out.println("协议测试:"+flag+"\t"+standardFlag1+"\t"+standardFlag2);
         
        //3.创建真实的数据库连接:
        String  url = "jdbc:oracle:thin:@127.0.0.1:1521:xe";
        Properties props = new Properties();

相关文章:

  • 2022-12-23
  • 2021-06-21
  • 2021-12-02
  • 2021-09-21
  • 2021-07-05
  • 2021-08-26
  • 2022-02-19
  • 2021-10-23
猜你喜欢
  • 2022-01-06
  • 2021-07-02
  • 2021-09-29
  • 2021-06-20
  • 2022-12-23
  • 2022-02-15
  • 2022-12-23
相关资源
相似解决方案