`
Donald_Draper
  • 浏览: 980106 次
社区版块
存档分类
最新评论

JDBC驱动初始化-Mysql

    博客分类:
  • JDBC
阅读更多
JDBC驱动初始化-Mysql:http://donald-draper.iteye.com/blog/2342010
JDBC连接的获取:http://donald-draper.iteye.com/blog/2342011
Mysql负载均衡连接的获取:http://donald-draper.iteye.com/blog/2342089
Mysql主从复制读写分离连接的获取:http://donald-draper.iteye.com/blog/2342108
ConnectionImp创建MysqlIO :http://donald-draper.iteye.com/blog/2342959
Mysql预编译SQL:http://donald-draper.iteye.com/blog/2342960
MysqlSQL PreparedStatement的查询:http://donald-draper.iteye.com/blog/2343083
MySQL ServerPreparedStatement查询:http://donald-draper.iteye.com/blog/2343124
用hibernate和mybatis做持久层时候,屏蔽jdbc的东西,现在有时间,我们来看一下jdbc底层东西。
首先创建mysql测试实例如下;
测试实例:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.Date;
public class testMysqlX {
	public static void main(String[] args){
		testMysqlConnection();
	}
	@SuppressWarnings("deprecation")
	public static void testMysqlConnection()
	{
	    Connection con = null;// 创建一个数据库连接
	    PreparedStatement pre = null;// 创建预编译语句对象,一般都是用这个而不用Statement
	    ResultSet result = null;// 创建一个结果集对象
	    try
	    {
	        Class.forName("com.mysql.jdbc.Driver");// 加载驱动程序
	        System.out.println("开始尝试连接数据库!");
	        String url = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8";
			String user = "root";// 用户名,系统默认的账户名
			String password = "123456";// 你安装时选设置的密码	
	        long startTime = System.currentTimeMillis();
	        con = DriverManager.getConnection(url, user, password);// 获取连接
	        PreparedStatement ps = con.prepareStatement("select count(*) from ?"); 
	        ps.setString(1, "user");
	        result = ps.executeQuery();
	        //result 初始游标为head,移动next到第一个记录
	          while(result.next()){
		         int sum = result.getInt(1);
	        	 System.out.println("============sum:"+sum);
	         }
	        long endTime = System.currentTimeMillis();
	 
	        System.out.println("============time:"+ (endTime-startTime));
	        System.out.println("============hashCode:"+ con.hashCode());
	        if(!con.isClosed()){
	        	 System.out.println("============连接成功!");
	        }
	    }
	    catch (Exception e)
	    {
	    	System.out.println("=============连接失败:"+e.getMessage());
	    	e.printStackTrace();
	    }
	    finally
	    {
	        try
	        {
	            // 逐一将上面的几个对象关闭,因为不关闭的话会影响性能、并且占用资源
	            // 注意关闭的顺序,最后使用的最先关闭
	            if (result != null)
	                result.close();
	            if (pre != null)
	                pre.close();
	            if (con != null)
	                con.close();
	            System.out.println("数据库连接已关闭!");  
	        }
	        catch (Exception e)
	        {
	            e.printStackTrace();
	        }
	    }
	}
}


下面我们来看一下,从驱动加载,获取连接,及获取PreparedStatement,执行查询,结果集的处理的整个过程;
先看加载驱动
从这一句开始:
 Class.forName("com.mysql.jdbc.Driver");

//Class
 public final
    class Class<T> implements java.io.Serializable, 
			      java.lang.reflect.GenericDeclaration, 
			      java.lang.reflect.Type,
                              java.lang.reflect.AnnotatedElement {
    private static final int ANNOTATION= 0x00002000;
    private static final int ENUM      = 0x00004000;
    private static final int SYNTHETIC = 0x00001000;

    private static native void registerNatives();
    static {
        registerNatives();
    }
//根据类名加载对应class
   public static Class<?> forName(String className) 
                throws ClassNotFoundException {
        return forName0(className, true, ClassLoader.getCallerClassLoader());
    }
 /** Called after security checks have been made. */
    private static native Class forName0(String name, boolean initialize,
					    ClassLoader loader)
	throws ClassNotFoundException;
}

来看一下的mysql的Driver类
//com.mysql.jdbc.Driver 
 public class Driver extends NonRegisteringDriver
    implements java.sql.Driver
{
    public Driver()
        throws SQLException
    {
    }
    static 
    {
        try
        {
	    //将驱动注册到驱动管理器
            DriverManager.registerDriver(new Driver());
        }
        catch(SQLException E)
        {
            throw new RuntimeException("Can't register driver!");
        }
    }
}

//DriverManager
public class DriverManager {
    /* write copy of the drivers vector */
    private static java.util.Vector writeDrivers = new java.util.Vector();

    /* write copy of the drivers vector */
    private static java.util.Vector readDrivers = new java.util.Vector();

    private static int loginTimeout = 0;
    private static java.io.PrintWriter logWriter = null;
    private static java.io.PrintStream logStream = null;
    private static boolean initialized = false;
        //注册驱动
	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();

        //将driver信息添加到writeDrivers集合中
	writeDrivers.addElement(di); 
	println("registerDriver: " + di);
	//克隆writeDrivers到readDrivers
	readDrivers = (java.util.Vector) writeDrivers.clone();

    }
     //初始化
    static void initialize() {
        if (initialized) {
            return;
        }
        initialized = true;
	//加载驱动,初始化
        loadInitialDrivers();
        println("JDBC DriverManager initialized");
    }
    //加载驱动
     private static void loadInitialDrivers() {
        String drivers;
        try {
	    drivers = (String) java.security.AccessController.doPrivileged(
		new sun.security.action.GetPropertyAction("jdbc.drivers"));
        } catch (Exception ex) {
            drivers = null;
        }
	//如果driver是放在jar包中,通过类型加载器加载,所有Driver,每个java.sql.Driver.class是一个Service
	 DriverService ds = new DriverService();

	 //获取所有驱动的访问权限
	 java.security.AccessController.doPrivileged(ds);		
	        
         println("DriverManager.initialize: jdbc.drivers = " + drivers);
        if (drivers == null) {
            return;
        }
        while (drivers.length() != 0) {
            int x = drivers.indexOf(':');
            String driver;
            if (x < 0) {
                driver = drivers;
                drivers = "";
            } else {
                driver = drivers.substring(0, x);
                drivers = drivers.substring(x+1);
            }
            if (driver.length() == 0) {
                continue;
            }
            try {
                println("DriverManager.Initialize: loading " + driver);
		//加载驱动
                Class.forName(driver, true,
			      ClassLoader.getSystemClassLoader());
            } catch (Exception ex) {
                println("DriverManager.Initialize: load failed: " + ex);
            }
        }
    }
    class DriverService implements java.security.PrivilegedAction {
        Iterator ps = null;
	public DriverService() {};
        public Object run() {

	// uncomment the followin line before mustang integration 	
        // Service s = Service.lookup(java.sql.Driver.class);
	// ps = s.iterator();
        //通过Service加载所有Driver
	ps = Service.providers(java.sql.Driver.class);

	/* Load these drivers, so that they can be instantiated. 
	 * It may be the case that the driver class may not be there
         * i.e. there may be a packaged driver with the service class
         * as implementation of java.sql.Driver but the actual class
         * may be missing. In that case a sun.misc.ServiceConfigurationError
         * will be thrown at runtime by the VM trying to locate 
	 * and load the service.
         * 
	 * Adding a try catch block to catch those runtime errors
         * if driver not available in classpath but it's 
	 * packaged as service and that service is there in classpath.
	 */
		
	try {
           while (ps.hasNext()) {
	       //初始化Driver
               ps.next();
           } // end while
	} catch(Throwable t) {
	    // Do nothing
	}
        return null;
    } //end run

} //end DriverService
    //驱动信息类
    class DriverInfo {
    Driver         driver;
    Class          driverClass;
    String         driverClassName;

    public String toString() {
	return ("driver[className=" + driverClassName + "," + driver + "]");
    }
}

从DriverManager的初始化过程可以看出,Driver的加载是委托给DriverService,而DriverService是通过
Service去加载,我们来看一下Service
public final class Service
{
    //加载驱动,委托给providers(Class class1, ClassLoader classloader)
    public static Iterator providers(Class class1)
        throws ServiceConfigurationError
    {
        ClassLoader classloader = Thread.currentThread().getContextClassLoader();
        return providers(class1, classloader);
    }
    public static Iterator providers(Class class1, ClassLoader classloader)
        throws ServiceConfigurationError
    {
         //实际上返回的为一个Iterater,LazyIterator为Service的静态内部类
        return new LazyIterator(class1, classloader);
    }
    //LazyIterator,懒加载驱动集合
    private static class LazyIterator
        implements Iterator
    {

        public boolean hasNext()
            throws ServiceConfigurationError
        {
            if(nextName != null)
                return true;
            if(configs == null)
                try
                {
                    String s = (new StringBuilder()).append("META-INF/services/").append(service.getName()).toString();
                    if(loader == null)
                        configs = ClassLoader.getSystemResources(s);
                    else
                        configs = loader.getResources(s);
                }
                catch(IOException ioexception)
                {
                    Service.fail(service, (new StringBuilder()).append(": ").append(ioexception).toString());
                }
            for(; pending == null || !pending.hasNext(); pending = Service.parse(service, (URL)configs.nextElement(), returned))
                if(!configs.hasMoreElements())
                    return false;

            nextName = (String)pending.next();
            return true;
        }
        //next函数在DriverService,有调用,通过遍历LazyIterator,加载驱动
        public Object next()
            throws ServiceConfigurationError
        {
            String s;
            Class class1;
            if(!hasNext())
                throw new NoSuchElementException();
            s = nextName;
            nextName = null;
            class1 = null;
            try
            {
                class1 = Class.forName(s, false, loader);
            }
            catch(ClassNotFoundException classnotfoundexception)
            {
                Service.fail(service, (new StringBuilder()).append("Provider ").append(s).append(" not found").toString());
            }
            if(!service.isAssignableFrom(class1))
                Service.fail(service, (new StringBuilder()).append("Provider ").append(s).append(" not a subtype").toString());
            return service.cast(class1.newInstance());
            Throwable throwable;
            throwable;
            Service.fail(service, (new StringBuilder()).append("Provider ").append(s).append(" could not be instantiated: ").append(throwable).toString(), throwable);
            return null;
        }

        public void remove()
        {
            throw new UnsupportedOperationException();
        }

        Class service;
        ClassLoader loader;
        Enumeration configs;
        Iterator pending;
        Set returned;
        String nextName;

        private LazyIterator(Class class1, ClassLoader classloader)
        {
            configs = null;
            pending = null;
            returned = new TreeSet();
            nextName = null;
            service = class1;
            loader = classloader;
        }
	
    private static void fail(Class class1, String s, Throwable throwable)
        throws ServiceConfigurationError
    {
        ServiceConfigurationError serviceconfigurationerror = new ServiceConfigurationError((new StringBuilder()).append(class1.getName()).append(": ").append(s).toString());
        serviceconfigurationerror.initCause(throwable);
        throw serviceconfigurationerror;
    }
    //驱动加载失败的处理,抛出异常
    private static void fail(Class class1, String s)
        throws ServiceConfigurationError
    {
        throw new ServiceConfigurationError((new StringBuilder()).append(class1.getName()).append(": ").append(s).toString());
    }

    private static void fail(Class class1, URL url, int i, String s)
        throws ServiceConfigurationError
    {
        fail(class1, (new StringBuilder()).append(url).append(":").append(i).append(": ").append(s).toString());
    }
}

//ServiceConfigurationError
public class ServiceConfigurationError extends Error
{
    public ServiceConfigurationError(String s)
    {
        super(s);
    }
    public ServiceConfigurationError(Throwable throwable)
    {
        super(throwable);
    }
}

至此,driver的加载结束,我们来回顾一下整个过程,Class加载com.mysql.jdbc.Driver,com.mysql.jdbc.Driver通过静态语句块,将Driver注册到DriverManager,DriverManager首先检查有没有初始化,没有则加载驱动类,整个驱动加载过程是通过DriverService,而DriverService则委托给Service,Service加载驱动是返回的是,所有java.sql.Driver实现的Iterator,Iterator为LazyIterator,
DriverService通过遍历LazyIterator,加载驱动所有驱动;最后将Driver包装成DriverInfo,添加到writeDrivers集合中,并clone到readDrivers。

0
0
分享到:
评论

相关推荐

    mysql8.0.15,安装配套所需的软件及Jdbc驱动jar包

    在给定的文件列表中,虽然没有明确的 JDBC 驱动 jar 包,但在实际应用中,你需要下载并添加 `mysql-connector-java-x.x.x.jar` 到你的 Java 项目的类路径中,这里的 x.x.x 是具体的版本号。 安装步骤通常包括以下几...

    mysql5.0jdbc驱动.rar

    1. 引入JDBC驱动的依赖:在项目中,你需要将驱动的jar文件(如`mysql-connector-java-x.x.x.jar`)添加到类路径中。对于现代构建系统(如Maven或Gradle),可以在相应的配置文件中声明依赖。 2. 加载驱动:使用`...

    mysql的jdbc的驱动程序

    1. **添加驱动依赖**:`mysql-connector-java-5.0.7-bin.jar` 文件是MySQL JDBC驱动的二进制版本,它包含了所有必要的类和库,使得Java程序能够连接到MySQL数据库。在Java项目中,通常将这个JAR文件添加到项目的类...

    servlet--jdbc--mysql.rar

    5. 配置文件:如web.xml,配置Servlet的映射和初始化参数,包括JDBC连接池的配置。 6. HTML/JavaScript页面:前端页面,可能包含分页链接,触发Ajax请求,与Servlet进行交互。 这个项目对初学者和开发者来说很有...

    mysql-connector-java-5.1.35 MySQL的jdbc驱动jar

    MySQL的jdbc驱动jar,如"mysql-connector-java-5.1.35",是连接Java应用程序与MySQL数据库的关键组件。这个驱动程序遵循Java Database Connectivity (JDBC) API规范,使得Java开发者能够通过编写Java代码来执行SQL...

    JDBC驱动加载分析

    - **静态初始化块**:对于JDBC驱动来说,通常在驱动类中包含一个静态初始化块。在类被加载时,静态初始化块会被执行。在这个例子中,`JdbcOdbcDriver`类可能包含了必要的静态初始化逻辑,比如注册驱动到`...

    JDBC连接MySQL驱动

    这个方法会加载并初始化指定的类,确保JDBC驱动已准备就绪。 3. **建立连接**:注册完驱动后,你可以使用`java.sql.DriverManager`类的`getConnection()`方法创建到MySQL数据库的连接。需要提供数据库URL、用户名...

    mysql驱动包 mysql-connector-java-5.1.7-bin.jar

    这通常通过`Class.forName()`方法完成,比如`Class.forName("com.mysql.jdbc.Driver")`,这会加载并初始化对应的驱动类。 5. 数据库连接:连接MySQL数据库使用`java.sql.DriverManager.getConnection()`方法,传入...

    MySQL驱动jar包(mysql-connector-java)

    `mysql-connector-java`是MySQL官方提供的JDBC驱动,符合JDBC规范,使得Java程序可以无缝连接到MySQL数据库。 2. **版本兼容性**:`mysql-connector-java-5.4.40.jar`是特定版本的驱动,5.4系列适用于MySQL 5.x到8....

    mysqlJDBC驱动包和连接程序

    连接池预先初始化并维护一定数量的数据库连接,当需要连接时,可以从池中获取,用完后归还,而不是每次建立和关闭新的连接。这样可以减少连接创建和销毁的开销,提高系统性能。 总结来说,MySQL JDBC驱动包和连接...

    mysql-jdbc驱动

    1. **mysql-connector-java-5.1.8-bin.jar**:这是MySQL官方提供的JDBC驱动程序,版本为5.1.8。这个JAR文件包含了所有必要的类和资源,使得Java应用程序能够连接到MySQL服务器并执行SQL命令。例如,你可以使用`...

    dolphinscheduler安装包和mysql的jdbc连接jar包

    3. 添加JDBC驱动:将`mysql-connector-java-5.1.47-bin.jar`复制到DolphinScheduler的lib目录下,使其成为系统的类路径一部分。 4. 初始化数据库:使用DolphinScheduler提供的SQL脚本对数据库进行初始化,创建必要...

    java-mysql jdbc

    1. **加载驱动**:首先,我们需要在程序中加载MySQL的JDBC驱动。这通常通过`Class.forName()`方法完成,指定驱动类名,例如`com.mysql.cj.jdbc.Driver`。 2. **创建连接**:加载驱动后,使用`DriverManager.get...

    jdbc驱动类包

    这会触发驱动的静态初始化,从而注册到JDBC驱动管理器。 - 从Java 6开始,可以使用服务提供者接口(SPI)自动加载驱动,无需显式调用`Class.forName()`。 3. **建立数据库连接** - 使用`DriverManager.get...

    mysql分库分表-mysql-sharding-jdbc.zip

    `mysql-sharding-jdbc` 是一个用于 MySQL 数据库分片的 Java 框架,它提供了 JDBC 驱动接口,使得开发者可以方便地在应用层进行分库分表操作。 一、MySQL 分库分表原理 1. 分库:将一个大型数据库拆分为多个小型...

    oracle-mysql-sqlservice jar驱动

    使用时,开发者需要按照特定的配置方式初始化连接池服务,并通过服务接口获取和释放数据库连接。 总的来说,`oracle-mysql-sqlservice jar驱动` 是一个集成多种数据库驱动的服务,它简化了在Java项目中同时处理...

    jsp中jdbc驱动程序

    这一步会确保驱动类被初始化。 2. **建立连接**:通过`DriverManager.getConnection()`方法建立到数据库的连接,需要提供URL、用户名和密码,如:`Connection conn = DriverManager.getConnection("jdbc:mysql://...

    注册Jdbc驱动程序的三种方式

    对于JDBC驱动来说,这个初始化块通常会包含对`java.sql.Driver`接口的实现类的实例化。例如,如果我们使用MySQL的JDBC驱动,代码可能如下所示: ```java try { Class.forName("com.mysql.jdbc.Driver"); } catch ...

    mysql-connector-java-8.0.20.jar

    JDBC驱动程序是Java平台上的一个接口,它定义了如何在Java代码中创建、提交和管理SQL语句。`mysql-connector-java-8.0.20.jar`是MySQL Connector/J的特定版本,它实现了这些JDBC接口,使得Java开发者可以方便地在...

    JDBC-Drivers

    MySQL的JDBC驱动通常称为`mysql-connector-java.jar`,它允许Java应用程序与MySQL数据库进行通信。该驱动支持多种认证方式,如标准的用户名/密码认证、SSL加密连接以及使用Connector/J的MySQL Native Password认证...

Global site tag (gtag.js) - Google Analytics