sharding-jdbc的源碼分析一

路由的輸入與執(zhí)行

ShardingPreparedStatement的route()方法如下,routingEngine在構(gòu)造時(shí)會(huì)傳入需要路由的sql字符串以及對(duì)應(yīng)的Connection關(guān)聯(lián)的ShardingContext(一個(gè)javaBean),在執(zhí)行路由的時(shí)候栏笆,route()方法會(huì)傳入setParameter獲得的參數(shù)僧鲁,根據(jù)參數(shù)、參數(shù)值以及SQL進(jìn)行路由分析產(chǎn)生執(zhí)行單元PreparedStatementUnit列表奈懒,之后將PreparedStatementUnit列表傳到谷歌的Excutor框架去對(duì)里面路由后的各個(gè)SQL通過PreparedStatement執(zhí)行屯阀。
這里的getParameters()實(shí)際上獲取的是父類的屬性,在父類已經(jīng)定義了捅伤,父類是AbstractShardingPreparedStatementAdapter抽象類劫流,再通過幾層關(guān)系實(shí)現(xiàn)了PreparedStatement的接口,ShardingPreparedStatement通過子類繼承的方式封裝并實(shí)現(xiàn)了PreparedStatement接口規(guī)范丛忆,實(shí)現(xiàn)了excuteQuery等方法祠汇,ShardingPreparedStatement的創(chuàng)建在ShardingConnection里進(jìn)行創(chuàng)建

 private Collection<PreparedStatementUnit> route() throws SQLException {
        Collection<PreparedStatementUnit> result = new LinkedList<>();
        routeResult = routingEngine.route(getParameters());
        for (SQLExecutionUnit each : routeResult.getExecutionUnits()) {
            SQLType sqlType = routeResult.getSqlStatement().getType();
            Collection<PreparedStatement> preparedStatements;
            if (SQLType.DDL == sqlType) {
                preparedStatements = generatePreparedStatementForDDL(each);
            } else {
                preparedStatements = Collections.singletonList(generatePreparedStatement(each));
            }
            routedStatements.addAll(preparedStatements);
            for (PreparedStatement preparedStatement : preparedStatements) {
                replaySetParameter(preparedStatement);
                result.add(new PreparedStatementUnit(each, preparedStatement));
            }
        }
        return result;
    }
    public ShardingPreparedStatement(final ShardingConnection connection, final String sql, final int resultSetType, final int resultSetConcurrency, final int resultSetHoldability) {
        this.connection = connection;
        this.resultSetType = resultSetType;
        this.resultSetConcurrency = resultSetConcurrency;
        this.resultSetHoldability = resultSetHoldability;
        routingEngine = new PreparedStatementRoutingEngine(sql, connection.getShardingContext());
    }

SQL的解析到路由的解析到SQL的執(zhí)行

從ShardingPreparedStatement的route()方法跟進(jìn)下去,可以發(fā)現(xiàn)路由解析的過程是在PreparedStatementRoutingEngine里面蘸际,PreparedStatementRoutingEngine是上面說到的routingEngine的具體實(shí)現(xiàn)座哩,在構(gòu)造他的時(shí)候徒扶,他獲取了sql字符串和Connection連接關(guān)聯(lián)的ShardingContext(一個(gè)javaBean)粮彤,在調(diào)用route()的時(shí)候獲取了PreparedStatement的參數(shù),因此路由解析的參數(shù)的三個(gè)輸入就確定了下來姜骡;PreparedStatementRoutingEngine里面有三個(gè)屬性以及一個(gè)方法导坟,看到這里,基本上可以確定路由算法就是在SQLRouter接口的實(shí)現(xiàn)類實(shí)現(xiàn)的圈澈,從構(gòu)造方法里面跟進(jìn)去可以發(fā)現(xiàn)SQLRouter的實(shí)現(xiàn)類在2.0版本有兩個(gè)惫周,一個(gè)是DatabaseHintSQLRouter,一個(gè)是ParsingSQLRouter康栈,他們都實(shí)現(xiàn)了SQLRouter的parse和route方法递递,parse解析的結(jié)果封裝在SQLStatement接口,route的結(jié)果封裝在SQLRouteResult(一個(gè)Bean)啥么。DMLStatement繼承AbstractSQLStatement從而實(shí)現(xiàn)SQLStatement接口登舞,DMLStatement根據(jù)SQL的類型派生了例如InsertStatement、updateStatement等子類(alter悬荣、create菠秒、drop、insert氯迂、select践叠、truncate、update)嚼蚀。
實(shí)際上這里的SQLStatement命名應(yīng)該是參考了mysql-connector包里面的禁灼。從下面的代碼 route(final List<Object> parameters)我們也可以知道,sqlStatement封裝的是SQL解析后的結(jié)果轿曙,sqlRouter利用了該結(jié)果去對(duì)SQL進(jìn)行路由弄捕,封裝成SQLRouteResult哮独,最后SQL的執(zhí)行就是利用了SQLRouteResult里面的信息,sqlRouter里面方法的執(zhí)行順序是先parse后route。

public final class PreparedStatementRoutingEngine {
    
    private final String logicSQL;
    
    private final SQLRouter sqlRouter;
    
    private SQLStatement sqlStatement;
    
    public PreparedStatementRoutingEngine(final String logicSQL, final ShardingContext shardingContext) {
        this.logicSQL = logicSQL;
        sqlRouter = SQLRouterFactory.createSQLRouter(shardingContext);
    }
    
    /**
     * SQL route.
     * 
     * <p>First routing time will parse SQL, after second time will reuse first parsed result.</p>
     * 
     * @param parameters parameters of SQL placeholder
     * @return route result
     */
    public SQLRouteResult route(final List<Object> parameters) {
        if (null == sqlStatement) {
            sqlStatement = sqlRouter.parse(logicSQL, parameters.size());
        }
        return sqlRouter.route(logicSQL, parameters, sqlStatement);
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末察藐,一起剝皮案震驚了整個(gè)濱河市皮璧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌分飞,老刑警劉巖悴务,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異譬猫,居然都是意外死亡讯檐,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門染服,熙熙樓的掌柜王于貴愁眉苦臉地迎上來别洪,“玉大人,你說我怎么就攤上這事柳刮⊥诙猓” “怎么了?”我有些...
    開封第一講書人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵秉颗,是天一觀的道長(zhǎng)痢毒。 經(jīng)常有香客問我,道長(zhǎng)蚕甥,這世上最難降的妖魔是什么哪替? 我笑而不...
    開封第一講書人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮菇怀,結(jié)果婚禮上凭舶,老公的妹妹穿的比我還像新娘。我一直安慰自己爱沟,他們只是感情好帅霜,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著钥顽,像睡著了一般义屏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蜂大,一...
    開封第一講書人閱讀 49,821評(píng)論 1 290
  • 那天闽铐,我揣著相機(jī)與錄音,去河邊找鬼奶浦。 笑死兄墅,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的澳叉。 我是一名探鬼主播隙咸,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼沐悦,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了五督?” 一聲冷哼從身側(cè)響起藏否,我...
    開封第一講書人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎充包,沒想到半個(gè)月后副签,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡基矮,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年淆储,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片家浇。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡本砰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出钢悲,到底是詐尸還是另有隱情点额,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布譬巫,位于F島的核電站咖楣,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏芦昔。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一娃肿、第九天 我趴在偏房一處隱蔽的房頂上張望咕缎。 院中可真熱鬧,春花似錦料扰、人聲如沸凭豪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)嫂伞。三九已至,卻和暖如春拯钻,著一層夾襖步出監(jiān)牢的瞬間帖努,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工粪般, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拼余,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓亩歹,卻偏偏與公主長(zhǎng)得像匙监,于是被迫代替她去往敵國(guó)和親凡橱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容

  • 關(guān)于Mongodb的全面總結(jié) MongoDB的內(nèi)部構(gòu)造《MongoDB The Definitive Guide》...
    中v中閱讀 31,912評(píng)論 2 89
  • 首先去官網(wǎng)下載python3.5直接安裝亭姥,安裝完畢后自帶pip可以在命令行中使用python查看版本稼钩,pip -V...
    曉函閱讀 407評(píng)論 0 0
  • 第一份工作是在廣告公司做策劃專員变抽。這一行,每一天都風(fēng)起云涌氮块,變幻莫測(cè)绍载。折射在日常的工作中就成了臨下班前布置的任務(wù)、...
    是閃閃發(fā)光的曉宇宙閱讀 414評(píng)論 5 4
  • 她穿上新買的羽絨服 笑著 在原地轉(zhuǎn)了一個(gè)圈 輕盈地 張開的手臂旋起來像花朵 我裹在 落了塵灰的舊大衣里 看著她 想...
    江山宜喚酒閱讀 320評(píng)論 0 0