最近开始学习myBatis框架,为了不遗忘,所以将自己的浅显理解写下方便过后温习,写的很粗糙,见谅
通过代码我们能看出myBatis建立连接用了四步
String resource = "SqlMapConfig.xml"; InputStream is = Test3.class.getClassLoader().getResourceAsStream(resource); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is); SqlSession session = factory.openSession();
先用字符串储存核心配置文件的资源名
然后,用当前测试类的类加载器调用getResourceAsStream()方法,去找到指定资源名的绝对路径,返回一个字节输入流
SqlSessionFactoryBuilder获得这个字节流,找到核心配置文件
//通过读入配置文件,最终获得一个sqlSessionFactory public class SqlSessionFactoryBuilder { //这里是字符输入流的相关方法 public SqlSessionFactory build(Reader reader) { return build(reader, null, null); } public SqlSessionFactory build(Reader reader, String environment) { return build(reader, environment, null); } public SqlSessionFactory build(Reader reader, Properties properties) { return build(reader, null, properties); } public SqlSessionFactory build(Reader reader, String environment, Properties properties) { try { XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties); return build(parser.parse());//获得SqlSessionFactory } catch (Exception e) { throw ExceptionFactory.wrapException("Error building SqlSession.", e); } finally { ErrorContext.instance().reset(); try { reader.close(); } catch (IOException e) { // Intentionally ignore. Prefer previous error. } } } //以字节输入流传入配置信息,这里才是以文章开头代码的方式,调用的方法 public SqlSessionFactory build(InputStream inputStream) { //去调用带有三个参数的build方法 return build(inputStream, null, null); } public SqlSessionFactory build(InputStream inputStream, String environment) { return build(inputStream, environment, null); } public SqlSessionFactory build(InputStream inputStream, Properties properties) { return build(inputStream, null, properties); } //调用此处的build方法 public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) { try { //解析myBatis配置文件,以字节流的方式 XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties); //调用下方的build方法来获得连接工厂SqlSessionFactory return build(parser.parse()); } catch (Exception e) { throw ExceptionFactory.wrapException("Error building SqlSession.", e); } finally { ErrorContext.instance().reset(); try { //关闭字节输入流 inputStream.close(); } catch (IOException e) { // Intentionally ignore. Prefer previous error. } } } public SqlSessionFactory build(Configuration config) { //获得sqlsessionFactory工厂,再从工厂中获得sqlsession return new DefaultSqlSessionFactory(config); } }
连接工厂去调用openSession()方法
//调用这个openSession方法 @Override public SqlSession openSession() { //调用openSessionFromDataSource,从configuration中获取默认Executor对象类型,这是一个很重要的对象 return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false); }
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) { Transaction tx = null; try { //获得配置文件中的enviroment final Environment environment = configuration.getEnvironment(); //从environment中获得事务 final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment); //获取数据源 tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit); //创建一个Executor对象,SqlSession的操作都是通过这个对象来实现的 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(); } }