mybatis源码阅读-SqlSessionFactory
Posted 意犹未尽
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mybatis源码阅读-SqlSessionFactory相关的知识,希望对你有一定的参考价值。
说明
读了3遍:https://my.oschina.net/zudajun/blog/665956 现在统一整理成笔记 并跟着源码一行一行调试 统一整理起来
SqlSession
接口定义
public interface SqlSession extends Closeable { <T> T selectOne(String var1); <T> T selectOne(String var1, Object var2); <E> List<E> selectList(String var1); <E> List<E> selectList(String var1, Object var2); <E> List<E> selectList(String var1, Object var2, RowBounds var3); <K, V> Map<K, V> selectMap(String var1, String var2); <K, V> Map<K, V> selectMap(String var1, Object var2, String var3); <K, V> Map<K, V> selectMap(String var1, Object var2, String var3, RowBounds var4); <T> Cursor<T> selectCursor(String var1); <T> Cursor<T> selectCursor(String var1, Object var2); <T> Cursor<T> selectCursor(String var1, Object var2, RowBounds var3); void select(String var1, Object var2, ResultHandler var3); void select(String var1, ResultHandler var2); void select(String var1, Object var2, RowBounds var3, ResultHandler var4); int insert(String var1); int insert(String var1, Object var2); int update(String var1); int update(String var1, Object var2); int delete(String var1); int delete(String var1, Object var2); void commit(); void commit(boolean var1); void rollback(); void rollback(boolean var1); List<BatchResult> flushStatements(); void close(); void clearCache(); Configuration getConfiguration(); <T> T getMapper(Class<T> var1); Connection getConnection(); }
完成数据库CRUD操作
实现类结构图
DefaultSqlSession部分源码
//执行器 接口 private Executor executor; //配置文件 类 private Configuration configuration; /*** * 查询方法 * @param statement mapper.xml namesapce+id * @param parameter 查询参数 * @param rowBounds 分页参数 解析返回值的handler */ public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) { List var5; try { //从config根据 namesapce+id 获得对应的mappedStatement 然后交给executor的query方法 MappedStatement ms = this.configuration.getMappedStatement(statement); var5 = this.executor.query(ms, this.wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER); } catch (Exception var9) { throw ExceptionFactory.wrapException("Error querying database. Cause: " + var9, var9); } finally { ErrorContext.instance().reset(); } return var5; } /** * 修改方法 增加删除也是最终调用这个方法 * @param statement mapper.xml namesapce+id * @param parameter 参数 * @return */ public int update(String statement, Object parameter) { int var4; try { this.dirty = true; //从config根据 namesapce+id 获得对应的mappedStatement 然后交给executor的query方法 MappedStatement ms = this.configuration.getMappedStatement(statement); var4 = this.executor.update(ms, this.wrapCollection(parameter)); } catch (Exception var8) { throw ExceptionFactory.wrapException("Error updating database. Cause: " + var8, var8); } finally { ErrorContext.instance().reset(); } return var4; }
职责是根据namesapce+id 获得对应的mappedStatement然后交给executor执行
SqlSessionFactory
接口定义
public interface SqlSessionFactory { SqlSession openSession(); SqlSession openSession(boolean var1); SqlSession openSession(Connection var1); SqlSession openSession(TransactionIsolationLevel var1); SqlSession openSession(ExecutorType var1); SqlSession openSession(ExecutorType var1, boolean var2); SqlSession openSession(ExecutorType var1, TransactionIsolationLevel var2); SqlSession openSession(ExecutorType var1, Connection var2); Configuration getConfiguration(); }
sqlSession工厂
类图
DefaultSqlSessionFactory源码
public class DefaultSqlSessionFactory implements SqlSessionFactory { //配置文件 保存了解析的mybaits.xml和mapper.xml的内容 private final Configuration configuration; /** * openSession()最终都是调用这个方法创建Session * @param execType 执行器 * @param level 事物隔离级别 * @param autoCommit 是否自动提交 * @return */ private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) { Transaction tx = null; DefaultSqlSession var8; try { //根据配置文件获得Environment 内部封装了数据源信息和事物管理器Factory environments标签配置 Environment environment = this.configuration.getEnvironment(); //获得对应的事物管理器 TransactionFactory transactionFactory = this.getTransactionFactoryFromEnvironment(environment); //开启事物 tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit); //创建执行器 Executor executor = this.configuration.newExecutor(tx, execType); //创建DefaultSqlSession var8 = new DefaultSqlSession(this.configuration, executor, autoCommit); } catch (Exception var12) { this.closeTransaction(tx); throw ExceptionFactory.wrapException("Error opening session. Cause: " + var12, var12); } finally { ErrorContext.instance().reset(); } return var8; } /** * 判断是否有指定事物管理创建工厂 如果没有指定 则默认ManagedTransactionFactory environments标签配置 * @param environment * @return */ private TransactionFactory getTransactionFactoryFromEnvironment(Environment environment) { return (TransactionFactory)(environment != null && environment.getTransactionFactory() != null ? environment.getTransactionFactory() : new ManagedTransactionFactory()); } }
SqlSessionManager
使用
执行完后自动提交回滚 创建2个session
public static void main(String[] args) throws FileNotFoundException { SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder .build(ClassLoader.getSystemResourceAsStream("mybatis.xml")); SqlSessionManager sqlSessionManager = SqlSessionManager.newInstance(sqlSessionFactory); List<Classes> list = sqlSessionManager.selectList("classes.selectAll"); list = sqlSessionManager.selectList("classes.selectAll"); }
创建一个session手动提交回滚
public static void main(String[] args) throws FileNotFoundException { SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder .build(ClassLoader.getSystemResourceAsStream("mybatis.xml")); SqlSessionManager sqlSessionManager=null; try { sqlSessionManager.startManagedSession(); List<Classes> list = sqlSessionManager.selectList("classes.selectAll"); list = sqlSessionManager.selectList("classes.selectAll"); sqlSessionManager.commit(); }catch (Exception e) { if(sqlSessionManager!=null) { sqlSessionManager.rollback(); } } }
类图
源码
public class SqlSessionManager implements SqlSessionFactory, SqlSession { private final SqlSessionFactory sqlSessionFactory; //被代理的sqlSeesion private final SqlSession sqlSessionProxy; //线程缓存 private ThreadLocal<SqlSession> localSqlSession = new ThreadLocal(); private SqlSessionManager(SqlSessionFactory sqlSessionFactory) { this.sqlSessionFactory = sqlSessionFactory; //代理sqlSession 第一个参数类装载器 第二个参数哪个接口类型被代理 第三个参数为代理类 为SqlSessionManager内部内 this.sqlSessionProxy = (SqlSession) Proxy.newProxyInstance(SqlSessionFactory.class.getClassLoader(), new Class[]{SqlSession.class}, new SqlSessionManager.SqlSessionInterceptor()); } public <T> T selectOne(String statement, Object parameter) { return this.sqlSessionProxy.selectOne(statement, parameter); } public int insert(String statement) { return this.sqlSessionProxy.insert(statement); } public int update(String statement, Object parameter) { return this.sqlSessionProxy.update(statement, parameter); } public int delete(String statement) { return this.sqlSessionProxy.delete(statement); }
public SqlSession openSession() {
return this.sqlSessionFactory.openSession();
}
}
内部类SqlSessionInterceptor源码
private class SqlSessionInterceptor implements InvocationHandler { public SqlSessionInterceptor() { } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //从当前线程获得SqlSession 如果为空则创建不为空则直接使用缓存中的SqlSession SqlSession sqlSession = (SqlSession)SqlSessionManager.this.localSqlSession.get(); if (sqlSession != null) { try { //直接使用线程缓存中的SqlSession 并不提交不回滚 return method.invoke(sqlSession, args); } catch (Throwable var12) { throw ExceptionUtil.unwrapThrowable(var12); } } else { //调用SqlSessionManager的openSession方法获得SqlSession 执行完毕后提交回滚 SqlSession autoSqlSession = SqlSessionManager.this.openSession(); Object var7; try { Object result = method.invoke(autoSqlSession, args); autoSqlSession.commit(); var7 = result; } catch (Throwable var13) { autoSqlSession.rollback(); throw ExceptionUtil.unwrapThrowable(var13); } finally { autoSqlSession.close(); } return var7; } } }
以上是关于mybatis源码阅读-SqlSessionFactory的主要内容,如果未能解决你的问题,请参考以下文章