SqlSession对象的获取
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = factory.openSession();
SqlSession对象创建的过程
配置文件的解析
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
主要是在build方法中对配置文件进行的解析,主要完成配置文件的解析成对象,还有就是读取配置文件中的mapper, 尽量在一次IO操作中完成对对象的封装,减少IO调用。
XML的解析
XML解析有三种方式
- DOM
- SAX
- XPath (Mybatis)
与熟悉的ORM相对的就是OXM,java的核心思想,一切皆对象,OXM就是Object和xml的映射。 Mybatis中把xml中的配置封装成Configuration对象,通过XpathParser解析成XNode对象,再进一步封装成Configuration对象。
XPathParser xpathParser = new XPathParser(inputStream);
xpathParser.evalNodes("/xxxxx") ----> XNode ---> 标签的名字 标签的属性 标签内容
封装Configuration
build() --> parseConfiguration(parser.evalNode("/configuration"));
封装MapperStatement
xPathParser XNode ---> MappedStatement ---> namespace.id parseConfiguration-->mapperElement(root.evalNode("mappers"));
XMLMapperBuilder mapperParser = new XMLMapperBuilder();
mapperParser.parse();
configurationElement(parser.evalNode("/mapper"));
statementParser.parseStatementNode();
builderAssistant.addMappedStatement
MappedStatement statement = statementBuilder.build();
configuration.addMappedStatement(statement);
上边是封装的主要流程,最后把MappedStatment 存放在了 Configuration 中
SqlSessionFactory工厂的创建
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
return build(parser.parse());
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
直接通过build方法,入参是Configuration对象,直接创建了默认的DefaultSQLSessionFactory进行返回,也就是说这个是工厂的默认实现
再看SqlSession对象的获取
SqlSession sqlSession = sqlSessionFactory.openSession();
猜测一下openSession里边的过程,首先可以知道的是肯定需要把Executor交给SqlSession,因为底层都是Executor来进行操作的,然后可能还需要MapperStatement
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();
}
}
获取了Environment对象,得到相关的连接池信息。创建了Executor交给SqlSession用于后边的执行,还赋值了Configuration对象,其中就包括了从配置文件解析、封装并存入Configuration对象中的MapperStatement对象,而且创建的是DefaultSqlSession
SqlSession执行sql的主要流程
SqlSession.getMapper() -> 动态代理 -> DAO接口的实现类
MapperProxyFactory(JDK创建的代理对象)
|- InvocationHandler -> MapperProxy
|- SqlCommand
|- type [insert|update|delete|select]
|- name namespace.id -类的全路径.方法名
|- MethodSingnature
|- 方法的返回值、参数
|- sqlSession.update()
|- Executor(SimpleExecutor|ReUseExecutor|BatchExecutor)
|- StatementHandler
|- ParameterHandler ResultSetHandler
|- TypeHandlder
|- sqlSession.select()
|- sqlSession.delete()