从源码角度看,mybatis是十分优秀的源码,其设计思路清晰简洁,虽然代码复杂度不高(相较于某些复杂源码)但麻雀虽小五脏俱全,非常适合拿来学习分析。
通过本次分享,希望收获如下:
1.Configuration:保存配置、sql,实体映射等各项配置(mybatis-config.xml,mapper.xml)
2.Executor:与数据库进行交互,真正干活的
3.SqlSession:外交官,与用户请求直接打交道,拿到请求后把活分下去,内部定义了getMapper和CRUD的方法,getMapper委派给Configuration,CRUD委派给Executor
Q:mybatis暴露给用户使用的是interface(*Mapper.java),并没有具体的实现类,那是如何实现CRUD的呢?
A:一定是通过代理实现的!
对于JDK动态代理,一定需要一个被代理实体类,但是mybatis只有interface,那么他是如何实现的动态代理呢?
4.MapperProxy的引入:
mybatis引入MapperProxy实体类,该类没有具体含义,仅作为媒介,将sqlSession引入,调用SqlSession中定义的CRUD方法,个人将该Proxy理解为“运输车”
经过上述分析后,mybatis执行的核心流程如下:
demo参考
了解了mybatis的核心组成之后,对于v1版本代码面向对象、面向接口,并加入设计模式,渐渐就变成了我们看不懂的亚子
1、SqlSessionFactoryBuilder.build()(method级别) -> Configuration(app级别) and SqlSessionFactory(app级别)
2、SqlSessionFactory.openSession() -> Configuration.newExecutor() -> DefaultSqlSession(configuration, executor)
3、SqlSession.getMapper() -> Configuration.getMapper() -> MapperRegistry.getMapper() -> new MapperProxyFacory() -> Proxy.newInstance(new MapperProxy(SqlSession))
4、*Mapper.selectByPrimaryKey -> MapperProxy.invoke() -> SqlSession.selectOne() -> Executor.query()
5、ParameterHandler.prepareStatement() -> handler.query() -> ResultSetHanlder.handleResultSets()
Q:对于分页要么手写sql,要么使用pagehelper,不会使用mybatis的分页,为什么?
A:逻辑分页,查询全部后遍历。。。
Q:为什么一级缓存是session级别,二级缓存是namespace级别?
A:一级缓存:openSession->newExecutor->newPerpetualCache
二级缓存:装饰者模式,从Cache里取的,Cache由Configuration的MappedStatement持有
Q:mybatis接入dtracker如何实现的?
A:基于plugin
Q:plugin的局限性是什么?为什么会有这种局限性
A:局限性是,实现的plugin仅能作用于Executor、ParameterHandler、ResultSetHandler、StatementHandler,mybatis官方文档
产生该局限性是因为仅这几个功能被包装
0)修炼内功
1)找入口:从programming开始
2)关注源码核心模块功能,做到看类图识功能
3)条件允许,手写源码印象更深
1、工厂模式——factory
2、单例模式——singleton
3、原型模式——proto
4、建造者模式——builder
5、适配器模式——adapter
6、装饰器模式——decorator、wrapper
7、代理模式——proxy
8、责任链模式——chain
9、观察者模式——observer、monitor、listener
10、策略模式——strategy
11、模板模式——template
12、委派模式——delegate、dispatcher