https://www.programcreek.com/java-api-examples/?code=loye168/tddl5/tddl5-master/tddl-group
https://github.com/ninqing/hermes/wiki/Tddl_Rulejava
本例是用apply_no爲分表分庫鍵node
mybatis中:git
mapper.xml文件中的方法先被mybatis先處理: # 轉爲佔位符 ?, $ 則是直接注入值, 再被TDDL來處理。
通過驗證: 必定要是「APPLY_NO=${applyNo}」這樣的寫法!github
int insertBatch(@Param("applyNo") String applyNo, @Param("list")List<DecisionExecNode> list);
<insert id="insertBatch" parameterType="java.util.List" > /*+TDDL({type:'condition',params:[{"paramtype":"long","expr":["APPLY_NO=${applyNo}"]}],vtab:'decision_exec_node'})*/ insert into decision_exec_node ( id, apply_no, case_no, product_code ) values <foreach collection="list" item="item" separator=","> ( #{item.id,jdbcType=BIGINT}, #{item.applyNo,jdbcType=VARCHAR}, #{item.caseNo,jdbcType=VARCHAR}, #{item.productCode,jdbcType=VARCHAR} ) </foreach> </insert>
在tddl-client 3.3.2.4 中的 SimpleHintParser 最末端有個測試用例, 對於使用格式在此類中處理! sql
在網上找到一些關於SimpleHintParser的使用事例: https://www.programcreek.com/java-api-examples/?api=com.taobao.tddl.optimizer.parse.hint.SimpleHintParser。沒試過每個用例,權當解決問題的一種思路。數據庫
具體能夠關注SimpleHintParser.convertHint2RouteCondition方法中的入參StartInfo對象的屬性sql和sqlParam 在不一樣hint寫法下構建tddlHint是有區別的。會取第一個param來注入api
分表規則:
如下的方法是: SimpleHintParser.decodeComparativemybatis
這種會直接按字符串「#applyNo#」進行路由分表,致使數據分表不一致!!
app
這種會直接按取第一個佔位符指定的參數值來填充。 但比較奇怪的是拿不到傳入的「applyNo」, 只會拿到「List」對象裏的第一個param 填充(applyNo像被丟了同樣,推測是由於在mapper文件方法體內並無對其進行直接使用,mybatis解析時會過濾多餘的屬性值), 致使最後因填充參數不足插入失敗測試
這種原本應該是最接近真相的方式,這種方式能夠讀取到額外傳入的「applyNo」 的屬性值, 但比較奇怪的是在SimpleHintParser處理時調用的HintParserHelper.extractHint方法會斷定這個參數是不是「setString」, 會給真實值先後加入了單引號! 這個致使VirtualTableRuleMatcher.findMatchedRule的入參map值與正常處理情景下的不一致! 最終致使會在WrappedGroovyRule執行eval方法路由的時候異常!
最終獲得的對象是:
但正常狀況下應該是:
異常時的入參倒是:
那能不能直接傳遞hashCode進去呢? 最後驗證發現然並軟。。分表規則是先轉成String再hash, 仍是不行。。
根據推測: mybatis對於「#」會轉爲佔位符,那直接在拼接sql的時候拼入分庫分表鍵值,跳過SimpleHintParser中對String類型參數的額外補單引號動做!
這下正常了:
GroovyRule
在TPreparedStatementImp執行executeQuery(其餘方法相似)時,經過buildSqlExecutionContextUsePipeline來獲取真實的group信息。
咱們來看TGroupPreparedStatement執行的executeQuery(其餘方法相似):會經過TConnection獲取真實的TGroupConnection。
此時將經過GroupHintParser來處理sql獲取指定的GroupIndex
這個GroupIndex用在AbstractDBSelector的tryExecute方法中選擇當前Group下匹配的DataSourceHolder
處理鏈路handler