JDBC实现
说明
jdbc实现就是桥接模式
关注点在依赖关系的维护。对于jdbc技术来说,它解耦了业务与数据库通信协议这两个纬度之间的关系,所以这两个纬度之间的关系就需要一个桥,即Driver,至于DriverManager把这个关系接到哪里就是运行时的事情了。
微观上,从connection的创建来看,它更像一个抽象工厂模式,特定的Driver创建对应的connection。
宏观上,从业务代码与connection的关系来看,关键点在于一个sql怎么转化为对应的通信协议,就属于桥接。
我们知道不同的数据库自我实现和传输协议不同,java不可能为每种数据库厂商提供其实现,这不符合精简设计的原则,这里java提供了一套统一的接口让各个厂商自己实现,一套接口给程序开发者调用,两者的结合就是经典的桥接模式。
Class.forName("com.mysql.jdbc.Driver");//加载及注册JDBC驱动程序 String url = "jdbc:mysql://localhost:3306/sample_db?user=root&password=your_password"; Connection con = DriverManager.getConnection(url); Statement stmt = con.createStatement(); String query = "select * from test"; ResultSet rs=stmt.executeQuery(query); while(rs.next()) { rs.getString(1); rs.getInt(2); }
如果我们要换oracle数据库只需要换成oracle.jdbc.driver.OracleDriver就行了
com.mysql.jdbc.Driver类
package com.mysql.jdbc; import java.sql.SQLException; public class Driver extends NonRegisteringDriver implements java.sql.Driver { 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() } }
Class.forName会触发Driver类的类加载 执行静态方法 将Driver注册到DriverMnanger供后续使用
DriverManager
public class DriverManager { private final static CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<DriverInfo>(); //... static { loadInitialDrivers(); println("JDBC DriverManager initialized"); } //... public static synchronized void registerDriver(java.sql.Driver driver) throws SQLException { if (driver != null) { registeredDrivers.addIfAbsent(new DriverInfo(driver)); } else { throw new NullPointerException(); } } public static Connection getConnection(String url, String user, String password) throws SQLException { java.util.Properties info = new java.util.Properties(); if (user != null) { info.put("user", user); } if (password != null) { info.put("password", password); } return (getConnection(url, info, Reflection.getCallerClass())); } //... }
后续jdbc操作都会委托个Driver操作
桥接模式理解
将抽象和实现解耦,让它们可以独立变化 这里的抽象不是抽象,而是抽象出来的一套类库, 使抽象和实现可以独立开发,然后通过桥梁组合在一起
不知道理解对不对我认为slf4j就是桥接模式
1.抽象出来的的slf4j类库,具体实现交给各个日志系统实现
2.最终通过桥梁 在在classpath查找 org/slf4j/impl/StaticLoggerBinder.class 获取对应的日志系统的ILoggerFactory