一文快速入門分庫分表中介軟體 Sharding-JDBC (必修課)
Attempts to establish a connection with the data source that * this {@code DataSource} object represents. * @return a connection to the data source */ Connection getConnection() throws SQLException; /** *
Attempts to establish a connection with the data source that
* this {@code DataSource} object represents.
* @param username the database user on whose behalf the connection is
* being made
* @param password the user's password
*/
Connection getConnection(String username, String password)
throws SQLException;
}
```
其中 `CommonDataSource` 是定義資料來源的根介面這很好理解,而 `Wrapper` 介面則是拓展 JDBC 分片功能的關鍵。
由於資料庫廠商的不同,他們可能會各自提供一些超越標準 JDBC API 的擴充套件功能,但這些功能非 JDBC 標準並不能直接使用,而 `Wrapper` 介面的作用就是把一個由第三方供應商提供的、非 JDBC 標準的介面包裝成標準介面,也就是`介面卡模式`。
既然講到了介面卡模式就多囉嗦幾句,也方便後邊的理解。
>介面卡模式個種比較常用的設計模式,它的作用是將某個類的介面轉換成客戶端期望的另一個介面,使原本因介面不匹配(或者不相容)而無法在一起工作的兩個類能夠在一起工作。
比如用耳機聽音樂,我有個圓頭的耳機,可手機插孔卻是扁口的,如果我想要使用耳機聽音樂就必須藉助一個轉接頭才可以,這個轉接頭就起到了適配作用。
舉個栗子:假如我們 `Target` 介面中有 `hello()` 和 `word()` 兩個方法。
```javascript
public interface Target {
void hello();
void world();
}
```
可由於介面版本迭代`Target` 介面的 `word()` 方法可能會被廢棄掉或不被支援,`Adaptee` 類的 `greet()`方法將代替`hello()` 方法。
```javascript
public class Adaptee {
public void greet(){
}
public void world(){
}
}
```
但此時舊版本仍然有大量 `word()` 方法被使用中,解決此事最好的辦法就是建立一個介面卡`Adapter`,這樣就適配了 `Target` 類,解決了介面升級帶來的相容性問題。
```javascript
public class Adapter extends Adaptee implements Target {
@Override
public void world() {
}
@Override
public void hello() {
super.greet();
}
@Override
public void greet() {
}
}
```
而 `Sharding-JDBC` 提供的正是非 JDBC 標準的介面,所以它也提供了類似的實現方案,也使用到了 `Wrapper` 介面做資料分片功能的適配。除了 DataSource 之外,Connection、Statement、ResultSet 等核心物件也都繼承了這個介面。
下面我們通過 `ShardingDataSource` 類原始碼簡單看下實現過程,下圖是繼承關係流程圖。
![ShardingDataSource實現流程](https://img-blog.csdnimg.cn/20201021211025155.png?#pic_center)
`ShardingDataSource` 類它在原 `DataSource` 基礎上做了功能拓展,初始化時註冊了分片SQL路由包裝器、SQL重寫上下文和結果集處理引擎,還對資料來源型別做了校驗,因為它要同時支援多個不同型別的資料來源。到這好像也沒看出如何適配,那接著向上看 `ShardingDataSource ` 的繼承類 `AbstractDataSourceAdapter ` 。
```javascript
@Getter
public class ShardingDataSource extends AbstractDataSourceAdapter {
private final ShardingRuntimeContext runtimeContext;
/**
* 註冊路由、SQl重寫上下文、結果集處理引擎
*/
static {
NewInstanceServiceLoader.register(RouteDecorator.class);
NewInstanceServiceLoader.register(SQLRewriteContextDecorator.class);
NewInstanceServiceLoader.register(ResultProcessEngine.class);
}
/**
* 初始化時校驗資料來源型別 並根據資料來源 map、分片規則、資料庫型別得到一個分片上下文,用來獲取資料庫連線
*/
public ShardingDataSource(final Map