Mybatis运行原理

getSqlSessionFactory

	1.new SqlSessionFactoryBuilder().bulid(全局配置文件的流in)
	2.build(in)  进入build(in)
	3.parser = new XMLconfigurationBuilder(in) 创建解析器解析 全局配置文件  
	  build(parser.parse()) 进入parse() 方法
	4.parse()最后返回的 是 configuration
	  parseConfiguration(parse.evalNode("/configuration")) 解析全局配置文件configuration节点
	5.解析每一个标签,set configuration
	6.mapperParser = new XMLMappedBuilder(mapper.xml的 流 )
	7.解析 mapper.xml,并且保存在configuration中,并且将mapper.xml中crud标签的每一个标签都解析出来
	  封装成一个mappedStatement,并将它add configuration
	 (一个mappedStatnebt代表一个crud标签的 详细信息)
	8.返回configuration   build(parser.parse())  结束
	9.build(in),结束返回一个  new DefaultSqlSessionFactory(configuration)
	  返回一个sqlSessionFactory
	10.configuration中的两个重要信息
		1.mapperStatement(保存每一个mapper.xml 中的 每一个crud的标签信息)
		2.mapperRegister 中有一个knowMappers(保存了 每一个 mapper.xml 对应的 接口信息 mapperProxyFactory)
		  用它可以拿到,mapperProxy

openSession()

	1.return openSessionFromDataSource(configuration.getDefalutExecutorType,...)
	  getDefaultExecutorType 拿到执行器的类型
	  默认是Simple,还有 REUSE(可复用的执行器),BATCH(可批量操作的执行器)
	2.进入 openSessionFromDataSource
		1.configuration.getEnvironment()
		  configuration.getTransation() 
		  获得 全局配置文件的 环境,事务等信息
		2.Executor executor = configuration.newExecutor(tx,execType) 四大对象之一
		  默认拿到的 是 SimpleExecutor(根据 exeTpye 的值 创建不同的 executor)
		  下面都是对 executor的 封装
		3.if(cacheEnabled) 是否配置了二级缓存
		  若是,将executor包装成 cachingExecutor
		  executor = new CachingExecutor(executor)
		  包装的好处:在查询之前先用cachingExecutor查询缓存,然后再用executor去查询
		4.executor = (Executor) interceptorChain.piuginAll(executor)
		  这是最终的executor,拦截器链连接executor,然后用每一个拦截器包装executor
		  最终返回executor
		5.return DefalutSqlSession(configuration.executor,autoCommit)
		  最终返回一个defalutSqlSession(包含 configuration,和 executor)

session.getMapper 获得代理对象

	1.session.getMapper(mapper.class)
	2.进入这个方法,return configuration.getMapper(mapper.class,this),this代表session
	3.进入这个方法,return mapperRegister.getMapper(mapper.class,sqlSession)
	4.进入这个方法,先拿到 mapperProxyFactory
	MapperProxyFactory<T> mapperProxyFactory =(MapperProxyFactory<T>) knowMappers.get(mapperType)
	根据接口的类型,拿到对应的mapperProxyFactory
	5.return mapperProxyFactory.newInstance(sqlSession)
		1.先拿到 mapperProxy 这是InvocationHander,里面包含接口,接口方法,sqlSession,他不是代理对象
		2. return newInstance(mapperProxy) 进入这个方法
		2.return (T)Proxy.newProxyInstance(),创建mapperProxy的代理对象
	6.最终返回,mapperProxy的代理对象

mapper执行方法

	1.MapperProxy的invoke(Object proxy,Method method,Object[] args)
		1.把 method 包装成 MapperMethod(Mybatis可以识别的)
		  MapperMethod里面有 sqlCommand属性 和 MethodSignature属性
		2.method.execute(sqlSession,args)
			1.判断sql的类型 command的类型
			2.method.converArgsCommandParam(args)
		    3.调用sqlSession.select(String statement,params)  statement就是 mapperStatement的 id 
		    	1.mapperStatement ms = configuration.getMapperStatement(statement)
		    	2.return executor.query(ms,parameter,......)
				   进入 executor.query
					 	1.BoundSql boundSql = ms.getBoundSql(param) boundSql包含了sql语句的详情
					 	2.创建二级缓存的key CacheKey key
					 	3.return executor.query(ms,param,boundsql,ley......)
					 		1.获取二级缓存 cache(是整体的二级缓存,先拿到后面在去取值)
					 		2.executor.query(ms,param.....),这个executor和前面两个不一样
					 		  这个是解封装后的,simpleExecutor
					 			1.cache.getObject(key)  先从二级缓存拿,没有的话
					 			2.localcache.getObject(key) 从一级缓存中拿,没有的话
					 			3.queryFromDatabase(ms,param....)
					 				1.localcache.putObject(key,占位符) 
					 				2.list = doQuery(ms....) 查出数据
					 				3.localcache.putObject(key,list)
										  进入doQuery(ms..)
											1.声明 Statment stms = null;
											2.拿取 mapperStatment的配置信息 config
											3.StatementHandler handler = config.newStatementHandler() 创建 statementHandler
												进入newStatementHandler() 
													1.StatementHandler handler = new RoutingStatementHandler() 创建statementHandler
														1.ms.getStatementType 默认 preparedStatement
														2.new preparedStatementHandler()
													2.和 executor一样,handler创建出来,得经过 拦截器链的封装获得 封装后的 handler
													3.handler获取完成
											(注意,在创建statementHandler的同时构造器,也创建了ParameterHandler,和ResultSetHandler)
											4.用statementHandler创建一个 prepareStatment赋值给stmt
											  stmt = prepareStatement(handler,ms...)
											  		1.获取连接
											  		2.参数预编译以及参数set进入sql语句
											  			1.获取prepareStatement的时候进行了预编译
											  			2.用ParameterHandler给 预编译后的sql语句 填充占位符
											  				期间使用TypeHandler 来做类型转换
											 5.return handler.query(stmt,resultHandler) 执行sql返回回结果集
											   最终是 stmt来完成执行sql,并且用resultSetHandler来封装结果集
											   结果集的封装也要用到TypeHandler做映射

sqlSessionFactory(包含configuration)

sqlSession(包含了configuration,executor)

mapperProxy(包含sqlSession),他是invocationHandler,不是mapper接收的代理对象,执行mapper在执行的时候会跳到mapperProxy的invoke方法中去

四大对象的创建后,都经过了interceptchain拦截器链的包装,形成新的对象

prepareStatement在获取的时候就进行了预编译,以及用parameterHandler 填充了占位符

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值