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