(1). 概述
在这里,主要剖析:DriverManager.getConnection(“jdbc:calcite:”, info)方法的内部实现.
(2). DriverManager.getConnection
public static Connection getConnection(
String url,
java.util.Properties info) throws SQLException {
// 1. 委托给了另一个方法
// Reflection.getCallerClass() 获得当前调用Class
return (getConnection(url, info, Reflection.getCallerClass()));
} // end getConnection
private static Connection getConnection(
String url,
java.util.Properties info,
// org.apache.calcite.test.CsvTest2.class
Class<?> caller) throws SQLException {
// ... ...
// 2. 获得当前类(org.apache.calcite.test.CsvTest2.class)的ClassLoader
ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
// 这里的:registeredDrivers为上一章节所说的Driver容器.
for(DriverInfo aDriver : registeredDrivers) {
// 3. 通过:org.apache.calcite.test.CsvTest2类的ClassLoader尝试加载:Driver
// 如果,能加载到,返回:true
// 如果,不能加载,返回:false
// 如果,连ClassLoader都不能加载,就不能谈能调用:Driver的方法了.
if(isDriverAllowed(aDriver.driver, callerCL)) {
try {
println("trying " + aDriver.driver.getClass().getName());
// 4. 创建连接
Connection con = aDriver.driver.connect(url, info);
if (con != null) {
println("getConnection returning " + aDriver.driver.getClass().getName());
return (con);
}
} catch (SQLException ex) {
if (reason == null) {
reason = ex;
}
}
} else {
println(" skipping: " + aDriver.getClass().getName());
}
}// end for
}
(3). org.apache.calcite.jdbc.Driver
public abstract class UnregisteredDriver implements java.sql.Driver {
final DriverVersion version;
protected final AvaticaFactory factory;
public final Handler handler;
public Connection connect(
// jdbc:calcite:
String url,
// { model = "/model.json" }
Properties info) throws SQLException {
// 判断url是否支持的URL
if (!acceptsURL(url)) {
return null;
}
//
final String prefix = getConnectStringPrefix();
assert url.startsWith(prefix);
final String urlSuffix = url.substring(prefix.length());
final Properties info2 = ConnectStringParser.parse(urlSuffix, info);
// ********************************************************
// 通过AvaticaJdbc41Factory工厂,创建连接.
// connection在Drvier的构造器时,初始化的.
// ********************************************************
final AvaticaConnection connection = factory.newConnection(this, factory, url, info2);
handler.onConnectionInit(connection);
return connection;
} //end connect
}
(4). AvaticaJdbc41Factory.newConnection
public AvaticaConnection newConnection(
UnregisteredDriver driver,
AvaticaFactory factory,
String url,
Properties info) {
// 创建了:AvaticaJdbc41Connection(是java.sql.Connection的实现)包裹:Driver/AvaticaFactory/url/{ model = "/model.json" }
return new AvaticaJdbc41Connection(driver, factory, url, info);
}
(5). 我们看下Calcite相关的UML图
Calcite对Driver/Connection/PreparedStatement,ResulSet 进行了自己的实现.
(6). 总结
- 当我们调用:DriverManager.getConnection时,DriverManager内部有一个Drvier容器,会判断,当前类(XXXMapper/XXXTest)的ClassLoader能否加载:Driver,如果能加载,就通过这个Driver做处理.
- 委托给:AvaticaJdbc41Factory类,去创建一个:java.sql.Connection的实现类(AvaticaJdbc41Connection).
- 我们仍然没有分析到:Calcite是如何分析SQL的,还需要继往下分析.