MyBatis(设置参数、延迟加载、缓存)

settings设置参数:

 

设置项

描述

允许值

默认值

cacheEnabled

对在此配置文件下的所有cache 进行全

局性开/关设置。

true | false

true

lazyLoadingEnabled

全局性设置懒加载。如果设为‘关’,

则所有相关联的都会被初始化加载。

true | false

true

aggressiveLazyLoading

当设置为‘开’的时候,懒加载的对象

可能被任何懒属性全部加载。否则,每

个属性都按需加载。

true | false

true

multipleResultSetsEnabled

允许和不允许单条语句返回多个数据

集(取决于驱动需求)

true | false

true

useColumnLabel

使用列标签代替列名称。不用的驱动器

有不同的作法。参考一下驱动器文档,

或者用这两个不同的选项进行测试一

下。

true | false

true

useGeneratedKeys

允许JDBC 生成主键。需要驱动器支持。

如果设为了true,这个设置将强制使用

被生成的主键,有一些驱动器不兼容不

过仍然可以执行。

true | false

False

autoMappingBehavior

指定MyBatis 是否并且如何来自动映射

数据表字段与对象的属性。PARTIAL

将只自动映射简单的,没有嵌套的结

果。FULL 将自动映射所有复杂的结果。

NONE,

PARTIAL,

FULL

PARTIAL

defaultExecutorType

配置和设定执行器,SIMPLE 执行器执

行其它语句。REUSE 执行器可能重复

使用prepared statements 语句,BATCH

执行器可以重复执行语句和批量更新。

SIMPLE

REUSE

BATCH

SIMPLE

defaultStatementTimeout

设置一个时限,以决定让驱动器等待数

据库回应的多长时间为超时

正整数

Not Set

(null)

 

mybatis的延迟加载 

延迟加载的意思是说,在关联查询时,利用延迟加载,先加载主信息。使用关联信息时再去加载关联信息。

         要设置延迟加载,需要在SqlMapConfig.xml文件中,在<settings>标签中设置下延迟加载:lazyLoadingEnabled、aggressiveLazyLoading

代码演示如下:

<!-- 开启延迟加载 -->
<settings>
    <!-- lazyLoadingEnabled:延迟加载启动,默认是false -->
    <setting name="lazyLoadingEnabled" value="true" />
    <!-- aggressiveLazyLoading:积极的懒加载,false的话按需加载,默认是true -->
    <setting name="aggressiveLazyLoading" value="false" />
</settings>

mybatis的缓存

许多应用程序,为了提高性能而增加缓存, 特别是从数据库中获取的数据.mybatis中对于缓存的使用,类似于hibernate的缓存机制,分为一级缓存和二级缓存

 

1.mybatis的一级缓存

mybatis的一级缓存是基于sqlSession的。

         在同一个连接范围内,执行相同的查询SQL,第一次会去查询数据库,并写到缓存中;第二次直接从缓存中取。

         当执行SQL时两次查询中间发生了增删改操作或者数据库连接关闭,则SqlSession的缓存清空。

         与hibernate的一级缓存不一样,mybatis的一级缓存,可以用于所有的查询(hibernate中的一级缓存只针对根据主键查对象,而mybatis中查询全部时一级缓存也有效)

         一级缓存的原理如下图:

 

 2.mybatis的二级缓存

如果要实现 mybatis 的二级缓存,一般来说有如下两种方式:
         i. 采用 mybatis 内置的 cache 机制。
         ii. 采用三方 cache 框架, 比如ehcache, oscache 等等.

  

  mybatis内置的缓存机制

在 sql 语句映射文件中加入 <cache /> 语句 , 并且相应的实体类要实现 Serializable 接口,因为缓存说白了就是序列化与反序列化的过程,所以需要实现这个接口. 单纯的 <cache /> 表示如下意思:

         1.所有在映射文件里的 select 语句都将被缓存。
         2.所有在映射文件里 insert,update 和 delete 语句会清空缓存。
         3.缓存使用“最近很少使用”算法来回收
         4.缓存不会被设定的时间所清空。
         5.每个缓存可以存储 1024 个列表或对象的引用(不管查询出来的结果是什么) 。
         6.缓存将作为“读/写”缓存,意味着获取的对象不是共享的且对调用者是安全的。不会有其它的调用者或线程潜在修改。

         对于mybatis中的二级缓存:

         mybatis中二级缓存是基于mapper级别的。不同的实体映射文件,二级缓存是不共享的;

         mybatis默认没有开启二级缓存;

         第一次调用mapper下的SQL去查询用户信息。查询到的信息会存到该mapper对应的二级缓存区域内;

         第二次调用相同namespace下的mapper映射文件中相同的SQL去查询用户信息。会去对应的二级缓存内取结果;

         如果调用相同namespace下的mapper映射文件中的增删改SQL,并执行了commit操作。此时会清空该namespace下的二级缓存;

         二级缓存的原理图如下:

 

 

mybatis中应用二级缓存,操作步骤如下:

1. 在mybatis的配置文件中,开启二级缓存(cacheEnabled设置为 true).

         在mybatis_config.xml文件中,设置如下:

<settings>
    <!-- 开启二级缓存,默认为false(默认二级缓存是关闭的) -->
    <setting name="cacheEnabled" value="true"/>
</settings>

 

2. 在实体映射文件中,应用二级缓存:

<cache eviction='FIFO' flushInterval='60000' size='512' readOnly='true'/>

其中各项属性代表的含义为:

         flushInterval(刷新间隔)可以被设置为任意的正整数,而且它们代表一个合理的毫秒形式的时间段。默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。

         size(引用数目)可以被设置为任意正整数,要记住你缓存的对象数目和你运行环境的可用内存资源数目。默认值是1024。

         readOnly(只读)属性可以被设置为true或false。只读的缓存会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。可读写的缓存会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是false。

         eviction配置创建了一个 FIFO 缓存,并每隔 60 秒刷新,存数结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此在不同线程中的调用者之间修改它们会导致冲突。可用的收回策略有, 默认的是 LRU:

         1.      LRU – 最近最少使用的:移除最长时间不被使用的对象。

         2.      FIFO – 先进先出:按对象进入缓存的顺序来移除它们。

         3.      SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。

         4.      WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。

3. 缓存对象执行序列化

         由于二级缓存的数据不一定都是存储到内存中,它的存储介质多种多样,所以需要给缓存的对象执行序列化。

         如果该类存在父类,那么父类也要实现序列化,类似如下写法:

public class Emp implements Serializable {
  ...
}

至此,二级缓存可以使用了。

另外,在应用二级缓存过程中,我们还可以禁用二级缓存:

<!-- 查询全部员工信息 -->
<select id="findallEmp" resultType="cn.jbit.pojo.Emp" useCache="false">
    select empno, ename, job, mgr, hiredate, sal, comm, deptno from emp
</select>

该statement中设置userCache=false可以禁用当前select语句的二级缓存,即每次查询都是去数据库中查询,默认情况下是true,即该statement使用二级缓存.

还可以刷新二级缓存:

<!-- 查询全部员工信息 -->
<select id="findallEmp" resultType="cn.jbit.pojo.Emp" flushCache="true">
    select empno, ename, job, mgr, hiredate, sal, comm, deptno from emp
</select>

 

应用第三方缓存框架ehcache

ehcache是一个分布式缓存框架。

         EhCache 是一个纯Java的进程内缓存框架,是一种广泛使用的开源Java分布式缓存,具有快速、精干等特点,是Hibernate中默认的CacheProvider。

         mybatis提供了一个cache接口,如果要实现自己的缓存逻辑,实现cache接口开发即可。

mybatis和ehcache整合,mybatis和ehcache整合包中提供了一个cache接口的实现类:

1. 准备jar包

         可以到github上下载,路径如下:

         https://github.com/mybatis/ehcache-cache/releases

         下载后可以找到三个jar包:

                  1. mybatis-ehcache-1.0.3.jar

                  2. ehcache-core-2.6.8.jar

                  3. slf4j-api-1.6.1.jar

         其中,mybatis本身已经带了slf4j-api包,所以只需要拷贝前两个jar包即可

2. 整合Ehcache

         在项目的src目录下,新建ehcache.xml文件,文件内容如下:

<ehcache>
    <!--表示硬盘上保存缓存的位置。默认是临时文件夹。-->
    <diskStore path="java.io.tmpdir"/>
    <!--默认缓存配置,如果类没有做特定的设置,则使用这里配置的缓存属性。
       maxInMemory  - 设置缓存中允许保存的最大对象(pojo)数量
       eternal -设置对象是否永久保存,如果为true,则缓存中的数据永远不销毁,一直保存。
       timeToIdleSeconds - 设置空闲销毁时间。只有eternal为false时才起作用。表示从现在到上次访问时间如果超过这个值,则缓存数据销毁
       timeToLiveSeconds-设置活动销毁时间。表示从现在到缓存创建时间如果超过这个值,则缓存自动销毁
       overflowToDisk - 设置是否在超过保存数量时,将超出的部分保存到硬盘上。-->
    <defaultCache
        maxElementsInMemory="1500"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="300"
        overflowToDisk="true"/>
<!-- 也可以通过name设置针对某个类的缓存配置
    <cache name="cn.sz.po.Emp"
        maxElementsInMemory="1000"
        eternal="true"
        timeToIdleSeconds="0"
        timeToLiveSeconds="0"
        overflowToDisk="false"
        />-->
</ehcache>

这个ehcache.xml的写法与在hibernate中写法完全一致

 

3. sql映射文件中配置cache:

打开需要缓存的实体映射文件(比如Emp.xml),加上cache,并指定处理缓存的实现类:

<cache type="org.mybatis.caches.ehcache.LoggingEhcache" > 
        <property name="timeToIdleSeconds" value="3600"/>
        <property name="timeToLiveSeconds" value="3600"/>
        <!-- 同ehcache参数maxElementsInMemory-->
        <property name="maxEntriesLocalHeap" value="1000"/>
         <!-- 同ehcache参数maxElementsOnDisk -->
        <property name="maxEntriesLocalDisk" value="10000000"/>
        <property name="memoryStoreEvictionPolicy" value="LRU"/>
</cache>

 

这个配置是会带上cache执行的日志,如果不要带日志可以把LogginEhcache改成EhcacheCache,如下:

<!-- 如果不需要缓存日志,也可以改为EhCacheCache -->
<cache type="org.mybatis.caches.ehcache.EhcacheCache"></cache>

至此,ehcache缓存就配置起来了

另,如果与spring集成,除了需要完成上面的三步以外,还需要在spring的配置文件里面加上一段配置:

<bean id="manager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:ehcache.xml"></property>
</bean>

最后,这个mapper.xml里面的操作是全局,默认为useCache="true"  都会有作用,

假如某个业务是不要缓存的,可以在当前业务下加上useCache="false"

 

 

mybatis与hibernate的区别:

1.缓存

2.mybatis需要自己编写sql;hibernate则是生成(不需要自己编写sql)

3.在项目需要更换数据库时,hibernate更容易切换,mybatis相对更加繁琐(因为不同数据库,sql写法可能有区别)

4.性能上,mybatis性能相对更好(因为直接执行现有的sql),hibernate性能相对较差(需要根据对象自动拼接sql)

 

posted @ 2020-07-15 10:47  IT搬砖者  阅读(586)  评论(0编辑  收藏  举报