mybatis源码简析
1.sqlSession线程安全问题
SqlSession线程不安全
SqlSessionManager线程安全,因为SqlSessionManager中的sqlSession是交给ThreadLocal管理。
SqlSessionTemplate线程安全,因为它是从TransactionSynchronizationManager中获取,实现也是ThreadLocal。
1.1SqlSessionManager代码片段
1.2SqlSessionTemplate代码片段
1.2.1SqlSessionTemplate构造函数
1.2.2代理类
1.2.3获取sqlSession
1.2.4resource是ThreadLocal
2 mybatis初始化
2.1 Configuration类
这个类在org.apache.ibatis.session包下,简单说几个。
2.1.1扫描实体
2.1.2 解析xml,bindMapperForNamespace绑定mapper和xml关系
2.1.3 创建这个对象的动态代理实例
我们写mapper接口都不会去写它的实现方法就是因为在初始化config类的时候,会用动态代理来处理真正的数据库操作,也就是我们在mapper.xml里定义的sql。
2.1.4 获取mapper对象同时创建动态代理对象
获取mapper 对象
动态代理类
2.1.5 MapperProxy中用命令模式处理具体sql
3 一个查询的生命周期
假设我们现在有个TestMapper.java,里面有个方法selectByPrimaryKey。
还有个TestMapper.xml,里面有对应的xml配置。我们来看下当我们调用
testMapper.selectByPrimaryKey()这个方法时mybatis干了些啥。
3.1 动态代理
我们调用testMapper.selectByPrimaryKey的时候,首先会被2.1.4中的动态代理类来处理(什么是动态代理这里就不说了)。
如果是代理类中的方法,则直接执行。这里我们我们是自己建的testMapper,所以走下面的逻辑mapperMethod.execute(sqlSession, args)。
备注 MapperMethod 包含执行的是哪种命令,执行的sql及执行结果的一些信息。这些信息来自2.1的config类中buildAllStatements,初始化的时候解析的xml会写到MappedStatement中。
3.2 命令模式
mapperMethod.execute执行采用到是命令模式来执行对应到操作。SqlCommandType.SELECT对应到就是xml中到select标签。
method.returnsMap()对应到就是resultMap属性。
3.3 selectOne
本质其实就是selectList限制最多返回1条数据。
从config中获取mappedStatement
3.4 CachingExecutor
这里82行设置到是一级缓存到key,同一个session生效
这里下面先看一级缓存,如果一级缓存没数据再查数据库
delegate在这里可以确定,示例中走的是SimpleExecutor