MyCAT与Hibernate的兼容问题
最近在做卡券项目,由于交易量巨大,所以上 MyCAT 作为MySQL的中间件来解决多库和分表的问题。
由于使用PlayFramework内置了Hibernate,所以先硬着头皮上,结果发现bug了。
Bug
下面是示例语句
SELECT
orders0_.id AS id1_5_,
orders0_.merchant_id AS merchant6_5_,
orders0_.num AS num7_5_,
orders0_.order_no AS order_no8_5_
FROM orders orders0_
WHERE orders0_.merchant_id = 'HsPSlXcm37rkzMNHti4'
AND orders0_.mch_order_no = '20170717163649132'
LIMIT 1
解析后分发到全部节点的语句变成了
SELECT
orders0_.id AS id1_5_,
orders0_.merchant_id AS merchant6_5_,
orders0_.num AS num7_5_,
orders0_.order_no AS order_no8_5_
FROM orders_1
WHERE orders0_.merchant_id = 'HsPSlXcm37rkzMNHti4'
AND orders0_.mch_order_no = '20170717163649132'
LIMIT 10000
结果发现,from
后面漏了orders0_
这个alias。
解决
最后通过修改MyCAT代码解决:
//io.mycat.route.parser.druid.impl.DruidSelectParser
//more code ...
if(rrs.isDistTable()){
SQLTableSource from = mysqlSelectQuery.getFrom();
for (RouteResultsetNode node : rrs.getNodes()) {
SQLIdentifierExpr sqlIdentifierExpr = new SQLIdentifierExpr();
sqlIdentifierExpr.setParent(from);
sqlIdentifierExpr.setName(node.getSubTableName());
//这句漏传了一个参数,导致alias丢失
//SQLExprTableSource from2 = new SQLExprTableSource(sqlIdentifierExpr);
//更正为下面语句即可
SQLExprTableSource from2 = new SQLExprTableSource(sqlIdentifierExpr, from.getAlias());
mysqlSelectQuery.setFrom(from2);
node.setStatement(stmt.toString());
}
}
希望官方早日合并PR: https://github.com/MyCATApache/Mycat-Server/issues/1577