Mybatis学习总结(二)SqlSession

总概

SqlSession是Mybatis的接口,Mybatis对数据库的很多操作都通过这个上层接口暴露给开发者。

它的主要作用有3个:

1、获取Mapper接口。

2、发送SQL给数据库。

3、控制数据库事务。

它有两个实现类:1、线程不安全的DefaultSqlSession和线程安全的SqlSessionManager。

一、SqlSession的创建过程

我们首先还是先来看SqlSession的创建过程:

SqlSession sqlSession = sqlSessionFactory.openSession();

那么这个方法具体做了哪些工作呢?

/**

*    Copyright 2009-2015 the original author or authors.

*

*    Licensed under the Apache License, Version 2.0 (the "License");

*    you may not use this file except in compliance with the License.

*    You may obtain a copy of the License at

*

*      http://www.apache.org/licenses/LICENSE-2.0

*

*    Unless required by applicable law or agreed to in writing, software

*    distributed under the License is distributed on an "AS IS" BASIS,

*    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

*    See the License for the specific language governing permissions and

*    limitations under the License.

*/

package org.apache.ibatis.session.defaults;

import java.sql.Connection;

import java.sql.SQLException;

import org.apache.ibatis.exceptions.ExceptionFactory;

import org.apache.ibatis.executor.ErrorContext;

import org.apache.ibatis.executor.Executor;

import org.apache.ibatis.mapping.Environment;

import org.apache.ibatis.session.Configuration;

import org.apache.ibatis.session.ExecutorType;

import org.apache.ibatis.session.SqlSession;

import org.apache.ibatis.session.SqlSessionFactory;

import org.apache.ibatis.session.TransactionIsolationLevel;

import org.apache.ibatis.transaction.Transaction;

import org.apache.ibatis.transaction.TransactionFactory;

import org.apache.ibatis.transaction.managed.ManagedTransactionFactory;

/**

* @author Clinton Begin

*/

public class DefaultSqlSessionFactory implements SqlSessionFactory {

  private final Configuration configuration;

  public DefaultSqlSessionFactory(Configuration configuration) {

    this.configuration = configuration;

  }

  @Override

  public SqlSession openSession() {

    return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);

  }

  @Override

  public SqlSession openSession(boolean autoCommit) {

    return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, autoCommit);

  }

  @Override

  public SqlSession openSession(ExecutorType execType) {

    return openSessionFromDataSource(execType, null, false);

  }

  @Override

  public SqlSession openSession(TransactionIsolationLevel level) {

    return openSessionFromDataSource(configuration.getDefaultExecutorType(), level, false);

  }

  @Override

  public SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level) {

    return openSessionFromDataSource(execType, level, false);

  }

  @Override

  public SqlSession openSession(ExecutorType execType, boolean autoCommit) {

    return openSessionFromDataSource(execType, null, autoCommit);

  }

  @Override

  public SqlSession openSession(Connection connection) {

    return openSessionFromConnection(configuration.getDefaultExecutorType(), connection);

  }

  @Override

  public SqlSession openSession(ExecutorType execType, Connection connection) {

    return openSessionFromConnection(execType, connection);

  }

  @Override

  public Configuration getConfiguration() {

    return configuration;

  }

  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();

    }

  }

  private SqlSession openSessionFromConnection(ExecutorType execType, Connection connection) {

    try {

      boolean autoCommit;

      try {

        autoCommit = connection.getAutoCommit();

      } catch (SQLException e) {

        // Failover to true, as most poor drivers

        // or databases won't support transactions

        autoCommit = true;

      }     

      final Environment environment = configuration.getEnvironment();

      final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);

      final Transaction tx = transactionFactory.newTransaction(connection);

      final Executor executor = configuration.newExecutor(tx, execType);

      return new DefaultSqlSession(configuration, executor, autoCommit);

    } catch (Exception e) {

      throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);

    } finally {

      ErrorContext.instance().reset();

    }

  }

  private TransactionFactory getTransactionFactoryFromEnvironment(Environment environment) {

    if (environment == null || environment.getTransactionFactory() == null) {

      return new ManagedTransactionFactory();

    }

    return environment.getTransactionFactory();

  }

  private void closeTransaction(Transaction tx) {

    if (tx != null) {

      try {

        tx.close();

      } catch (SQLException ignore) {

        // Intentionally ignore. Prefer previous error.

      }

    }

  }

}

通过DefaultSqlSessionFactory的源码我们可以看到,真正构建DefaultSqlSession对象也就是这两个私有方法(加粗部分):

 private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit)

private SqlSession openSessionFromConnection(ExecutorType execType, Connection connection) 

二、SqlSession用法详解

首先来看SqlSession的事务模型:

SqlSession sqlSession = null;

try{

sqlSession = sqlSessionFactory.openSession(false);//获得一个不自动commit的SqlSession对象

//do somthing here

sqlSession.commit(); //提交事务

}catch(Exception ex){

sqlSession.rollback(); //事务回滚

}finally{

if(sqlSession != null){

 sqlSession.close();//关闭连接,将它还给连接池

}

}

你可能感兴趣的:(Mybatis学习总结(二)SqlSession)