JDBC模型—深入理解JDBC设计思想(探究Class.forName("DBDriver"))

写在前面:笔者上篇文章《JDBC要点总结、SQL注入示例(Statement和PreparedStatement)》中提到过,JDBC是sun公司制定的一系列接口标准,由不同厂商(Oracle、MySQL等)实现接口方法并封装成驱动文件,供开发人员操作数据库。开发者可通过统一的代码操作不同类型数据库,那么如何实现这种统一操作呢?本篇深入JDBC设计思想,用示例代码模拟整个JDBC运行原理。

背景知识:

1.JVM(Java虚拟机)将系统分配的内存区域分为三块(堆区、栈区、方法区)

2.类的加载:当使用new 关键字新建一个对象,或使用Class.forName()加载指定类时,虚拟机读取类(.class)的字节码文件并加载到方法区。<由类加载器完成>

3.类在加载时,静态成员会被执行,包括静态成员被赋值,静态代码块被执行

补充:任何堆区的Java对象都有一个指针指向方法区中的class对象(每个类只有一个),即方法区共享了类的方法。

如以下代码段:

Student s1 = new Student("张三");

s1.study();

Student s2 = new Student("李四");

s2.study();

程序执行流程:

1.程序经过编译后,.java文件转换成字节码.class文件

2.执行Student s1 = new Student(“张三”);时:

    a.JVM读取Student类的字节码文件并加载到方法区,生成class对象;

    b.然后在堆区开辟内存区域初始化Student(“张三”)对象,该对象有一个指针指向方法区中的class对象;

    c.在栈区分配一个变量s1,s1指向堆区Student(“张三”)对象的首地址;

3.执行s1.study();时,JVM通过堆区s1对象指向方法区的指针,找到class对象的方法并执行

4.执行Student s2 = new Student(“李四”);时,不会再加载并生成class对象(再次强调:同一个类只有一个class对象在方法区),但在堆区和栈区的操作同s1一样

图示如下:

《JDBC模型—深入理解JDBC设计思想(探究Class.forName(

接下来,我们来看看JDBC是如何实现对数据库的统一操作的

实现步骤:

1.sun公司制定标准接口

2.数据库厂商实现标准接口,并封装在定制的驱动文件中

3.开发者通过各厂商驱动文件对不同数据库操作

设计思想关键词:接口、类加载器、静态代码块

设计描述:

1.sun公司制定接口标准:Connection接口和DriverManager类(Connection接口提供操作数据库的抽象方法,待数据库厂商实现;DriverManager类提供给数据库厂商注册连接和获取连接的方法) 。

2.数据库厂商实现Connection接口中的方法(用来定义具体的数据库操作)

3.数据库厂商自定义驱动文件Driver类,将2中的连接注册到SUN提供的DriverManager中(此过程在静态代码块中,确保类被加载时即可执行)

4.程序员通过Class.for(“”);加载驱动文件,并获取连接,进而对数据库进行操作

示意图:

《JDBC模型—深入理解JDBC设计思想(探究Class.forName(

SUN公司

首先,SUN公司定义了一个接口类:

/**
 * @Description:sun公司定义的接口类
 *
 * @author:SUN
 */
public interface Connection {

	public void f1();
}

同时,SUN公司定义了一个驱动管理类:

/**
 * @Description:SUN公司定义的驱动管理类
 *
 * @author:SUN
 */
public class DriverManager {

    public static Connection conn = null;

    /**
     * 注册连接
     *
     * @param connection
     */
    public static void registConnection(Connection connection) {
        conn = connection;
    }

    /**
     * 获取连接
     *
     * @return
     */
    public static Connection getConnection() {
        return conn;
    }
}

数据库厂商:(如Oracle、MySQL等)

各数据库厂商实现SUN制定的接口标准,如:

Oracle

/**
 * @Description:Oracle数据库厂商实现的接口类
 *
 * @author:Oracle
 */
public class ConnectionOracleImpl implements Connection {

	@Override
	public void f1() {
		// 这里实现Oracle操作数据库的具体方法,封装在.jar文件中,供程序员调用
		System.out.println("Oracle的f1()方法实现");
	}

}

或者MySQL

/**
 * @Description:MySQL数据库厂商实现的接口类
 *
 * @author:MySQL
 */
public class ConnectionMySQLImpl implements Connection {

    @Override
    public void f1() {
        //这里实现MySQL操作数据库的具体方法,封装在.jar文件中,供程序员调用
        System.out.println("MySQL的f1()方法实现");
    }

}

同时,数据库厂商定制自己的驱动类,并通过静态代码块,确保该驱动类被加载时,SUN的驱动管理类可以注册厂商的数据库连接,如:

Oracle

/**
 * @Description:Oracle厂商制定的驱动类
 *
 * @author:Oracle
 */
public class OracleDriver {
	static {
		DriverManager.registConnection(new ConnectionOracleImpl());
	}
}

或者MySQL

/**
 * @Description:MySQL厂商制定的驱动类
 *
 * @author:MySQL
 */
public class MySQLDriver {
	static {
		DriverManager.registConnection(new ConnectionMySQLImpl());
	}
}

开发者:

开发人员引入某个数据库厂商的驱动文件,即可调用内部方法操作数据库,如:

/**
 * @Description:开发人员
 *
 * @author:me
 */
public class Test2 {

	public static void main(String[] args) throws Exception {
		Class.forName("test.OracleDriver");// 虚拟机根据类名找到字节码文件
		Connection con = DriverManager.getConnection();
		con.f1();

		Class.forName("test.MySQLDriver");// 虚拟机根据类名找到字节码文件
		Connection con2 = DriverManager.getConnection();
		con2.f1();
	}
}

运行结果:

Oracle的f1()方法实现
MySQL的f1()方法实现

转载请注明出处:

http://blog.csdn.net/daijin888888/article/details/50969621

    原文作者:mysql
    原文地址: https://blog.csdn.net/daijin888888/article/details/50969621
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞