MyBatis源碼學習(一)SqlSession建立,mybatissqlsession
MyBatis封裝了JDBC操作資料庫的代碼,通過SqlSession來執行sql語句,那麼首先來看看MyBatis是怎麼建立SqlSession。
MyBatis沒有託管給spring的時候,資料庫的配置資訊是在Configuration.xml檔案裡邊配置的 ,測試代碼如下
1 Reader reader = Resources.getResourceAsReader("Configuration.xml");
Mybatis通過SqlSessionFactoryBuilder.build(Reader reader)方法建立一個SqlSessionFactory對象 build方法的參數就是剛才的reader對象,裡邊包含了設定檔的所有資訊,build方法有很多重載方法
1 public SqlSessionFactory build(Reader reader, String environment, Properties properties) { 2 try { 3 //委託XMLConfigBuilder來解析xml檔案,並構建 4 XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties); 5 return build(parser.parse()); 6 } catch (Exception e) { 7 throw ExceptionFactory.wrapException("Error building SqlSession.", e); 8 } finally { 9 ErrorContext.instance().reset();10 try {11 reader.close();12 } catch (IOException e) {13 }14 public SqlSessionFactory build(Configuration config) {15 return new DefaultSqlSessionFactory(config);16 }
最後返回一個DefaultSqlSessionFactory對象,通過DefaultSqlSessionFactory的openSession()返回一個SqlSession對象
public SqlSession openSession() { return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false); }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); //然後產生一個DefaultSqlSession 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(); } }
可以看到最後返回一個DefaultSqlSession即SqlSession對象,DefaultSqlSession中的selectOne(…) selectList(…)
selectMap(…) update(…)等方法就是真正執行要執行sql的方法
具體的執行由executor對象來執行
public void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler) { try { MappedStatement ms = configuration.getMappedStatement(statement); executor.query(ms, wrapCollection(parameter), rowBounds, handler); } catch (Exception e) { throw ExceptionFactory.wrapException("Error querying database. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } }