mybatis源码阅读之7:mybatis源码执行流程

上一篇 mybatis缓存

下一篇 获取sqlSessionFactory对象

我们先看一下mybatis按照模块提供的功能:

mybatis源码阅读之7:mybatis源码执行流程_第1张图片

这个图是参照尚学堂的课件画的哈!

先提示一下,阅读源码,要注意mybatis的四大对象:

  • Executor(update,query,flushStatements,commit,rollback,getTransaction,close,isClosed)
  • ParameterHandler(getParameterObject,setParameters)
  • ResultSetHandler(handleResultSets,handleOutputParameters)
  • StatementHandler(prepare,parameterize,batch,update,query)

ok,下面,我们按照这几个步骤来阅读源码:

  1. 获取sqlSessionFactory对象
  2. 获取sqlSession对象
  3. 获取接口的代理对象(MapperProxy)
  4. 执行增删改查

 

我们用下面的代码来做debug,看看每一个操作的执行流程:

	public SqlSessionFactory sqlSessionFactory() throws IOException {

		String resource = "mybatis-config.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

		return sqlSessionFactory;
	}

	/**
	 * mybatis执行流程:(四大对象:Executor,ParameterHandler,ResultSetHandler,StatementHandler)
	 * 
	 * 
	 * 1.获取sqlSessionFactory对象
	 *    1.1解析文件的每一个信息保存在configuration对象中,返回包含configuration的DefaultSqlSessionFactory.
	 *       注意:MappedStatement,代表对一个的一个增删改查sql详细信息
	 *       
	 * 2.获取SqlSession对象
	 *   2.1返回一个DefaultSqlSession对象,包含一个executor和configuration对象
	 * 3.获取接口的代理对象MapperProxy
	 * 
	 * 4.执行增删改查方法
	 * 
* * @throws IOException */ @Test public void testInsert() throws IOException { SqlSession session = sqlSessionFactory().openSession(true); try { StudentMapper mapper = session.getMapper(StudentMapper.class); Student s = new Student("12344", 32); int nums = mapper.addStudent(s); System.out.println(nums); System.out.println(s.getId()); } finally { session.close(); } } @Test public void testBatchInsert() throws IOException { SqlSession session = sqlSessionFactory().openSession(ExecutorType.BATCH); try { StudentMapper mapper = session.getMapper(StudentMapper.class); Student s = new Student("12344", 32); int nums = mapper.addStudent(s); System.out.println(nums); System.out.println(s.getId()); } finally { session.close(); } } @Test public void testSelectOne() throws IOException { SqlSession session = sqlSessionFactory().openSession(true); try { StudentMapper mapper = session.getMapper(StudentMapper.class); Student s = mapper.findOneById(6L); System.out.println(s); System.out.println(s.getId()); } finally { session.close(); } } @Test public void testSelectAll() throws IOException { SqlSession session = sqlSessionFactory().openSession(true); try { StudentMapper mapper = session.getMapper(StudentMapper.class); List s = mapper.findAll(); System.out.println(s); } finally { session.close(); } } @Test public void testDelete() throws IOException { SqlSession session = sqlSessionFactory().openSession(true); try { StudentMapper mapper = session.getMapper(StudentMapper.class); int result = mapper.deleteById(6L); System.out.println(result); } finally { session.close(); } } @Test public void testUpdate() throws IOException { SqlSession session = sqlSessionFactory().openSession(true); try { StudentMapper mapper = session.getMapper(StudentMapper.class); Student s = new Student("lichangwu", 30); s.setId(6L); int result = mapper.updateStudent(s); System.out.println(result); } finally { session.close(); } }

 

1.获取sqlSessionFactory对象

1.1>创建SqlSessionFactoryBuilder

1.2>build(inputStream)

1.3>创建解析器parser

1.4>解析每一个标签把详细信息保存在Configuration中

1.5>解析mapper.xml

Mapper.xml中的每一个元素信息解析出来并保存在全局配置中,将增删改查标签的每一个标签每一个属性都解析出来,封装成一个MapperdStatement:一个MapperdStatement就代表一个增删改查标签的详细信息

1.6>返回Configuration

1.7>build(Configuration)

1.8>new DefaultSqlSession()

1.9>返回创建的DefaultSqlSession,包含了保存全部配置信息的Configuration

 

2.获取sqlSession对象

2.1>调用openSession()方法

2.2>调用openSessionFromDataSource()

2.3>获取相关信息,创建tx(事务)

2.4>创建执行器:new Executor()

2.5>根据Executor在全局配置中的类型,创建出SimpleExecutor/ReuseExecutor/BatchExecutor

2.6>如果有二级缓存配置开启,创建CachingExecutor(executor)

2.7>executor=(Executor)interceptorChain.pluginAll(executor),使用每一个拦截器重新包装executor并返回

2.8>创建DefaultSqlSession,其中包含Configuration和Executor

2.9>返回DefaultSqlSession

 

 

3.获取接口的代理对象(MapperProxy)

3.1>通过DefaultSqlSession的getMapper(Mapper.class)调用Configuration的getMapper(Class type, SqlSession sqlSession)方法

3.2>通过Configuration的getMapper(Class type, SqlSession sqlSession)调用MapperRegistry的getMapper(Class type,          SqlSession sqlSession)方法

3.3>在MapperRegistry的getMapper(Class type, SqlSession sqlSession)方法中创建Mapper代理工厂MapperProxyFactory

3.4>在MapperRegistry的getMapper(Class type, SqlSession sqlSession)方法中调用MapperProxyFactory的newInstance(sqlSession)方法,创建MapperProxy,他是一个InvocationHandler

3.5>创建MapperProxy的代理对象

3.6>返回MapperProxy的代理对象

 

 

 

4.执行增删改查

4.1>调用MapperProxy的invoke()方法

4.2>判断增删改查的类型

4.3>包装参数作为一个map或者直接返回

4.4>执行sqlSession.selectOne()

4.5>执行selectList()

4.6>获取MapperStatement

4.7>executor.query(ms,xxx,x)

4.8>获取BoundSql对象

4.9>executor.query

4.10>查看本地缓存是否有数据,没有数据就调用queryFromDatabase,查出数据后也会保存在本地缓存

4.11>执行doQuery方法

4.12>创建StatementHandler对象:PreparedStatementHandler

4.13>(StatemenetHandler)interceptorChain.pluginAll(statemenetHandler)

4.14>创建ParameterHandler:(ParameterHandler)interceptorChain.pluginAll(parameterHandler)

4.15>创建ResultSetHandler:(ResultSetHandler)interceptorChain.pluginAll(resultSetHandler)

4.16>预编译sql产生PreparedStatement对象

4.17>调用ParameterHandler设置参数

4.18>调用TypeHandler给sql预编译设置参数

4.19>查出数据使用ResultSetHandler处理结果,使用TypeHandler获取value值

4.20>后续的连接关闭

4.21>返回list的第一个

 

 

上一篇 mybatis缓存

下一篇 获取sqlSessionFactory对象​​​​​​​

 

 

你可能感兴趣的:(mybatis)