Preface
recently in the study of the MyBatis framework, since the framework is based on JDBC and wants to understand and learn mybatis well, it is necessary to have a deeper understanding of JDBC. So the JDBC this thing turned out, a good summary, as their own notes, but also to the reader a reference ~ ~ ~ The following is the structure of this article, readers can click on the above directory to view:
Overview
In general, database connections are made in the application, and the JDBC interface is called, and the JDBC driver implementation of a specific vendor is first loaded into system memory and then used by the system. The basic structure diagram is as follows:
the process of driving the load into memory
the so-called driver is actually the class that implements the Java.sql.Driver interface. such as Oracle's 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.
Since the driver is essentially a class, it is the same as loading the driver into memory and loading the normal class principle: Using Class.forName ("drivername"). Here is the code that loads the common database driver into 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 MySQL database driver class.forname (" Com.mysql.jdbc.Driver ");
NOTE: Class.forName () Loading the corresponding driver class into memory and then executing the static in-memory code snippet, in the code snippet, creates an instance of the driver driver, which is put into DriverManager for drivermanager use.
For example, when using the Class.forName () When loading Oracle's driver oracle.jdbc.driver.OracleDriver, a static code snippet in Oracledriver is executed, a Oracledriver instance is created, and then the drivermanager.registerdriver is called () Registration:
static {Timestamp Localtimestamp = timestamp.valueof ("2000-01-01 00:00:00.0"); try {if (defaultdriver = = null) {// Create a Oracledriver instance and register it in DriverManager defaultdriver = new Oracledriver ();D rivermanager.registerdriver ( defaultdriver);}} catch (RuntimeException localruntimeexception) {} catch (SQLException localsqlexception) {}
features of the driver
the Java.sql.Driver interface specifies that the driver should have the following functions:
which
The acceptsurl (String URL) method is used to test for the specified URL, whether the driver can open the URL connection. Driver to the URL that you can connect to develop their own protocol, only the URL in accordance with their own protocol to think that they can open the URL, if you can open, return true, conversely, return false;
For example: Oracle defines its own URL protocol as follows:
Jdbc:oracle:thin:@//
Jdbc:oracle:thin:@
Oracle's own 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 (+) + 1;if (i = = 0) {return -2;} Int J = Paramstring.indexof (+, i); if (j = =-1) {return-2;} if (! ( Paramstring.regionmatches (True, I, "Oracle", 0, J-i))) {return-2;} ++j;int k = Paramstring.indexof (+, 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;}
From the above, Oracle defines what type of URL you should receive and what type of URL connection you can open ( Note: here Acceptsurl (URL) only verifies that the URL conforms to the protocol and does not attempt to connect to determine if the URL is valid ). Expand reading: Common database JDBC URL format
The Connect (String url,properties Info) method creates a connection object that is used to manipulate and interact with the database data, while connection is the beginning of a real database operation (in this method, There is no requirement for acceptsurl () to be verified.
example of manually loading a drive Driver and instantiating a database operation
public static void Drivertest () {try {//1. Load the Oracle driver class, and instantiate driver Driver = (driver) class.forname (" Oracle.jdbc.driver.OracleDriver "). Newinstance ()//2. Determine whether the specified URL Oracle driver is acceptable (compliant with Oracle protocol rules) Boolean flag = Driver.acceptsurl ("Jdbc:oracle:thin:@127.0.0.1:1521:xe");//Standard protocol Test Boolean STANDARDFLAG1 = Driver.acceptsurl ("jdbc : Oracle:thin:@//
The process of manually loading driver and getting a connection is slightly awkward: if we now load multiple driver driver, manually creating driver instances and creating connections based on URLs can be confusing, error-prone, and inconvenient to manage. a DriverManager role is provided in JDBC to manage these driver driver.
DriverManager Role
In fact, generally we operate driver, get connection objects are handed to DriverManager unified management. Drivermanger can register and delete loaded drivers, and can obtain a driver driver that conforms to the URL protocol given the URL or establish a conenction connection for database interaction.
The following is a summary of the key methods of DriverManager:
DriverManager internally hold these registered driver Driver, since these drivers are java.sql.Driver type, how can I get the driver Driver of the specified manufacturer? The answer is:
The Java.sql.Driver interface specifies that the vendor implements the interface and defines its own URL protocol. Vendors implement the driver interface to determine whether this URL conforms to its own protocol through the Acceptsurl (String URL), and if it complies with its own protocol, you can use this driver for database connection operations, and the query driver thinks it can open a connection to a given URL.
use DriverManager to get the specified driver
How do I get the specified driver after the driver is loaded? Here, DriverManager's static method, Getdriver (String URL), can be passed to the URL that returns a driver that can open this URL connection.
For example, I want to get Oracle's database driver, just pass the form like jdbc:oracle:thin:@ or jdbc:oracle: Thin:@// parameters to Drivermanager.getdriver (String URL):
Driver oracledriver =drivermanager.getdriver ("jdbc:oracle:thin:@
in fact, Drivermanager.getdriver (String URL) method is based on the passed URL, traversing the driver driver it maintains, sequentially calling the driver's driver Acceptsurl (URL), if return Acceptsurl (URL) returns True, the corresponding driver is returned:
public static Driver Getdriver (String paramstring) throws SQLException {//Omit part of code .... Iterator localiterator = Registereddrivers.iterator ();//traverse the registered driver while (Localiterator.hasnext ()) {Driverinfo Localdriverinfo = (driverinfo) localiterator.next (), if (isdriverallowed (Localdriverinfo.driver, LocalClass)) try {// If Accepsurl () is true, returns the corresponding Driverif (LocalDriverInfo.driver.acceptsURL (paramstring)) {//returns the corresponding Driverreturn Localdriverinfo.driver;}} catch (SQLException localsqlexception) {}elseprintln (" skipping:" + localDriverInfo.driver.getClass (). GetName () );} throw new SQLException ("No Suitable Driver", "08001");//-----Omit part of the code}
register and unregister driver driver using DriverManager
In the driver loading process section at the beginning of this blog post, it is discussed that a driver instance is registered with the DriverManager when the driver is loaded using Class.forName ("drivername"). The following code validates this assertion:
public static void Defaultdriver () {try {String url = ' Jdbc:oracle:thin:@127.0.0.1:1521:xe ';//1. Load driver into memory, Then execute its static code, create a Oracledriver instance registered to DriverManager class.forname ("Oracle.jdbc.driver.OracleDriver");// Remove the corresponding Oracle driver driverdriver driver = drivermanager.getdriver (URL); System.out.println ("After loading the class, get the driver object:" +driver);//Driver off DriverManager drivermanager.deregisterdriver (driver );//re-fetch driverdriver = drivermanager.getdriver (URL) from DriverManager via URL; SYSTEM.OUT.PRINTLN (driver);} catch (Exception e) {System.out.println ("Failed to load Oracle Class! "); E.printstacktrace ();} finally{}}
The above code is mainly divided into the following steps:
1. The first is to load the oracle.jdbc.driver.OracleDriver into memory;
2. Then call Drivermanager.getdriver () to fetch the driver instance;
3. Write off the driver instance from the DriverManager;
4. Try to fetch the driver instance of the corresponding URL;
The result of the above code execution is as follows:
from the execution results, just can verify the above: When the fourth step to obtain the corresponding URL of the Driver instance, because it has been written off, unable to find the appropriate driver Driver, throws the "not suitable Driver" exception.
To change the above example slightly, after you have written off the static block-created driver, register a driver object instance (see note) to DriverManager that you created yourself:
public static void Defaultdriver () {try {String url = ' Jdbc:oracle:thin:@127.0.0.1:1521:xe ';//1. Load driver into memory, Then execute its static code, create a Oracledriver instance to register in DriverManager Driver dd = (Driver) class.forname (" Oracle.jdbc.driver.OracleDriver "). Newinstance ()//2. Remove the corresponding Oracle driver driverdriver Driver = Drivermanager.getdriver ( URL); System.out.println ("After loading the class, get the driver object:" +driver);//3. Remove the driver from the DriverManager drivermanager.deregisterdriver (driver)//4. There is no driver DriverManager instance in driver at this time, Register the created DD to DriverManager Drivermanager.registerdriver (DD)//5. Re-fetch driverdriver from drivermanager via URL = Drivermanager.getdriver (URL); system.out.println ("Unregister the driver after a statically created driver:" +driver); System.out.println ("Driver and DD are the same object:" + (DRIVER==DD));} catch (Exception e) {System.out.println ("Failed to load Oracle Class! "); E.printstacktrace ();} finally{}}
The following code runs the result:
The above code first creates a driver object, which is registered to the system after it is statically created by the load driver during the logoff of DriverManager, and now the driver returned by the corresponding URL in DriverManager is the driver object created in the code.
Creating Connection Connection objects using DriverManager
To create a Connection connection object, you can use Connect (url,props) that drives driver, or you can use the getconnection () method provided by DriverManager. This method automatically matches the corresponding driver driver instance through the URL, and then calls 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 to:
Class.forName ("Oracle.jdbc.driver.OracleDriver"); Connection Connection = drivermanager.getconnection (URL, props);
jdbc.drivers
DriverManager as the manager of Driver, which is used for the first time in the process (that is, when it is first used in code), it is loaded into memory and then executes its defined static code snippet, in the static code snippet, there is a Loadinitialdrivers () static method, used to load the driver driver configured within the Jdbc.drivers system properties, the driver driver configured in Jdbc.drivers will be loaded first:
static {loadinitialdrivers ();//Load the driver driverprintln configured in the jdbc.drivers system variable ("JDBC drivermanager initialized"); 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;} Omit part of the code ... if ((str1 = = null) | | (Str1.equals (""))) Return string[] arrayOfString1 = Str1.split (":");p rintln ("Number of Drivers:" + arrayofstring1.length); for (String Str2:arrayo FString1) try {//class.forname loads the corresponding driverclass.forname (STR2, True, Classloader.getsystemclassloader ());} catch ( Exception localException2) {println ("DriverManager.Initialize:load failed:" + LocalException2);}}
Here's how to load the drive driver via Jdbc.drivers:
String url = "Jdbc:oracle:thin:@127.0.0.1:1521:xe";//Set Value system variable Jdbc.driversSystem.setProperty ("Jdbc.drivers", " Oracle.jdbc.driver.OracleDriver ")//2. Get Driverdriver Driver = drivermanager.getdriver (URL) through a specific URL;// Print whether there is System.out.println (driver);
Remember: Be sure to set jdbc.drivers before you first use drivermanager because static static code snippets in DriverManager will only be executed One time!
--------------------------------------------------------------------------------------------------------------- ----------------------------------------------
The above is the same as the following : the JDBC Series < driver loading principle of comprehensive analysis > all content, above is their own experience, not authority, if there is inappropriate or this error, welcome readers criticism and treatise! Welcome to my next blog post: The <JDBC hierarchy and basic composition of the JDBC series >