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