`
Donald_Draper
  • 浏览: 971846 次
社区版块
存档分类
最新评论

DefaultSqlSession第二讲-更新,刷新Statement

阅读更多
上一篇文章中,我们讲到DefaultSqlSession的查询,今天来讲更新
//DefaultSqlSession
public class DefaultSqlSession
    implements SqlSession
{
    private Configuration configuration;
    private Executor executor;
    private boolean dirty;
    public DefaultSqlSession(Configuration configuration, Executor executor)
    {
        this.configuration = configuration;
        this.executor = executor;
        dirty = false;
    }
    //插入
     public int insert(String statement)
    {
        return insert(statement, null);
    }

    public int insert(String statement, Object parameter)
    {
       //委托给update方法
        return update(statement, parameter);
    }

    public int update(String statement)
    {
        return update(statement, null);
    }
    //删除
     public int delete(String statement)
    { 
        //委托给update
        return update(statement, null);
    }

    public int delete(String statement, Object parameter)
    {
        return update(statement, parameter);
    }
    public int update(String statement, Object parameter)
    {
        int i;
        try
        {
            dirty = true;
            org.apache.ibatis.mapping.MappedStatement ms = configuration.getMappedStatement(statement);
            //委托给executor的update
	    i = executor.update(ms, wrapCollection(parameter));
        }
    }
    //刷新Statements
    public List flushStatements()
    {
        List list;
        try
        {
            list = executor.flushStatements();
        }
    }
}

从DefaultSqlSession类,看一看出插入,删除,更新操作实际上都是调用update方法,下面
我们来看一下这个方法
public int update(String statement, Object parameter)
    {
        int i;
        try
        {
            dirty = true;
            org.apache.ibatis.mapping.MappedStatement ms = configuration.getMappedStatement(statement);
            //委托给executor的update
	    i = executor.update(ms, wrapCollection(parameter));
        }
    }

update方法委托给具体的executor,executor默认为CachingExecutor,CachingExecutor为执行器代理,具体executor
有SimpleExecutor,BatchExecutor;
下面来看SimpleExecutor
//CachingExecutor
public int update(MappedStatement ms, Object parameterObject)
        throws SQLException
    {
        flushCacheIfRequired(ms);
        return _flddelegate.update(ms, parameterObject);
    }

具体执行器SimpleExecutor
//BaseExecutor
  
public int update(MappedStatement ms, Object parameter)
        throws SQLException
    {
        ErrorContext.instance().resource(ms.getResource()).activity("executing an update").object(ms.getId());
        if(closed)
        {
            throw new ExecutorException("Executor was closed.");
        } else
        {
            clearLocalCache();
	    //委托给doUpdate
            return doUpdate(ms, parameter);
        }
    }
    //待子类扩展
     protected abstract int doUpdate(MappedStatement mappedstatement, Object obj)
        throws SQLException;

//SimpleExecutor
public int doUpdate(MappedStatement ms, Object parameter)
        throws SQLException
    {
        Statement stmt = null;
        int i;
        Configuration configuration = ms.getConfiguration();
	//创建StatementHandler
        StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, RowBounds.DEFAULT, null, null);
        //创建Statement
	stmt = prepareStatement(handler, ms.getStatementLog());
	//执行查询
        i = handler.update(stmt);
	//Statement关闭
        closeStatement(stmt);
    }

//创建StatementHandler,创建Statement,执行查询,Statement关闭,上一篇我们已经说,这里就不说了,
我们看一下BatchExecutor
public class BatchExecutor extends BaseExecutor
{
    public static final int BATCH_UPDATE_RETURN_VALUE = -2147482646;
    private final List statementList = new ArrayList();//statement集合
    private final List batchResultList = new ArrayList();//结果集合
    private String currentSql;
    private MappedStatement currentStatement;
    
    public BatchExecutor(Configuration configuration, Transaction transaction)
    {
        super(configuration, transaction);
    }
     public int doUpdate(MappedStatement ms, Object parameterObject)
        throws SQLException
    {
        Configuration configuration = ms.getConfiguration();
	//创建StatementHandler
        StatementHandler handler = configuration.newStatementHandler(this, ms, parameterObject, RowBounds.DEFAULT, null, null);
        BoundSql boundSql = handler.getBoundSql();
        String sql = boundSql.getSql();
        Statement stmt;
        if(sql.equals(currentSql) && ms.equals(currentStatement))
        {
	   //如果sql与currentSql相等,则从statementList获取Statement
            int last = statementList.size() - 1;
            stmt = (Statement)statementList.get(last);
            BatchResult batchResult = (BatchResult)batchResultList.get(last);
            batchResult.addParameterObject(parameterObject);
        } else
        {
	    //获取连接
            java.sql.Connection connection = getConnection(ms.getStatementLog());
	    //创建statement
            stmt = handler.prepare(connection);
            currentSql = sql;
            currentStatement = ms;
	    //将statement添加到statementList
            statementList.add(stmt);
            batchResultList.add(new BatchResult(ms, sql, parameterObject));
        }
	//设置statement参数
        handler.parameterize(stmt);
	//
        handler.batch(stmt);
        return -2147482646;
    }
}

//执行statement
handler.batch(stmt);

handler为RoutingStatementHandler,RoutingStatementHandler为StatementHandler的代理类,具体可能为SimpleStatementHandler,PreparedStatementHandler,
CallableStatementHandler;
下面我们来看一下RoutingStatementHandler的batch
//RoutingStatementHandler
public class RoutingStatementHandler
    implements StatementHandler
{
 private final StatementHandler _flddelegate;
  public void batch(Statement statement)
        throws SQLException
    {
        _flddelegate.batch(statement);
    }
}

RoutingStatementHandler的batch方法实际上,是调用代理的batch方法,
//PreparedStatementHandler
public class PreparedStatementHandler extends BaseStatementHandler
{
public void batch(Statement statement)
        throws SQLException
    {
        PreparedStatement ps = (PreparedStatement)statement;
        ps.addBatch();
    }
}

//CallableStatementHandler
 
 public void batch(Statement statement)
        throws SQLException
    {
        CallableStatement cs = (CallableStatement)statement;
        cs.addBatch();
    }

具体为调用CallableStatement和PreparedStatement的批处理函数
讲到批处理,我们来看一下 DefaultSqlSession的flushStatements方法
public List flushStatements()
    {
        List list;
        try
        {
            list = executor.flushStatements();
        } 
    }

这里我们来看一下具体executor的flushStatements
//BatchExecutor
public List doFlushStatements(boolean isRollback)
        throws SQLException
    {
        List results;
        List list;
        results = new ArrayList();
        if(!isRollback)
            break MISSING_BLOCK_LABEL_83;
        list = Collections.emptyList();
        Statement stmt;
	//关闭statementList中的Statement
        for(Iterator i$ = statementList.iterator(); i$.hasNext(); closeStatement(stmt))
            stmt = (Statement)i$.next();
        //currentSql,设为null
        currentSql = null;
        statementList.clear();
        batchResultList.clear();
        return list;
    }

BatchExecutor的doFlushStatements主要是关闭statementList中的Statement,
清空statementList与batchResultList
//SimpleExecutor
public List doFlushStatements(boolean isRollback)
        throws SQLException
    {
        return Collections.emptyList();
    }

SimpleExecutor没做任何事情,从上可以看出doFlushStatements,主要是BatchExecutor会用到;
总结:
Sqlsession的update,通过CachingExecutor代理,CachingExecutor是SimpleExecutor,BatchExecutor等执行器代理执行器;CachingExecutor是调用Executor的相应方法。SimpleExecutor,BatchExecutor为实际执行器,继承BatchExecutor。SimpleExecutor更新,构造StatementHandler,获取Statement,执行查询,关闭statement。BatchExecutor的doFlushStatements主要是关闭statementList中的Statement,
清空statementList与batchResultList


分享到:
评论

相关推荐

    HSBC-Bank-statement_statement_template_

    hsbc statement template

    test-sql-statement.frx

    test-sql-statement.frx

    switch-statement-examples_C-C++_statement_

    这个标题"switch-statement-examples_C-C++_statement_"表明我们将深入探讨`switch`语句在C和C++中的用法,并通过实例进行解析。 `switch`语句的基本语法如下: ```c switch(expression) { case value1: // code...

    fluent-plugin-mysql-prepared-statement

    fluent-plugin-mysql-prepared-statement, 的插件 流利的插件mysql准备语句查询 安装 td-agent(Linux) /usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-mysql-prepared-statement td-agent(Mac...

    Efficiency-Analysis-of-sql-statement.zip_statement

    以下是对"Efficiency Analysis of sql statement.zip_statement"中涉及的知识点的详细说明: 1. **索引的使用**:索引是提高SQL查询速度的重要手段。为经常用于查询的列创建索引可以大大加快查找速度。但需要注意的...

    JDBC从入门到放弃02-JDBC的Statement数据库增加和删除

    本教程将深入浅出地介绍如何使用JDBC的Statement接口来执行数据库的增加(INSERT)和删除(DELETE)操作,帮助初学者从入门到熟练掌握这一核心技术。 首先,JDBC的核心是Java.sql包中的DriverManager类,它负责管理...

    webcomponent-vl-ui-cookie-statement

    vl-ui-cookie声明 Cookieverklaring Pagina安装$ npm install --save vl-ui-cookie-statement原料药强,可以保护车辆的功能。演示版De pagina bevat een overzicht van de Mogelijkheden遇到了代号voorbeelden。 ...

    第4讲-结构程序设计教学课件PPT文档.pptx

    本讲主要探讨了C语言中的程序结构,包括C程序的组成、基本结构以及数据输入输出。 首先,C程序通常由一个或多个源程序文件组成,每个文件可能包含不同的函数。预编译命令如`#include`用于引入头文件,例如`#include...

    Multiple-Criteria-Query-Statement-Probabilities:顶点项目。 内部攻击监控系统

    在本项目中,JavaScript主要用于前端交互逻辑,处理用户输入的查询条件,计算查询概率,并与后端服务器进行通信,实时更新和反馈监控结果。同时,JavaScript的事件驱动模型也能有效地处理大量并发查询请求,确保系统...

    simplify-logic-statement-ts:采取逻辑陈述并简化它

    简化逻辑陈述采取逻辑陈述并将其简化。用法将简化函数应用于以下概述的一种类型。例子消除双重否定import { simplify , ... statement , statement : 'statement 3' , } , } ,}simplify ( myNotStatement ) // {

    statement-tracer-for-oracle

    2. 执行计划分析: 工具会提供SQL语句的执行计划,这是理解查询如何在数据库内部执行的关键。执行计划展示了数据是如何被访问、排序和组合的,有助于发现潜在的索引问题或者不恰当的表连接方式。 3. 资源消耗统计...

    infrastructure-funding-statement-collection

    更新收藏 我们建议在安装python, 和其他依赖项之前在工作。 需要Make v4.0或更高版本。 $ make makerules $ make init $ make collect 每晚收藏 该集合由。 建立国家数据集 然后可以将收集的文件转换为国家数据集...

    vscode-complete-statement:在vscode中使用分号的完整语句

    在vscode中用分号完成语句。 模仿IntelliJ的完整声明。 换句话说: 用完整的正常... 您可以将extension.complete-statement重新绑定到ctrl+shift+enter 。 顺便说一句, ctrl+; 比ctrl+shift+enter更容易记住和键入。

    programming-univbasics-2-statement-if-end-wdc01-seng-ft-080921

    作为会话进行编程2:使用if ... end和Statement修饰符进行选择学习目标写一个if...end语句写一个if...else...end语句写一个if...elsif...else...end语句使用语句修饰符更改默认顺序介绍我们已经介绍了Ruby在读取和...

    programming-univbasics-2-statement-if-end-atx01-seng-ft-080921

    作为会话进行编程2:使用if ... end和Statement修饰符进行选择 学习目标 写一个if...end语句 写一个if...else...end语句 写一个if...elsif...else...end语句 使用语句修饰符更改默认顺序 介绍 我们已经介绍了Ruby在...

    C BNF grammar

    #### 二、BNF与C语言语法 **Backus-Naur Form (BNF)** 是一种用于定义上下文无关文法的形式化语言,它提供了一种简洁明了的方式来描述编程语言的语法结构。在C语言中,通过BNF可以清晰地定义语言的各个组成部分,如...

    prepareStatement和Statement的区别

    prepareStatement和Statement的区别 prepareStatement和Statement是 Java 中两个常用的数据库操作接口,它们都可以用来执行 SQL 语句,但是它们之间有着明显的区别。 首先,从创建时的区别开始,Statement 需要...

    Account-Income-Statement-Programme

    帐户收入报表程序 待办事项清单 创建对齐方式以充当终端中的表 选择继续计算资产负债表 资产负债表代码 授予用户创建新价值的完整权限(负债,资产等的详细信息) 向用户显示平衡值 在终端中创建路线以用作资产负债...

    顶级投行、金融估值建模培训资料-Three Statement Financial Modeling _ Street Of Walls.pdf

    顶级投行、金融估值建模培训资料-Three Statement Financial Modeling _ Street Of Walls.pdf

    Jsp实现学生成绩管理系统-更新数据库文件

    【Jsp实现学生成绩管理系统-更新数据库文件】 在信息技术教育领域,开发一个学生成绩管理系统是提升教学管理效率的重要工具。本系统采用JavaServer Pages(JSP)技术结合MySQL数据库来实现,旨在为管理员、教师和...

Global site tag (gtag.js) - Google Analytics