Re-debugging: a comprehensive analysis of the JDBC series & lt; driver Loading Principles)

Source: Internet
Author: User
Tags driver manager
Preface recently, I have been studying the Mybatis framework. Since the framework is based on JDBC, to better understand and learn Mybatis, I must have a deep understanding of JDBC. So we will take the JDBC stuff out and summarize it. As a reference, we will also give readers a reference ~~~ Overview In general, connect to a database in an application and call J

Preface recently, I have been studying the Mybatis framework. Since the framework is based on JDBC, to better understand and learn Mybatis, I must have a deep understanding of JDBC. So we will take the JDBC stuff out and summarize it. As a reference, we will also give readers a reference ~~~ Overview In general, connect to a database in an application and call J

Preface

Recently, I have been studying the Mybatis framework. Since the framework is based on JDBC, to better understand and learn Mybatis, I must have a deep understanding of JDBC. So we will take the JDBC stuff out and summarize it. As a reference, we will also give readers a reference ~~~

Overview

Generally, to connect to a database in an application and call the JDBC interface, you must first load the JDBC driver implementation of a specific manufacturer into the system memory for use by the system. The basic structure is as follows:

Driver and Memory loading process

The so-called Driver is actually a class that implements the java. SQL. Driver Interface. For example, the oracle driver class is oracle. jdbc. Driver. OracleDriver. class (this class can be found in the JDBC jar package provided by oracle). This class implements the java. SQL. driver Interface.

Because the driver is essentially a class, the principle of loading the driver into the memory is the same as that of loading a common class: using Class. forName ("driverName "). The following code loads common database drivers into the memory:

// Load the Oracle database Driver Class. forName ("oracle. jdbc. driver. oracleDriver "); // load the SQL Server database Driver Class. forName ("com. microsoft. sqlserver. jdbc. SQLServerDriver "); // load the MySQL database Driver Class. forName ("com. mysql. jdbc. driver ");

Note: Class. forName () loads the corresponding Driver class into the memory, and then executes the static code segment in the memory. In the code segment, an instance of the Driver is created and put into DriverManager for use by DriverManager.

For example. forName () is used to load the oracle driver oracle. jdbc. driver. during OracleDriver, a static code segment in OracleDriver is executed, an OracleDriver instance is created, and DriverManager is called. registerDriver () Registration:

Static {Timestamp localTimestamp = Timestamp. valueOf ("00:00:00. 0 "); try {if (defaultDriver = null) {// create an OracleDriver instance and register it with DriverManager defaultDriver = new OracleDriver (); DriverManager. registerDriver (defaultDriver) ;}} catch (RuntimeException localRuntimeException) {} catch (SQLException localSQLException ){}
Driver Functions

The java. SQL. Driver Interface specifies that the Driver should have the following functions:

Where:

AcceptsURL (String url)The method is used to test whether the driver can enable the url Connection for the specified url. The driver will develop its own protocol for the url that can be connected by itself. Only a url that complies with its own protocol form can be considered to be able to open this url. If yes, true is returned. Otherwise, returns false;

For example, oracle defines its own url protocol as follows:

Jdbc: oracle: thin :@// : /ServiceName

Jdbc: oracle: thin :@ : :

The oracle acceptsURL (String url) method is as follows:

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;}

It can be seen from the above that oracle defines what type of URL they should receive and what type of URL Connection They can open (Note: Here, acceptsURL (url) only verifies whether the url complies with the Protocol and does not try to connect to determine whether the url is valid.). Extended reading: Common Database jdbc url formats

Connect (String url, Properties info)Method, create a Connection object, and use it to operate and interact with the database data, while Connection is the start of a real database operation (in this method, there is no rule on whether to perform an acceptsURL () for verification ).

Example of manually loading Driver and instantiating database operations
Public static void driverTest () {try {// 1. load the oracle Driver Class and instantiate the driver = (Driver) Class. forName ("oracle. jdbc. driver. oracleDriver "). newInstance (); // 2. determines whether the specified URL oracle driver can be accepted (complies with oracle Protocol rules) boolean flag = driver. acceptsURL ("jdbc: oracle: thin: @ 127.0.0.1: 1521: xe"); // test the standard protocol boolean standardFlag1 = driver. acceptsURL ("jdbc: oracle: thin :@//
 
  
:
  
   
/ServiceName "); boolean standardFlag2 = driver. acceptsURL (" jdbc: oracle: thin :@
   
    
:
    
     
:
     
      
"); System. out. println ("protocol test:" + flag + "\ t" + standardFlag1 + "\ t" + standardFlag2); // 3. create a real database connection: String url = "jdbc: oracle: thin: @ 127.0.0.1: 1521: xe"; Properties props = new Properties (); props. put ("user", "louluan"); props. put ("password", "123456"); Connection connection = driver. connect (url, props); // connection object is used for database interaction. The code is omitted .....} Catch (Exception e) {System. out. println ("An error occurred while loading the Oracle class! "); E. printStackTrace () ;}finally {}}
     
    
   
  
 

The process of manually loading the Driver and obtaining the connection is a little clumsy: If we have loaded multiple Driver drivers, then manually create a Driver instance, creating a connection based on the URL will make the code messy and error-prone and inconvenient to manage. JDBC provides a DriverManager role to manage these drivers.

DriverManager role

In fact, we generally operate the Driver and hand over the Connection object to DriverManager for unified management. DriverManger can register and delete loaded drivers. It can obtain Driver complying with the url protocol based on a given url or establish a Conenction connection for database interaction.

The following is a summary of DriverManager's key methods:

DriverManager holds these registered Driver internally, because these drivers areJava. SQL. DriverType. How can I obtain the Driver from a specified manufacturer? The answer is:

The java. SQL. Driver Interface specifies that the vendor implements this interface and defines its own URL protocol. The Driver interface implemented by the Manufacturer uses acceptsURL (String url) to determine whether the url complies with its own protocol. if it complies with its own protocol, you can use this Driver to connect to the database, queries whether the driver thinks it can open a connection to a given URL.

Use DriverManager to obtain the specified Driver

How can I get the specified driver after the driver is loaded? Here, the static method getDriver (String url) of DriverManager can return the Driver that can open the URL Connection through the URL passed.
For example, to obtain the oracle database driver, you only need to passJdbc: oracle: thin :@ : : OrJdbc: oracle: thin :@// : /ServiceName To DriverManager. getDriver (String url:

Driver oracleDriver =DriverManager.getDriver("jdbc:oracle:thin:@
 
  :
  
   :
   
    ");
   
  
 

Actually, DriverManager. the getDriver (String url) method traverses the maintained Driver Based on the passed URL, and calls the Driver's acceptsURL (url) in turn. If the returned acceptsURL (url) returns true, the corresponding Driver is returned:

Public static Driver getDriver (String paramString) throws SQLException {// some code is omitted .... Iterator localIterator = registeredDrivers. iterator (); // traverses the registered driver while (localIterator. hasNext () {DriverInfo localDriverInfo = (DriverInfo) localIterator. next (); if (isDriverAllowed (localDriverInfo. driver, localClass) try {// If accepsURL () is true, the corresponding driverif (localDriverInfo. driver. acceptsURL (paramString) {// return the corresponding driverreturn localDriverInfo. driver ;}} catch (SQLException localSQLException) {} elseprintln ("skipping:" + localDriverInfo. driver. getClass (). getName ();} throw new SQLException ("No suitable driver", "08001"); // ----- omitting some code}
Use DriverManager to register and cancel Driver registration

Started in this blogDriver Loading ProcessThis section describes how to register a Driver instance in DriverManager when using Class. forName ("driverName") to load a Driver. The following code verifies this statement:

Public static void defaultDriver () {try {String url = "jdbc: oracle: thin: @ 127.0.0.1: 1521: xe"; // 1. load the Driver to the memory, and then execute its static code. Create an OracleDriver instance and register it with the DriverManager Class. forName ("oracle. jdbc. driver. oracleDriver "); // obtain the corresponding oracle driver DriverDriver = DriverManager. getDriver (url); System. out. println ("Get the Driver object after loading the class:" + driver); // remove the driver from the DriverManager. deregisterDriver (driver); // re-use the url from the Dri In verManager, Driverdriver = DriverManager. getDriver (url); System. out. println (driver);} catch (Exception e) {System. out. println ("failed to load Oracle class! "); E. printStackTrace () ;}finally {}}
The preceding Code consists of the following steps:

1. First, load oracle. jdbc. driver. OracleDriver to the memory;

2. Then, call DriverManager. getDriver () to retrieve the Driver instance;

3. log off the driver instance from DriverManager;

4. Try again to get the Driver instance of the corresponding url;

The result of the above code execution is as follows:

According to the execution results, the above discussion can be verified: when the Driver instance of the corresponding url is obtained again in Step 4, the appropriate Driver cannot be found because the Driver has been deregistered, an exception "Not suitable driver" is thrown.

The above example is slightly changed. After canceling the driver created by the static block, register a self-created Driver object instance with DriverManager (for detailed steps, see the Notes ):

Public static void defaultDriver () {try {String url = "jdbc: oracle: thin: @ 127.0.0.1: 1521: xe"; // 1. load the Driver to the memory and execute its static code. Create an OracleDriver instance and register it with the Driver dd = (Driver) Class in DriverManager. forName ("oracle. jdbc. driver. oracleDriver "). newInstance (); // 2. obtain the corresponding oracle driver DriverDriver = DriverManager. getDriver (url); System. out. println ("Get the Driver object after loading the class:" + driver); // 3. remove the driver from DriverManager . DeregisterDriver (driver); // 4. if no Driver instance is available in DriverManager, register the created dd TO DriverManager. registerDriver (dd); // 5. use the url to retrieve Driverdriver = DriverManager from DriverManager again. getDriver (url); System. out. println ("deregister the statically created Driver, re-register the Driver:" + driver); System. out. println ("whether the driver and dd are the same object:" + (driver = dd);} catch (Exception e) {System. out. println ("failed to load Oracle class! "); E. printStackTrace () ;}finally {}}
The result of running the following code:

The above code first creates a Driver object. After logging out of DriverManager, the Driver is statically created during the Driver loading process, and then registered to the system, the Driver returned by the corresponding url in DriverManager is the Driver object created in the code.

Use DriverManager to create a Connection object

Create a Connection object. You can use the connect (url, props) method of the Driver or the getConnection () method provided by DriverManager. This method automatically matches the corresponding Driver instance through the url, then call the corresponding connect method to return the Connection object instance.

Driver driver  = DriverManager.getDriver(url);Connection connection = driver.connect(url, props);
The above code is equivalent:
Class.forName("oracle.jdbc.driver.OracleDriver");Connection connection = DriverManager.getConnection(url, props);
Jdbc. drivers

As the Driver manager, DriverManager is loaded into the memory when it is used for the first time (that is, when it is used for the first time in the Code, then execute the static code segment defined by it. In the static code segment, there is a static loadInitialDrivers () method to load the configuration in jdbc. driver in drivers system attribute, Which is configured in jdbc. the driver in drivers will be loaded first:

Static {loadInitialDrivers (); // load the driver driverprintln ("jdbc DriverManager initialized") in the JDBC. drivers system variable; SET_LOG_PERMISSION = new SQLPermission ("setLog ");}
Private static void loadInitialDrivers () {String str1; try {str1 = (String) AccessController. doPrivileged (new PrivilegedAction () {public String run () {return System. getProperty ("jdbc. drivers "); // return jdbc. drivers value }});} catch (Exception localException1) {str1 = null;} // omitting some code ...... if (str1 = null) | (str1.equals ("") return; String [] arrayOfString1 = str1.split (":"); println ("number of Drivers: "+ arrayOfString1.length); for (String str2: arrayOfString1) try {// Class. forName: load the corresponding driverClass. forName (str2, true, ClassLoader. getSystemClassLoader ();} catch (Exception localException2) {println ("DriverManager. initialize: load failed: "+ localException2 );}}

The following describes how to load the driver through jdbc. drivers:

String url = "jdbc: oracle: thin: @ 127.0.0.1: 1521: xe"; // sets the value system variable jdbc. driversSystem. setProperty ("jdbc. drivers "," oracle. jdbc. driver. oracleDriver "); // 2. get driverDriver driver = DriverManager through a specific url. getDriver (url); // print whether System exists. out. println (driver );
Remember: you must set jdbc. drivers before using DriverManager for the first time, because the static code segment in DriverManager will only be executed once!

Certificate -------------------------------------------------------------------------------------------------------------------------------------------------------------

The above is the articleOld: JDBC Series <驱动加载原理全面解析> All of the above are your own experiences and are not authoritative. If you have any mistakes, please feel free to criticize them! Welcome to my next blog:Old: JDBC Series

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.