SqlSession是mybatis的核心接口,SqlSessionFactory负责创建SqlSession对象,包含多个openSession()方法的重载。
在SqlSession中定义了常用的数据库操作以及事务操作,接口定义如下
SqlSession
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| public interface SqlSession extends Closeable { <T> T selectOne(String statement); <T> T selectOne(String statement, Object parameter);
<E> List<E> selectList(String statement);
<E> List<E> selectList(String statement, Object parameter); <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds);
<K, V> Map<K, V> selectMap(String statement, String mapKey);
<K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey);
<K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds); <T> Cursor<T> selectCursor(String statement);
<T> Cursor<T> selectCursor(String statement, Object parameter);
<T> Cursor<T> selectCursor(String statement, Object parameter, RowBounds rowBounds);
void select(String statement, Object parameter, ResultHandler handler);
void select(String statement, ResultHandler handler);
void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler);
int insert(String statement);
int insert(String statement, Object parameter);
int update(String statement);
int update(String statement, Object parameter);
int delete(String statement);
int delete(String statement, Object parameter); void commit();
void commit(boolean force); void rollback();
void rollback(boolean force);
List<BatchResult> flushStatements();
@Override void close();
void clearCache();
Configuration getConfiguration();
<T> T getMapper(Class<T> type);
Connection getConnection(); }
|
MyBatis为SqlSession提供了默认实现,DefaultSqlSession类
1 2 3 4 5 6 7 8 9 10
| private final Configuration configuration; private final Executor executor;
private final boolean autoCommit; private boolean dirty; private List<Cursor<?>> cursorList;
|
所有的数据库相关操作全部封装到了Executor接口实现中,DefaultSqlSession类中查询方法的调用关系如下图
查询最终都是调用Executor.query(MappedStatement, Object, RowBounds, ResultHandler)方法实现数据库查询操作的。
对返回对象进行调整
- selectOne()方法从结果集中获取第一个元素返回
- selectMap()方法将List集合转为Map集合返回
- select()方法将结果对象集合交由用户指定的ResultHandler对象处理,且没有返回值
- selectList()方法直接将集合返回
DefaultSqlSession中的insert()、update()、delete()方法最后通过调用DefaultSqlSession.update(String,Object)方法,从而调用Executor.update(MappedStatement, Object)方法完成数据库的修改操作。
DefaultSqlSessionFactory
DefaultSqlSessionFactory实现了SqlSessionFactory接口,提供了两种创建DefaultSqlSession的方式
方式一
通过数据源获取数据库连接,并创建Executor对象以及DefaultSqlSession对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
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); throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } }
|
方式二
用户提供数据库连接,根据数据库连接创建Executor对象以及DefaultSqlSession对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| private SqlSession openSessionFromConnection(ExecutorType execType, Connection connection) { try { boolean autoCommit; try { autoCommit = connection.getAutoCommit(); } catch (SQLException e) { 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(); } }
|
SqlSessionManager
SqlSessionManager同时实现了SqlSessionFactory和SqlSession接口,也提供了SqlSessionFactory创建SqlSession对象以及SqlSession操作数据库的功能。
1 2 3 4 5
| private final SqlSessionFactory sqlSessionFactory;
private final SqlSession sqlSessionProxy;
private final ThreadLocal<SqlSession> localSqlSession = new ThreadLocal();
|
SqlSessionManager与DefaultSqlSessionFactory主要不同点是SqlSessionManager提供了两种模式:第一种模式和DefaultSqlSessionFactory的行为相同,同一个线程每次通过SqlSessionManager对象访问数据库时,都会创建新的DefaultSession对象完成数据库操作
第二种模式是SqlSessionManager通过localSqlSession这个ThreadLocal变量,记录当前线程绑定的SqlSession对象,供当前线程循环使用,从而避免在同一个线程多次创建SqlSession对象带来的性能损失
1 2 3 4 5
| private SqlSessionManager(SqlSessionFactory sqlSessionFactory) { this.sqlSessionFactory = sqlSessionFactory; this.sqlSessionProxy = (SqlSession)Proxy.newProxyInstance(SqlSessionFactory.class.getClassLoader(), new Class[]{SqlSession.class}, new SqlSessionManager.SqlSessionInterceptor()); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| private class SqlSessionInterceptor implements InvocationHandler { public SqlSessionInterceptor() { }
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { final SqlSession sqlSession = SqlSessionManager.this.localSqlSession.get(); if (sqlSession != null) { try { return method.invoke(sqlSession, args); } catch (Throwable t) { throw ExceptionUtil.unwrapThrowable(t); } } else { try (SqlSession autoSqlSession = openSession()) { try { final Object result = method.invoke(autoSqlSession, args); autoSqlSession.commit(); return result; } catch (Throwable t) { autoSqlSession.rollback(); throw ExceptionUtil.unwrapThrowable(t); } } } } }
|
四大对象
sqlSession真正的执行时通过Executor、StatementHandler、ParameterHandler、ResultSetHandler来完成数据库操作和结果返回
- Executor 执行器 通过执行器来调度StatementHandler、ParameterHandler和ResultHandler等来执行对应的sql
- StatementHandler 使用数据库的Statement/PreparedStatement执行操作
- ParameterHandler 用于sql对参数的处理
- ResultSetHandler 进行结果集ResultSet的封装和返回