美文网首页fescar
Fescar - RM ExecuteTemplate介绍

Fescar - RM ExecuteTemplate介绍

作者: 晴天哥_王志 | 来源:发表于2019-02-13 16:02 被阅读5次

    开篇

     这篇文章的目的是介绍Fescar的RM模块中的ExecuteTemplate的代码,ExecuteTemplate作为StatementProxy当中真正执行SQL操作的模块,在Proxy和Executor的串联中起到承上启下的作用。

     调用链上按照DataSourceProxy->ConnectionProxy->StatementProxy->Executor的顺序进行。

    ExecuteTemplate源码介绍

    public class StatementProxy<T extends Statement> extends AbstractStatementProxy<T> {
    
        @Override
        public ResultSet executeQuery(String sql) throws SQLException {
            this.targetSQL = sql;
            return ExecuteTemplate.execute(this, new StatementCallback<ResultSet, T>() {
                @Override
                public ResultSet execute(Statement statement, Object... args) 
                 throws SQLException {
                    return statement.executeQuery((String) args[0]);
                }
            }, sql);
        }
    
        @Override
        public int executeUpdate(String sql) throws SQLException {
            this.targetSQL = sql;
            return ExecuteTemplate.execute(this, new StatementCallback<Integer, T>() {
                @Override
                public Integer execute(Statement statement, Object... args) 
                 throws SQLException {
                    return statement.executeUpdate((String) args[0]);
                }
            }, sql);
        }
    }
    

    说明:

    • StatementProxy通过执行executeQuery和executeUpdate执行具体的SQL语句。
    public class ExecuteTemplate {
        public static <T, S extends Statement> T execute(StatementProxy<S> statementProxy,
                                                         StatementCallback<T, S> statementCallback,
                                                         Object... args) throws SQLException {
            return execute(null, statementProxy, statementCallback, args);
        }
    
    
    
        public static <T, S extends Statement> T execute(SQLRecognizer sqlRecognizer,
                                                         StatementProxy<S> statementProxy,
                                                         StatementCallback<T, S> statementCallback,
                                                         Object... args) throws SQLException {
    
            if (!RootContext.inGlobalTransaction()) {
                // Just work as original statement
                return statementCallback.execute(statementProxy.getTargetStatement(), args);
            }
    
            if (sqlRecognizer == null) {
                sqlRecognizer = SQLVisitorFactory.get(
                    statementProxy.getTargetSQL(),
                    statementProxy.getConnectionProxy().getDbType());
            }
            Executor<T> executor = null;
            if (sqlRecognizer == null) {
                executor = new PlainExecutor<T, S>(statementProxy, statementCallback);
            } else {
                switch (sqlRecognizer.getSQLType()) {
                    case INSERT:
                        executor = new InsertExecutor<T, S>(statementProxy, statementCallback, sqlRecognizer);
                        break;
                    case UPDATE:
                        executor = new UpdateExecutor<T, S>(statementProxy, statementCallback, sqlRecognizer);
                        break;
                    case DELETE:
                        executor = new DeleteExecutor<T, S>(statementProxy, statementCallback, sqlRecognizer);
                        break;
                    case SELECT_FOR_UPDATE:
                        executor = new SelectForUpdateExecutor(statementProxy, statementCallback, sqlRecognizer);
                        break;
                    default:
                        executor = new PlainExecutor<T, S>(statementProxy, statementCallback);
                        break;
                }
            }
            T rs = null;
            try {
                rs = executor.execute(args);
    
            } catch (Throwable ex) {
                if (ex instanceof SQLException) {
                    throw (SQLException) ex;
                } else {
                    // Turn everything into SQLException
                    new SQLException(ex);
                }
            }
            return rs;
        }
    }
    

    说明:

    • ExecuteTemplate内部根据SQL执行类型不同分为InsertExecutor、UpdateExecutor、DeleteExecutor、SelectForUpdateExecutor、PlainExecutor。
    • InsertExecutor负责执行insert的SQL。
    • UpdateExecutor负责执行update的SQL。
    • DeleteExecutor负责执行delete的SQL。
    • SelectForUpdateExecutor负责执行select for update操作的SQL。

    期待

     后续进一步分析不同的Executor的执行逻辑,很快就要接近RM的核心逻辑。

    相关文章

      网友评论

        本文标题:Fescar - RM ExecuteTemplate介绍

        本文链接:https://www.haomeiwen.com/subject/yqrdeqtx.html