• Java的jdbc中 DriverManager.registerDriver(driver); //注册驱动 有没有必要写的思考


    加载数据库驱动的时候,有如下部分代码:

    1          //1) 注册驱动程序
    2          //给java.sql.Driver接口的引用赋值 com.mysql.jdbc.Driver 实现类对象
    3          Driver driver = new com.mysql.jdbc.Driver();
    4          DriverManager.registerDriver(driver);   //注册驱动

    先到数据库驱动包看下这个Driver类:

    可以看到这个类里面有个static语句块,这里先来复习以下,什么时候会加载static语句块,有如下情况:

     当一个类被主动使用时,Java虚拟就会对其初始化,类初始化的时候,就会执行静态代码。如下六种情况为主动使用:

    1. 当创建某个类的新实例时(如通过new或者反射,克隆,反序列化等)

    2. 当调用某个类的静态方法时

    3. 当使用某个类或接口的静态字段时

    4. 当调用Java API中的某些反射方法时,比如类Class中的方法,或者java.lang.reflect中的类的方法时

    5. 当初始化某个子类时

    6. 当虚拟机启动某个被标明为启动类的类(即包含main方法的那个类)

    Java编译器会收集所有的类变量初始化语句和类型的静态初始化器,将这些放到一个特殊的方法中:clinit。

     特别要注意的是:使用final修饰的静态字段,在调用的时候不会对类进行初始化!以及类被加载了不一定就会执行静态代码块,只有一个类被主动使用的时候,静态代码才会被执行

    那么回到原来的问题,在创建Driver这个对象的时候:

    Driver driver = new com.mysql.jdbc.Driver();

    必然会执行其内的static语句块的,其static语句块的作用就和:

    DriverManager.registerDriver(driver); 

    这段代码的作用是一样的,所以有必要再写一次这行代码吗?

    我试着删除了这行代码,发现还是能顺利连接到数据库。

    查找了一些资料,找到了计算driver数量的方法,如下所示:

     1 public class jbdctest01 {
     2     public static void main(String[] args) throws ClassNotFoundException, SQLException {
     3         //1) 注册驱动程序
     4         //给java.sql.Driver接口的引用赋值 com.mysql.jdbc.Driver 实现类对象
     5 //          Driver driver = new com.mysql.jdbc.Driver();
     6 //          DriverManager.registerDriver(driver);   //注册驱动
     7         //注册驱动也可以使用Class.forName()创建Class对象时,会执行类的静态代码块, 在com.mysql.jdbc.Driver类的静态代码块中,注册驱动
     8         Class.forName("com.mysql.jdbc.Driver");
     9         //2)在当前程序与 数据库服务器建立连接
    10 //        Connection connection = DriverManager.getConnection("jdbc:mysql://数据库服务器IP地址:MySQL服务的端口号/数据库名", "登录服务器的用户名", "登录密码");
    11         Enumeration<Driver> drivers = DriverManager.getDrivers();
    12 
    13         int nums = 0;
    14         //使用while循环来遍历驱动的个数
    15         while(drivers.hasMoreElements()) {
    16             nums ++;
    17             //打印出驱动
    18             System.out.println(drivers.nextElement());
    19         }
    20         //打印出驱动个数
    21         System.out.println("驱动个数:" + nums);
    22   }
    23 }

    测试结果如图所示:

    用反射的方法加载驱动,驱动数为一个,这是意料之中的事情,在创建Driver这个对象时,会执行static中的代码块,因此会加载驱动,且数量为1

    接下来测试,另外一种方法,代码如下:

     1 public class jbdctest01 {
     2     public static void main(String[] args) throws ClassNotFoundException, SQLException {
     3         //1) 注册驱动程序
     4         //给java.sql.Driver接口的引用赋值 com.mysql.jdbc.Driver 实现类对象
     5             Driver driver = new com.mysql.jdbc.Driver();
     6             DriverManager.registerDriver(driver);   //注册驱动
     7         //注册驱动也可以使用Class.forName()创建Class对象时,会执行类的静态代码块, 在com.mysql.jdbc.Driver类的静态代码块中,注册驱动
     8        //Class.forName("com.mysql.jdbc.Driver");
     9         //2)在当前程序与 数据库服务器建立连接
    10 //        Connection connection = DriverManager.getConnection("jdbc:mysql://数据库服务器IP地址:MySQL服务的端口号/数据库名", "登录服务器的用户名", "登录密码");
    11         Enumeration<Driver> drivers = DriverManager.getDrivers();
    12 
    13         int nums = 0;
    14         //使用while循环来遍历驱动的个数
    15         while(drivers.hasMoreElements()) {
    16             nums ++;
    17             //打印出驱动
    18             System.out.println(drivers.nextElement());
    19         }
    20         //打印出驱动个数
    21         System.out.println("驱动个数:" + nums);
    22   }
    23 }

    测试结果如图所示:

     

    可以看到结果是2

    接下来注释掉:DriverManager.registerDriver(driver); 这行代码,可以看到输出结果:

    可以看到驱动个数为1个,说明了DriverManager.registerDriver(driver);这行代码可以去掉,如果加上,就会出现了两个驱动,因为在创建Driver这个对象的时候,其内的static语句块会自动执行了。

    另外还有一个小的疑问,就是一个对象执行的时候,是先创建类还是先执行其内的静态方法呢?我特意写了一个程序试了一下:

     1 public class Teststatic {
     2     public  Teststatic(){
     3         System.out.println("看看谁先被执行");
     4 
     5     }
     6     static {
     7         System.out.println("我被执行了,哈哈哈");
     8     }
     9 }
    10  class  T {
    11     public static void main(String[] args) {
    12         Teststatic a = new Teststatic();
    13 
    14     }
    15 }

    运行结果如下:

    说明static语句块比构造方法执行的要早,我记得也是这样的。那么,我就有了一个疑问,因为Driver中的static,要用到Driver的实现类,如果先执行static语句块的话,不会抛出异常吗?因为这个时候Driver的实现类还没创建好啊

    这里我犯了一个错误,就是误认为构造方法执行完毕之后类才被创建,其实不是的,执行构造方法只是为了给类初始化,在执行构造方法只能类已经加载完毕,可以理解为类已经创建好了,所以是不会报错的。

    加载数据库驱动推荐使用反射机制来创建Driver驱动的方式。

  • 相关阅读:
    动态归划之不同路径走法之和
    【转】在ADO.NET中使用参数化SQL语句的大同小异
    asp.net C#如何实现验证码不区分大小写
    用C# + SqlServer2005 实现的treeview动态树形菜单
    捕捉用户的输入,用回车提交
    【转载】在一个aspx或ashx页面里进行多次ajax调用
    【转】在ashx页面中context.Session["xxx"]获取不到值的解决办法
    【转载】【很不错的文章,值得一看】实现小数据量和海量数据的通用分页显示存储过程
    【原创】纯javascript实现银行卡号的Luhn验证或校验算法
    Sql
  • 原文地址:https://www.cnblogs.com/ljfsmile0613/p/12916480.html
Copyright © 2020-2023  润新知