美文网首页
JDBC之桥接模式

JDBC之桥接模式

作者: Responsibility_ | 来源:发表于2020-08-05 08:53 被阅读0次

    先说说桥接模式,桥接模式的特点是将实现和抽象进行分离,进行解耦。
    抽象实现分离,使它们可以独立变化。它是用组合/聚合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。

    桥接模式的基本结构

    • Abstraction — 抽象化角色:
      定义抽象的接口,包含一个对实现化角色的引用

    • Refined Abstraciotn — 扩展抽象化角色:
      抽象化角色的子类,实现父类中的业务方法,并通过组合/聚合关系调用实现化角色中的业务方法

    • Implementor — 实现化角色:
      定义具体行为、具体特征的应用接口,供扩展抽象化角色使用

    • Concrete Implemetor — 具体实现化角色:
      实现化角色的具体实现

    实例一:模拟毛笔

    现需要提供大中小3种型号的画笔,能够绘制5种不同颜色,如果使用蜡笔,我们需要准备3*5=15支蜡笔,也就是说必须准备15个具体的蜡笔类。而如果使用毛笔的话,只需要3种型号的毛笔,外加5个颜料盒,用3+5=8个类就可以实现15支蜡笔的功能。本实例使用桥接模式来模拟毛笔的使用过程。


    image.png

    JDBC中的桥接模式

    JDBC中也分为两个维度的变化,一个是:Driver ,一个是Connection.

    源码解析
    Class.forName("com.mysql.cj.jdbc.Driver");
    Connection conn = DriverManager.getConnection("jdbc:mysql://<host>:<port>/<database>");
    

    Class.forName()反射的三种方式之一,返回java.lang.Class对象,用于在程序运行时的某个时刻,由客户端调用,动态加载该类或该接口到当前线程中。
    MySQL源码中:com.mysql.cj.jdbc.Driver类
    com.mysql.cj.jdbc.Driver类仅包含一段静态代码,其中最关键的是静态代码段中的 DriverManager.registerDriver(new Driver()) ,它会在客户端调用Class.forName()方法加载com.mysql.cj.jdbc.Driver类的同时被执行,Driver类自身的一个实例被注册到DriverManager(即保存到DriverManager的静态字段registeredDrivers内)。
    DriverManager类部分源码

    public class DriverManager {
        // List of registered JDBC drivers
        private final static CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<>();
        private static volatile int loginTimeout = 0;
        private static volatile java.io.PrintWriter logWriter = null;
        private static volatile java.io.PrintStream logStream = null;
        // Used in println() to synchronize logWriter
        private final static  Object logSync = new Object();
    

    Class.forName()方法调用后,com.mysql.cj.jdbc.Driver类被加载,并执行static { } 静态代码段,将com.mysql.cj.jdbc.Driver类实例注册到DriverManager中。然后,客户端会调用DriverManager.getConnection()方法获取一个Connection数据库连接实例,该方法的部分源码如下:

     for(DriverInfo aDriver : registeredDrivers) {
               // If the caller does not have permission to load the driver then
               // skip it.
               if(isDriverAllowed(aDriver.driver, callerCL)) {
                   try {
                       println("    trying " + aDriver.driver.getClass().getName());
                       Connection con = aDriver.driver.connect(url, info);
                       if (con != null) {
                           // Success!
                           println("getConnection returning " + aDriver.driver.getClass().getName());
                           return (con);
                       }
                   } catch (SQLException ex) {
                       if (reason == null) {
                           reason = ex;
                       }
                   }
    
               } else {
                   println("    skipping: " + aDriver.getClass().getName());
               }
           }
    

    遍历registeredDrivers 集合,尝试每一个driver和数据库之间的连接,如果全部失败,就抛出异常提示连接失败。

    Connection接口

    DriverManager.getConnection()方法返回的Connection数据库连接实例根据不同的数据库有不同的实现。
    这是变化的第二个维度。


    image.png

    相关文章

      网友评论

          本文标题:JDBC之桥接模式

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