Mybatis
文章目录
mybatis加载过程
-
Config.xml全局配置文件解析放到configuration对象中,Java中的注解配置及SQL配置文件封装到statement对象中存储在内存,同样由configuration对象来维护
-
映射文件加载:mappedStatement对象解析sql,每个sql对象对应一个statementID,将解析后的sql存储到map中,key就是statementId,value就是解析后的sql,存储到sqlsource中
-
sqlSource存储sql信息,还提供对sql的解析功能
dynamicsqlSource:${}解析这种动态sql
RawsqlSource:#{}解析这种动态sql
StaticsqlSource:将以上两种sql解析后,存储到sqlSource,通过这个sqlSource可以获取到BoundSql
结合staticSqlSource源码理解会会更容易些
public class StaticSqlSource implements SqlSource {
private final String sql;
private final List<ParameterMapping> parameterMappings;
private final Configuration configuration;
public StaticSqlSource(Configuration configuration, String sql) {
this(configuration, sql, null);
}
public StaticSqlSource(Configuration configuration, String sql, List<ParameterMapping> parameterMappings) {
this.sql = sql;
this.parameterMappings = parameterMappings;
this.configuration = configuration;
}
@Override
public BoundSql getBoundSql(Object parameterObject) {
return new BoundSql(configuration, sql, parameterMappings, parameterObject);
}
}
-
BoundSql:
String sql;解析后的s q l
List ParameterMappings; 对应传入的参数
sqlNode :树状结构
sqlSource存储sql信息,是通过sqlNode 的集合
Mybatis 一级缓存
mybatis是有一级缓存和二级缓存的
一级缓存
介绍
一级缓存是基于sqlSession的
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
sqlSession = sqlSessionFactory.openSession();
DemoMapper demoMapper = sqlSession.getMapper(DemoMapper.class);
// 第一次查询
Demo demo1 = demoMapper.findById(1);
// 第二次查询
Demo demo2 = demoMapper.findById(1);
上述代码,两次连续使用同一sqlSession进行查询,第一次查询确实会对数据库进行连接查询,而到第二次的时候,则会去mybatis的一级缓存中去取。也就是第一次查询后,会将查询结果存储到一级缓存,之后则再次查询会在一级缓存中去查找,匹配到则返回,匹配不到再去数据库中查询。
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
sqlSession = sqlSessionFactory.openSession();
DemoMapper demoMapper = sqlSession.getMapper(DemoMapper.class);
// 第一次查询
Demo demo1 = demoMapper.findById(1);
//更新
Demo demo = new User();
demo.setId(1);
demo.setName("test");
demoMapper.updateDemo(demo);
// 第二次查询
Demo demo2 = demoMapper.findById(1);
上述代码,在第一次查询后,又对数据进行了update,再第二次查询。
过程:
- 第一次查询对数据库进行连接查询,并将查询结果存储到一级缓存。
- 在将数据update,update操作会执行清空一级缓存,所以此时一级缓存中对应的缓存被清空了。update,delete, insert等操作会清空一级缓存来避免脏读
- 在进行第二次查询时,一级缓存中并不会获取到,所以去数据库中查询。
源码分析
我们找到SqlSesion接口.其中看起来对一级缓存有作用的也就是一个clearCache()方法