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

上一篇 mybatis缓存

下一篇 获取sqlSessionFactory对象

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

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

先提示一下,阅读源码,要注意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)
	 * 
	 * <pre>
	 * 1.获取sqlSessionFactory对象
	 *    1.1解析文件的每一个信息保存在configuration对象中,返回包含configuration的DefaultSqlSessionFactory.
	 *       注意:MappedStatement,代表对一个的一个增删改查sql详细信息
	 *       
	 * 2.获取SqlSession对象
	 *   2.1返回一个DefaultSqlSession对象,包含一个executor和configuration对象
	 * 3.获取接口的代理对象MapperProxy
	 * 
	 * 4.执行增删改查方法
	 * </pre>
	 * 
	 * @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<Student> 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<T> type, SqlSession sqlSession)方法

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

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

3.4>在MapperRegistry的getMapper(Class<T> 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对象​​​​​​​

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值