再說(shuō)JDBC
Jun 07, 2016 pm 03:59 PM上篇文章《再說(shuō)Java EE》說(shuō)明了一下什么是規(guī)范,有什么作用,這篇文章來(lái)細(xì)說(shuō)一下JDBC。 JDBC JDBC(Java Database Connection)也是Java EE中的一個(gè)規(guī)范,所謂規(guī)范是一組接口,如JDBC接口包含在java.sql及javax.sql包中,其中java.sql屬于JavaSE,javax.sql
上篇文章《再說(shuō)Java EE》說(shuō)明了一下什么是規(guī)范,有什么作用,這篇文章來(lái)細(xì)說(shuō)一下JDBC。
JDBC
JDBC(Java Database Connection)也是Java EE中的一個(gè)規(guī)范,所謂規(guī)范是一組接口,如JDBC接口包含在java.sql及javax.sql包中,其中java.sql屬于JavaSE,javax.sql屬于JavaEE,部分如下圖:
以上來(lái)自jdk中的src/java/sql。
因?yàn)樘岢嫦蚪涌诰幊?,所以建議僅使用JDBC規(guī)范中的類(lèi),規(guī)范與實(shí)現(xiàn)的關(guān)系如下:
使用
核心API
JDBC中核心的API有: DriverManager:工廠(chǎng)類(lèi),用來(lái)生產(chǎn)Driver對(duì)象Driver:驅(qū)動(dòng)程序?qū)ο蟮慕涌贑onnection:數(shù)據(jù)庫(kù)連接對(duì)象Statement:執(zhí)行靜態(tài)的SQL語(yǔ)句的接口Resultset:結(jié)果集對(duì)象的接口操作流程
加載數(shù)據(jù)庫(kù)驅(qū)動(dòng)創(chuàng)建數(shù)據(jù)庫(kù)連接執(zhí)行SQL語(yǔ)句,得到結(jié)果集對(duì)結(jié)果集進(jìn)行CRUD處理釋放資源如圖:
源碼分析
java.sql下有48個(gè)類(lèi),javax.sql下有45個(gè)類(lèi),展開(kāi)分析不太現(xiàn)實(shí),本文僅分析兩個(gè)類(lèi),DriverManager和Driver。不知大家注意過(guò)這個(gè)問(wèn)題沒(méi)有,JDBC是接口,數(shù)據(jù)庫(kù)驅(qū)動(dòng)是實(shí)現(xiàn),那么你編寫(xiě)的項(xiàng)目是如何找到實(shí)現(xiàn)的呢?
控制臺(tái)輸出
為了可以看到驅(qū)動(dòng)加載過(guò)程中輸出的日志,在加載驅(qū)動(dòng)Class.forName("com.mysql.jdbc.Driver")之前,加上一句:
DriverManager.setLogWriter(new java.io.PrintWriter(System.out));即可在控制臺(tái)中看到輸出。
加載驅(qū)動(dòng)
驅(qū)動(dòng)使用很簡(jiǎn)單,將數(shù)據(jù)庫(kù)驅(qū)動(dòng)放到項(xiàng)目的lib中,在代碼中寫(xiě)入:
Class.forName("com.mysql.jdbc.Driver");如果使用框架,如Hebernate配置文件中寫(xiě)入:
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>很明顯,這兩種方式都是使用反射加載驅(qū)動(dòng)程序,我們來(lái)看一下驅(qū)動(dòng)程序Driver的源代碼,以mysql-connector-java-3.1.13為例:
package com.mysql.jdbc; import java.sql.SQLException; public class Driver extends NonRegisteringDriver implements java.sql.Driver { // // Register ourselves with the DriverManager // static { try { java.sql.DriverManager.registerDriver(new Driver()); } catch (SQLException E) { throw new RuntimeException("Can't register driver!"); } } /** * Construct a new driver and register it with DriverManager * @throws SQLException * if a database error occurs. */ public Driver() throws SQLException { // Required for Class.forName().newInstance() } }核心代碼就是那段靜態(tài)代碼塊(static{}的意思是在類(lèi)加載時(shí)執(zhí)行一次,并且僅此一次),可以看到靜態(tài)代碼斷的意思是將此Driver類(lèi)實(shí)例化后注冊(cè)到JDBC的java.sql.DriverManager類(lèi)中,所以再來(lái)看一下JDBC的DriverManager.registerDriver:
/** * Registers the given driver with the <code>DriverManager</code>. * A newly-loaded driver class should call * the method <code>registerDriver</code> to make itself * known to the <code>DriverManager</code>. * * @param driver the new JDBC Driver that is to be registered with the * <code>DriverManager</code> * @exception SQLException if a database access error occurs */ public static synchronized void registerDriver(java.sql.Driver driver) throws SQLException { if (!initialized) { initialize(); } DriverInfo di = new DriverInfo(); di.driver = driver; di.driverClass = driver.getClass(); di.driverClassName = di.driverClass.getName(); // Not Required -- drivers.addElement(di); writeDrivers.addElement(di); println("registerDriver: " + di); /* update the read copy of drivers vector */ readDrivers = (java.util.Vector) writeDrivers.clone(); }即可將com.mysql.jdbc.Driver添加到DriverManager的成員變量readDrivers中,以后獲取數(shù)據(jù)庫(kù)連接需要這個(gè)變量的幫助。
看上面的代碼發(fā)現(xiàn),還調(diào)用了initialize(),查看initialize()的源碼看到它調(diào)用loadInitialDrivers(),這個(gè)函數(shù)的主要作用是加載JDBC默認(rèn)驅(qū)動(dòng),registerDriver執(zhí)行完,控制臺(tái)的輸出語(yǔ)句為:
JdbcOdbcDriver class loaded registerDriver: driver[className=sun.jdbc.odbc.JdbcOdbcDriver,sun.jdbc.odbc.JdbcOdbcDriver@134e4fb] DriverManager.initialize: jdbc.drivers = null JDBC DriverManager initialized registerDriver: driver[className=com.mysql.jdbc.Driver,com.mysql.jdbc.Driver@157c2bd]可以看到先加載JdbcOdbcDriver,再加載我們加入的MySQL的driver。
獲取鏈接
加載驅(qū)動(dòng)完畢后,如何獲取連接,繼續(xù)看DriverManager的getConnection():// Worker method called by the public getConnection() methods. private static Connection getConnection( String url, java.util.Properties info, ClassLoader callerCL) throws SQLException { java.util.Vector drivers = null; /* * When callerCl is null, we should check the application's * (which is invoking this class indirectly) * classloader, so that the JDBC driver class outside rt.jar * can be loaded from here. */ synchronized(DriverManager.class) { // synchronize loading of the correct classloader. if(callerCL == null) { callerCL = Thread.currentThread().getContextClassLoader(); } } if(url == null) { throw new SQLException("The url cannot be null", "08001"); } println("DriverManager.getConnection(\"" + url + "\")"); if (!initialized) { initialize(); } synchronized (DriverManager.class){ // use the readcopy of drivers drivers = readDrivers; } // Walk through the loaded drivers attempting to make a connection. // Remember the first exception that gets raised so we can reraise it. SQLException reason = null; for (int i = 0; i < drivers.size(); i++) { DriverInfo di = (DriverInfo)drivers.elementAt(i); // If the caller does not have permission to load the driver then // skip it. if ( getCallerClass(callerCL, di.driverClassName ) != di.driverClass ) { println(" skipping: " + di); continue; } try { println(" trying " + di); Connection result = di.driver.connect(url, info); if (result != null) { // Success! println("getConnection returning " + di); return (result); } } catch (SQLException ex) { if (reason == null) { reason = ex; } } } // if we got here nobody could connect. if (reason != null) { println("getConnection failed: " + reason); throw reason; } println("getConnection: no suitable driver found for "+ url); throw new SQLException("No suitable driver found for "+ url, "08001"); }這個(gè)函數(shù)代碼比較多,但是我們關(guān)注的核心代碼就一句:
Connection result = di.driver.connect(url, info);
其中di就是我們前面加載驅(qū)動(dòng)后DriverManager的成員變量readDrivers包含的一個(gè)對(duì)象,也就是調(diào)用com.mysql.jdbc.driver的connect函數(shù),但是從上面該類(lèi)代碼可知,它只包含一個(gè)構(gòu)造函數(shù)和靜態(tài)代碼段,connect函數(shù)從何而來(lái)?
別忘了com.mysql.jdbc.driver繼承自NonRegisteringDriver,這也是MySQL驅(qū)動(dòng)下的一個(gè)類(lèi),進(jìn)入該類(lèi),找到connect函數(shù):
package com.mysql.jdbc; /***省略引用和注釋***/ public class NonRegisteringDriver implements java.sql.Driver { /***省略其他函數(shù)和注釋***/ public java.sql.Connection connect(String url, Properties info) throws SQLException { Properties props = null; if ((props = parseURL(url, info)) == null) { return null; } try { Connection newConn = new com.mysql.jdbc.Connection(host(props), port(props), props, database(props), url, this); return newConn; } catch (SQLException sqlEx) { // Don't wrap SQLExceptions, throw // them un-changed. throw sqlEx; } catch (Exception ex) { throw new SQLException(Messages .getString("NonRegisteringDriver.17") //$NON-NLS-1$ + ex.toString() + Messages.getString("NonRegisteringDriver.18"), //$NON-NLS-1$ SQLError.SQL_STATE_UNABLE_TO_CONNECT_TO_DATASOURCE); } } }
因?yàn)镹onRegisteringDriver也是java.sql.Driver的實(shí)現(xiàn),返回的也是JDBC中Connection的實(shí)現(xiàn),所以如上面向接口編程,即可從DriverManager中得到MySQL的Connection。
總結(jié)
JDBC的分析介紹到此結(jié)束,如果有興趣大家可以看一下其他數(shù)據(jù)庫(kù)驅(qū)動(dòng)的源碼,因?yàn)槎际歉鶕?jù)JDBC而來(lái),所以大都大同小異。

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

After Java8-291, TLS1.1 is disabled, so that JDBC cannot connect to SqlServer2008 using SSL. What should I do? The following is the solution to modify the java.security file 1. Find the java.security file of jre. If it is jre, go to {JAVA_HOME}/jre/ In lib/security, for example????C:\ProgramFiles\Java\jre1.8.0_301\lib\security. If it is the Eclipse green installation-free portable version, search for java.security in the installation folder, such as????xxx\plugins \org

1. How can you make money by publishing articles on Toutiao today? How to earn more income by publishing articles on Toutiao today! 1. Activate basic rights and interests: original articles can earn profits by advertising, and videos must be original in horizontal screen mode to earn profits. 2. Activate the rights of 100 fans: if the number of fans reaches 100 fans or above, you can get profits from micro headlines, original Q&A creation and Q&A. 3. Insist on original works: Original works include articles, micro headlines, questions, etc., and are required to be more than 300 words. Please note that if illegally plagiarized works are published as original works, credit points will be deducted, and even any profits will be deducted. 4. Verticality: When writing articles in professional fields, you cannot write articles across fields at will. You will not get appropriate recommendations, you will not be able to achieve the professionalism and refinement of your work, and it will be difficult to attract fans and readers. 5. Activity: high activity,

With the widespread application of Java, JDBC errors often occur when Java programs connect to databases. JDBC (JavaDatabaseConnectivity) is a programming interface in Java used to connect to a database. Therefore, a JDBC error is an error encountered when a Java program interacts with a database. Here are some of the most common JDBC errors and how to solve and avoid them. ClassNotFoundException This is the most common JDBC

1. Prerequisites for database programming Programming languages, such as Java, C, C++, Python and other databases, such as Oracle, MySQL, SQLServer and other database driver packages: Different databases provide different database driver packages corresponding to different programming languages. For example: MySQL provides the Java driver package mysql-connector-java, which is required to operate MySQL based on Java. Similarly, to operate Oracle database based on Java, Oracle's database driver package ojdbc is required. 2. Java database programming: JDBCJDBC, JavaDatabaseConnectiv

1. Explain that in JDBC, the executeBatch method can execute multiple dml statements in batches, and the efficiency is much higher than executing executeUpdate individually. What is the principle? How to implement batch execution in mysql and oracle? This article will introduce to you the principle behind this. 2. Experiment introduction This experiment will be carried out through the following three steps: a. Record the time consuming of jdbc batch execution and single execution in mysql; b. Record the time consuming of jdbc batch execution and single execution in oracle; c. Record the batch execution and single execution of oracleplsql. The execution time-consuming related java and database versions are as follows: Java17, Mysql8, Oracle

In recent years, the application of Java language has become more and more widespread, and JDBCAPI is a creative method for Java applications to interact with databases. JDBC is based on an open database connection standard called ODBC, which enables Java applications to connect to any database. management system (DBMS). Among them, MySQL is a popular database management system. However, developers will also encounter some common problems when connecting to MySQL databases. This article aims to introduce the JDBCAPI connection M

In this article, we will learn how to add articles in HTML5. One of the new segmentation elements in HTML5 is the tag. Articles are represented in HTML using tags. More specifically, the content contained within the element is different from the rest of the site's content (even though they may be related). Let us consider the following example to understand how to add an article in HTML5 Example 1 In the following example, we are using inline styles in the article element. <!DOCTYPEhtml><html><body><articlestyle="width:300px;border:2pxsolidgray;padding:

Differences between Hibernate and JDBC: Abstraction level: Hibernate provides high-level object mapping and query generation, while JDBC requires manual coding. Object-relational mapping: Hibernate maps Java objects and database tables, while JDBC does not provide this functionality. Query generation: Hibernate uses HQL to simplify query generation, while JDBC requires writing complex SQL queries. Transaction management: Hibernate automatically manages transactions, while JDBC requires manual management.
