JDBC设计分析(以MySQL为示例数据库)

研究JDBC架构下,如何与数据库协调工作(以MySQL为例)

JDBC如何连接数据库

只需要Class.forName一句话即可完成Mysql数据库驱动加载。
(jdk1.6以后,无需这句话即可加载驱动,jdbc通过SPI机制完成机制,后面会简单介绍)

Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection(...)

JDBC(SQL)类图

在这里插入图片描述

JDBC加载数据库驱动的时序图

在这里插入图片描述

获取数据库连接的时序图

在这里插入图片描述

分析

JDBC让用户能够利用类加载(Class.forName), 一句话来完成数据库的记载,同时通过java.sql.Driver和java.sql.Connection规定的数据库和连接的行为。理解了JDBC的实现方式,有利于我们自己的程序架构的设计。

SPI(Service Provider Interface)

  • @since 1.6
    ServiceLoader
    从jdk1.6引入的ServiceLoader, 可以自动完成实现了指定Inteface的类的加载。DriverManager利用了该设计,从而让jdk1.6以后的数据库驱动加载完全自动化。用户代码只需要DriverMananger.getConnection就可以得到数据库连接。
    关键代码如下:
java.sql.DriverManager
    /*
     * Load the initial JDBC drivers by checking the System property
     * jdbc.drivers and then use the {@code ServiceLoader} mechanism
     */
    private static void ensureDriversInitialized() {
    ...
    // If the driver is packaged as a Service Provider, load it.
            // Get all the drivers through the classloader
            // exposed as a java.sql.Driver.class service.
            // ServiceLoader.load() replaces the sun.misc.Providers()

            AccessController.doPrivileged(new PrivilegedAction<Void>() {
                public Void run() {

                    ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);
                    Iterator<Driver> driversIterator = loadedDrivers.iterator();

                    /* 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 java.util.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 (driversIterator.hasNext()) {
                            driversIterator.next(); // 会加载实现了java.sql.Driver的MySQL的类,从而完成数据库驱动的安装
                        }
                    } catch (Throwable t) {
                        // Do nothing
                    }
                    return null;
                }
            });

SPI的java.sql.Driver服务接口的全限定类名:
mysql-connector-java-5.1.49.jar\META-INF\services\java.sql.Driver
文件内容

com.mysql.jdbc.Driver
com.mysql.fabric.jdbc.FabricMySQLDriver

因此,上述两个类会自动加载,实现数据库驱动的安装。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值