您的位置:首页 > 数据库

JDBC注册过程分析

2014-12-12 17:35 302 查看
本博客要记录的是如何去使用JDBC去操作数据库的一般过程。

JDBC操作步骤如下:

1.注册驱动

2.建立连接

3.创建语句对象

4.执行语句

5.处理结果集

6.关闭资源

看如下代码:

package Base;

import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.mysql.jdbc.Connection;
import com.mysql.jdbc.Statement;

public class BaseDriver {

public static void Test() throws SQLException{
//注册驱动
DriverManager.registerDriver(new com.mysql.jdbc.Driver());

//建立连接
Connection conn = (Connection) DriverManager.getConnection("", "root","password01!");

//创建语句
Statement stm = (Statement) conn.createStatement();

//执行语句,获取结果
ResultSet resultSet = stm.executeQuery("select * from t_user");

//遍历结果集
while(resultSet.next()){
System.out.println(resultSet.getObject(0)+"\t"+resultSet.getObject(1)+"\t"+resultSet.getObject(2)+"\t"+resultSet.getObject(3));
}

//释放资源
resultSet.close();
stm.close();
conn.close();

}
}
1.注册驱动

注册驱动的方式有两种:

a.DriverManager进行注册

DriverManager.registerDriver(new com.mysql.jdbc.Driver());
b.使用Class进行注册

Class.forName("com.mysql.jdbc.Driver");

注册驱动过程到底做了什么事情呢?听我慢慢道来:
a方式注册驱动主要做了如下工作:

首先我们先来看一下DriverManager的源代码:

public class DriverManager {

// List of registered JDBC drivers
private final static CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<>();
private static volatile int loginTimeout = 0;
private static volatile java.io.PrintWriter logWriter = null;
private static volatile java.io.PrintStream logStream = null;
// Used in println() to synchronize logWriter
private final static  Object logSync = new Object();

}
上面是通过反编译出来的DriverManager类的部分代码

private final static CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<>();把驱动注册在一个列表里面。有了数据库的驱动包后,在调用getConnection后,就会在这个驱动注册列表里面去一个一个的找,看是否能够建立连接,如果最后没有找到,那么就会抛出异常。

b.方式注册驱动做了哪些工作:

同样我们也来看一下源代码:

/**
* Returns the {@code Class} object associated with the class or
* interface with the given string name.  Invoking this method is
* equivalent to:
*
* <blockquote>
*  {@code Class.forName(className, true, currentLoader)}
* </blockquote>
*
* where {@code currentLoader} denotes the defining class loader of
* the current class.
*
* <p> For example, the following code fragment returns the
* runtime {@code Class} descriptor for the class named
* {@code java.lang.Thread}:
*
* <blockquote>
*   {@code Class t = Class.forName("java.lang.Thread")}
* </blockquote>
* <p>
* A call to {@code forName("X")} causes the class named
* {@code X} to be initialized.
*
* @param      className   the fully qualified name of the desired class.
* @return     the {@code Class} object for the class with the
*             specified name.
* @exception LinkageError if the linkage fails
* @exception ExceptionInInitializerError if the initialization provoked
*            by this method fails
* @exception ClassNotFoundException if the class cannot be located
*/
@CallerSensitive
public static Class<?> forName(String className)
throws ClassNotFoundException {
return forName0(className, true,
ClassLoader.getClassLoader(Reflection.getCallerClass()));
}
根据上面的反编译出来的Class源代码重的ForName的源代码,也是加载在一个驱动列表中,通过遍历驱动列表进行检测是否有符合目标的驱动注册,如果没有则抛出异常。

区别:

DriverManager.registerDriver(new com.mysql.jdbc.Driver());会在JVM装载类时调用静态代码初始化块,new com.mysql.jdbc.Driver()同时会实例化一个驱动实例,所以这种方式会在驱动注册列表中出现两个相同的MySql的驱动注册项。
Class.forName("com.mysql.jdbc.Driver");因为forName的参数是字符串类型,在加载类时只会调用静态代码块创建一个实例,驱动注册表中只有一个MySql的驱动注册项。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息