mybatis懒加载和缓存

JAVA ginotang 1168℃ 0评论

提升mybatis的性能

任何对数据库的操作都无可避免地出现性能问题,任何频繁读写数据库的操作都是有问题的,为了尽可能提升我们的数据库读写速度,mybatis提供了赖加载和缓存的机制。

使用懒加载

当程序中的JavaBean有关联关系的时候(一对一或者一对多),使用懒加载可以实现关联属性的按需加载,按需加载的意思是当属性在使用的时候才会被加载数据。例如当查询部门员工信息的时候,员工职位并不一定是必须的。又如顾客和订单之间的关系:有时候只需要查询顾客信息,订单信息是非必需的。

开启懒加载

通过在mybatis-conf中的<settings>配置两个属性就可以开启懒加载,这两个属性是:

第一个属性很好理解,当ture的时候就是使用懒加载,反则关闭懒加载。当使用懒加载的时候,第二个属性必须是false,否则无法开启懒加载。这个属性在mybatis<=3.4.1的时候默认是true的,新版本默认false。

添加了这两个配置之后,懒加载机制就已经生效,不过需要注意的是,之前的文章中介绍了两种配置一对多关系的方式,其中方式二是无法享受懒加载的好处的。

使用缓存

缓存的好处是让我们尽量减少对数据库的读写操作,从而减少数据库的IO和提高程序的性能。mybatis中的缓存方式有两种:一级缓存和二级缓存。一级缓存由mybatis内部实现;二级缓存让我们可以利用第三方库提供的缓存方式,例如EhCache或者Redis 默认情况下,一级缓存和二级缓存都是开启的,但是,二级缓存还需要额外的配置。

缓存的作用域

一级缓存的作用域是session隔离的,即是说,相同的sql查询语句的缓存效果只对同一个session对象起作用。

二级缓存的作用域是基于命名空间的(namespace),二级缓存可以跨越多个session共享数据,只要它们处于同一个命名空间之中。

开启二级缓存

mybatis-config配置文件中缓存的全局开关:

如果value等于false,那么无论一级缓存还是二级缓存都不会生效。另外,要二级缓存生效,还需要在Mapper配置文件中打开缓存开关:

两个步骤,二级缓存就可以生效。<cache>可用的参数如下:

参数解释:

eviction:缓存的过期淘汰算法,即按照什么规则去清除缓存,可选值有:”LRU”、”FIFO”、”SOFT”、”WEAK”,默认值是LRU(最近最少使用)

flashInterval:过期时间,单位为毫秒,10000即为10秒,默认值为空,即只要容量足够,缓存永不过期

size:可缓存对象的个数,默认值为1024

readOnly:是否只读,值为true,则所有相同的sql查询语句返回同一个对象(会有线程安全问题),如果值为false,则相同的查询语句访问的是cache的clone副本。

两种缓存的关系

是不是开启二级缓存后,一级缓存就没有用呢?其实不是,mybatis优先使用的是一级缓存,二级缓存是需要被显式写入的(通过commit方法)。先看一段简单的代码来说明问题:

我们关注的是testCache()方法。方法中发出了两次sql查询语句,实际上,运行代码的过程中会发现,sql语句只被执行了一次,也就是说,第二次的结果是从一级缓存中获取的。

什么时候缓存会被更新

如果使用了缓存,我们面对的问题常常是:这些数据是最新的吗?换句话说,这些被缓存的数据会不会是脏数据。为了解决这个问题,mybatis的做法是,当数据有可能发生变更的时候,就会主动清除缓存。一般来说,会对数据产生影响的sql语句无非就是插入(insert)、删除(delete)、更新(update)。

下面是测试代码:

从控制台日输出可见,sql语句发送了两次(二级缓存未开启之前),印证了我们的说法。

什么时候会使用二级缓存

这个“使用”需要分开两个部分来说,即读取缓存和写入缓存。从控制台的输出来看,当Mapper的二级缓存开启的时候,每次执行sql查询语句之前,都会先从二级缓存中尝试获取数据,二级缓存没有匹配再查询一级缓存:

如果控制台中看到Cache Hit Ratio(缓存命中率)字样,证明二级缓存已经开启。

二级缓存中的数据是在sqlSession.commit()方法被调用的时候写入的,当然,sqlSession.close()方法也会触发二级缓存的发生,原因在于close之前会先调用commit方法。

测试代码:

控制台输出日志:

Cache Hit Ratio只要不为0,就证明数据是从二级缓存中获取的。

使用EHCACHE缓存库

Mapper配置文件中的<cache>元素有一个属性type,type属性用于指定我们用于缓存的具体对象类型。

在mybatis中整合ehcache需要另外导入mybatis-ehcache包。该包中有两个类:LoggingEhcache和EhcacheCache,只需要在type属性中指定这两个类中的任意一个即可。

 

转载请注明:Pure nonsense » mybatis懒加载和缓存

喜欢 (0)
0 0 投票数
文章评分
订阅评论
提醒
guest
0 评论
内联反馈
查看所有评论
0
希望看到您的想法,请您发表评论x
()
x