欢迎访问昆山宝鼎软件有限公司网站! 设为首页 | 网站地图 | XML | RSS订阅 | 宝鼎邮箱 | 后台管理


新闻资讯

MENU

软件开发知识

这是由dataSource标签中的type属性决定 图纸加密 的: private PooledConnection p

点击: 次  来源:宝鼎软件 时间:2017-06-01

原文出处: 五月的仓颉

打开一个会话Session

前文阐明白MyBatis将设置文件转换为Java工具的流程,本文开始阐明一下insert要领、update要领、delete要领处理惩罚的流程,至于为什么这三个要领要放在一起说,是因为:

  • 从语义的角度,insert、update、delete都是属于对数据库的行举办更新操纵
  • 从实现的角度,我们熟悉的PreparedStatement内里提供了两种execute要领,一种是executeUpdate(),一种是executeQuery(),前者对应的是insert、update与delete,后者对应的是select,因此对付MyBatis来说只有update与select
  • 示例代码为这段:

    public long insertMail(Mail mail) {
        SqlSession ss = ssf.openSession();
        try {
            int rows = ss.insert(NAME_SPACE + "insertMail", mail);
            ss.commit();
            if (rows > 0) {
                return mail.getId();
            }
            return 0;
        } catch (Exception e) {
            ss.rollback();
            return 0;
        } finally {
            ss.close();
        }
    }

    首先存眷的是第2行的代码,ssf是SqlSessionFactory,其范例是DefaultSqlSessionFactory,上文最后已经阐明过了,这里通过DefaultSqlSessionFactory来打开一个Session,通过Session去举办CRUD操纵。

    看一下openSession()要领的实现:

    public SqlSession openSession() {
         return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
     }

    顾名思义,从DataSource中获取Session,第一个参数的值是ExecutorType.SIMPLE,继承跟代码:

    private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
        Transaction tx = null;
        try {
          final Environment environment = configuration.getEnvironment();
          final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
          tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
          final Executor executor = configuration.newExecutor(tx, execType);
          return new DefaultSqlSession(configuration, executor, autoCommit);
        } catch (Exception e) {
          closeTransaction(tx); // may have fetched a connection so lets call close()
          throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
        } finally {
          ErrorContext.instance().reset();
        }
    }

    第4行的代码,获取设置的情况信息Environment。

    第5行的代码,从Environment中获取事物工场TransactionFactory,由于<environment>中设置的是”JDBC”,因此其真实范例是JdbcTransactionFactory,上文有说过。

    第6行的代码,按照Environment中的DataSource(其实际范例是PooledDataSource)、TransactionIsolationLevel、autoCommit三个参数从TransactionFactory中获取一个事物,留意第三个参数autoCommit,它是openSession()要领中传过来的,其值为false,即MyBatis默认事物是不自动提交的。

    第7行的代码,代码跟一下:

    public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
        executorType = executorType == null ? defaultExecutorType : executorType;
        executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
        Executor executor;
        if (ExecutorType.BATCH == executorType) {
          executor = new BatchExecutor(this, transaction);
        } else if (ExecutorType.REUSE == executorType) {
          executor = new ReuseExecutor(this, transaction);
        } else {
          executor = new SimpleExecutor(this, transaction);
        }
        if (cacheEnabled) {
          executor = new CachingExecutor(executor);
        }
        executor = (Executor) interceptorChain.pluginAll(executor);
        return executor;
    }

    这里总结一下:

  • 按照ExecutorType获取一个执行器,这里是第10行的SimpleExecutor
  • 假如满意第12行的判定开启缓存成果,则执行第13行的代码。第13行的代码利用到了装饰器模式,传入Executor,给SimpleExecutor装饰上了缓存成果
  • 第15行的代码用于配置插件
  • 这样就获取了一个Executor。最后将Executor、Configuration、autoCommit三个变量作为参数,实例化一个SqlSession出来,其实际范例为DefaultSqlSession。

    insert要领执行流程

    在看了openSession()要领知道最终得到了一个DefaultSqlSession之后,看一下DefaultSqlSession的insert要领是如何实现的:

     public int insert(String statement, Object parameter) {
          return update(statement, parameter);
      }

    看到固然挪用的是insert要领,可是最终统一城市去执行update要领,delete要领也是如此,这个开头已经说过了,这里证明白这一点。

    接着继承看第2行的要领实现:

    public int update(String statement, Object parameter) {
        try {
          dirty = true;
          MappedStatement ms = configuration.getMappedStatement(statement);
          return executor.update(ms, wrapCollection(parameter));
        } catch (Exception e) {
          throw ExceptionFactory.wrapException("Error updating database.  Cause: " + e, e);
        } finally {
          ErrorContext.instance().reset();
        }
    }

    第4行的代码按照statement从Configuration中获取MappedStatement,MappedStatement上文已经阐明过了,存储在Configuration的mappedStatements字段中。