Mybatis源码学习(二)缓存和别名处理器

缓存

一级缓存

Mybatis的一级缓存默认是开启的,并且,是SqlSession级别的,在默认情况下,是要是同一个SqlSession,就会复用相同的缓存,但是在使用flushCache="true"(这个是配置在SQL上的)可以在SQL执行之前flush掉缓存。同时,如果执行了insertupdatedelete等操作,也会清除一级缓存
重点:一级缓存仅仅是跟SqlSession相关的
采坑:一级缓存缓存是查询的结果,如果查询结果是个POJO,那么千万千万不要修改查询出来的结果,一旦修改了查询结果,那么会导致一级缓存的结果被修改。当然了,关掉解千愁,缓存就用专门的缓存好了,不应该打到数据库的查询就不要打到数据库。一旦查询打到数据库了,就应该明明白白的返回数据库的数据。

二级缓存

Mybatis的二级缓存默认是关闭的,可以通过配置开启,开启后,还需要在SQL上手动设置useCache="true"。二级缓存是SQLSessionFactory级别的,同一个SQLSessionFactory会使用同一个二级缓存。当然你可以自己实现org.apache.ibatis.cache.Cache然后配置到xml里面,这样你就可以接管Mybatis的二级缓存了,同样可以打破不同的SQLSessionFactory不能共享缓存的限制

缓存总结

关掉解千愁,缓存就用专门的缓存好了,不应该打到数据库的查询就不要打到数据库。一旦查询打到数据库了,就应该明明白白的返回数据库的数据

尤其是分布式环境下,二级缓存非常容易脏读

typeAliases

这个是用来解析别名的,支持两种方式

<package name="com.xxx"/>
<typeAlias type="com.xxx.A" alias="AC"/>

第二种是直接配置类和别名的对应关系,理解起来也比较简单,但是如果类很多的话,这个配置量会很大
第一种配置方式直接配置package,程序会自动扫描package下的所有类,如果类上有@Alias注解,那就用注解的别名,如果类上没有,那就用类的SimpleName作为别名
在做package扫描时,主要调用的下面这段代码org.apache.ibatis.type.TypeAliasRegistry#registerAliases
在这里插入图片描述
关键代码是resolverUtil.find,我们再往里面看
在这里插入图片描述
关键代码是VFS.getInstance().list(path) 这里体现了一个设计模式“单例模式”

VFS单例

单例一般分为懒汉、饿汉。我之前最常用的方式是用synchronized实现懒汉,但是今天学到了。VFS的单例是基于静态内部类实现的单例。源码如下:
在这里插入图片描述
可以看出来getInstance方法返回的是VFSHolder.INSTANCE
在这里插入图片描述
从这两个代码片段中可以看出来,当VFS被加载时,VFS的实例还没有被创建,所以这应该属于懒汉模式。当外部调用getInstance时,首先要加载VFSHolder这个类,重点来了类的加载是线程互斥的,而且由于双亲委派,一个类只会被加载一次,也就保证了VFSHolder中的INSTANCE只有一个。同时,代码里没有锁,很干净,效率也更好。

神奇的目录遍历方式

DefaultVFS中是这样实现的包扫描,下面代码片段来自org.apache.ibatis.io.DefaultVFS#list
在这里插入图片描述
大概的思想是拿到url,然后获得这个url的InputStream,将InputStream包装为InputStreamReader,再包装为BufferedReader,最后reader.readLine(),这样可以把目录结构一行一行的读出来,最后再递归。
之前的目录遍历一般都是通过File接口做的,new File(xxx),然后list,然后判断是否为目录,再递归。Spring的包扫描也是基于File的,但是上面的这个做法第一次见,值的学习。

最后,别名注册的逻辑就是这里了org.apache.ibatis.type.TypeAliasRegistry#registerAlias
在这里插入图片描述
最后的这个注册逻辑也体现了如果有注解就用注解,如果没有注解,就用SimpleName,同时别名是大小写不敏感的。如果出现别名相同的情况,那么会抛出异常。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值