mycat分片插入二次开发(基于1.6.5版本)

改造方向:

1. 支持oracle分片批量插入

    由于mycat分片批量插入的语法限定为 insert into values (),(),该批量插入语法oracle不支持。 

    目前的想法是将确定分片后的sql改造成insert into select xxx from dual union all select xxx from dual的格式以同时支持mysql和oralce两种数据库。

    改造点:

    DruidInsertParser.java

    1. 增加函数convertIntoSql

    /**
     * 将传入的values组转换成select xx from dual union all select xx from dual的格式
     *
     * @param valuesList
     * @return
     */
    private static SQLSelectQuery convertIntoSql(List valuesList) {
        StringBuilder unionSql = new StringBuilder();
        for (SQLInsertStatement.ValuesClause valuesClause : valuesList) {
            StringBuilder subSQL = new StringBuilder("select ");
            for (SQLExpr sqlExpr : valuesClause.getValues()) {
                if (sqlExpr instanceof SQLCharExpr) {
                    subSQL.append("'" + ((SQLCharExpr) sqlExpr).getText() + "', ");
                } else if (sqlExpr instanceof SQLIntegerExpr) {
                    subSQL.append(((SQLIntegerExpr) sqlExpr).getNumber() + ", ");
                }
            }
            subSQL.deleteCharAt(subSQL.length() - 2).append("from dual");
            unionSql.append(subSQL.toString() + " union all ");
        }
        SQLStatementParser sqlStatementParser = new SQLStatementParser(unionSql.substring(0, unionSql.length() - 10).trim());
        SQLSelectStatement statement = (SQLSelectStatement) sqlStatementParser.parseStatement();
        return statement.getSelect().getQuery();
    }

2. 修改parserBatchInsert函数,在sql分流完成后拦截改造sql

                for (Map.Entry> node : nodeValuesMap.entrySet()) {
                    Integer nodeIndex = node.getKey();
                    //获取节点values值并进行sql转换
                    List valuesList = node.getValue();
                    insertStmt.setQuery(new SQLSelect(convertIntoSql(valuesList)));
                    //清除values值
                    insertStmt.setValuesList(new ArrayList());
                    nodes[count] = new RouteResultsetNode(tableConfig.getDataNodes().get(nodeIndex),
                            rrs.getSqlType(), insertStmt.toString());
                    if (algorithm instanceof SlotFunction) {
                        nodes[count].setSlot(slotsMap.get(nodeIndex));
                        nodes[count].setStatement(ParseUtil.changeInsertAddSlot(nodes[count].getStatement(), nodes[count].getSlot()));
                    }
                    nodes[count++].setSource(rrs);

                }

你可能感兴趣的:(mycat)