美文网首页程序员
JAVA加载数据库驱动(JDBC)

JAVA加载数据库驱动(JDBC)

作者: 风雪乐雨 | 来源:发表于2016-12-18 11:47 被阅读0次

    JAVA加载数据库驱动(JDBC)

    前言

    之前,对Class.forName("com.mysql.jdbc.Driver");这条动态加载JDBC驱动感觉很疑惑,故有了这篇短文。

    一、使用JDBC连接MySQL

    首先,来看一下正常使用Java操纵MySql的简单代码逻辑。

        public static boolean connectionMySqlDemo() {
            Connection conn = null;
            try {
                // 1、动态加载mysql驱动
                Class.forName("com.mysql.jdbc.Driver"); 
                // 2、连接数据库
                conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?"
                        + "user=root&password=1234&useUnicode=true&characterEncoding=UTF8");
                // 3、声明一个Statement 用来执行sql语句
                Statement stmt = conn.createStatement();
                
                // 4、执行sql语句
                stmt.executeUpdate("create table student(no_id char(20),name varchar(20),primary key(no_id))");
                int result = stmt.executeUpdate("insert into student(no_id,name) values('1','fxleyu')");
                if (result > 0) {
                    ResultSet rs = stmt.executeQuery("select * from student");
                    while (rs.next()) {
                        System.out.println(rs.getString(1));
                    }
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                // 5、关闭数据库
                if (conn != null) {
                    try {
                        conn.close();
                        return true;
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }
    
            return false;
        }
    

    在上述代码中,动态加载数据库驱动那条语句感觉独立于其余代码逻辑。感觉缺少其并无关系(当然缺少了会在链接数据库时报java.sql.SQLException: No suitable driver found for)。

    二、疑惑

    上述代码很容易理解,除了如下Class.forName("com.mysql.jdbc.Driver");。正常理解,该语句只是加载把com.mysql.jdbc.Driver加载到JVM中,没不会产生特殊作用。
    阅读com.mysql.jdbc.Driver代码,可以发现其中的隐含逻辑。

    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()
        }
    }
    
    

    原来该类中有静态代码库,其加载到JVM时,会执行该静态代码库。而该代码块会把该类的对象实例自注册到DriverManager中。如此第一部分中的第二步就很容易理解了。

    // 2、连接数据库
    conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?"
            + "user=root&password=1234&useUnicode=true&characterEncoding=UTF8");
    

    其就是可以根据String来获得上述加载的驱动,从而可以正常访问数据库。

    三、余以为

    代码的逻辑很重要,而Class.forName("com.mysql.jdbc.Driver");单独来看只是一条孤立的语句。没有和上下文代码产生显示的关联,这就导致了余在前言中的疑惑。故,使用Class.forName("com.mysql.jdbc.Driver");来动态注册驱动,会对当前代码逻辑产生不利影响。

    正常的逻辑,Class.forName方法就是加载一个指定类,并对该类做一些初始化工作(使用静态代码库),其不应该做一些其它逻辑,例如动态注册驱动。如果需要注册驱动时,应该让用户自己使用DriverManager.registerDriver(new com.mysql.jdbc.Driver());来显示注册。这样代码逻辑会很清晰。

    但在这里使用显示注册并不合适。因为当new com.mysql.jdbc.Driver()的动作中,就有类的加载过程。在该过程中,已经把该驱动加载到了DriverManager的列表中。而有显示的注册了一次,故DriverManager的列表会有两个com.mysql.jdbc.Driver实例。也就是说,MySql的jdbc并不适合用来进行显示加载。

    当然,也许使用Class.forName("com.mysql.jdbc.Driver");有MySql团队自己的考虑,而我当前视野并没有看到其好处。

    四、结束

    Talk is cheap, show me the code. 当对某些代码逻辑有疑问时,不妨查看一下相关源码,就会豁然开朗。自勉。P.S. 第三部分的余以为灵感借鉴于“余晟以为”微信公众号,很喜欢他那句“我是这么以为的,当然你也可以那么以为”。

    参考

    1、使用源码下载路径 http://101.96.8.142/dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.40.tar.gz

    相关文章

      网友评论

        本文标题:JAVA加载数据库驱动(JDBC)

        本文链接:https://www.haomeiwen.com/subject/nygamttx.html