`
liyixing1
  • 浏览: 959298 次
  • 性别: Icon_minigender_1
  • 来自: 江西上饶
社区版块
存档分类
最新评论

ibatis缓存

阅读更多
ibatis的session缓存。做了一个测试
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.liyixing.ibatis.dao.IAccountDao">
<resultMap type="com.liyixing.ibatis.model.Account" id="account">
<id property="id" column="ID" />
<result property="userName" column="USER_NAME" />
<collection property="messages" javaType="ArrayList"
column="ID" ofType="com.liyixing.ibatis.model.Message" select="getMyMessage">
</collection>
</resultMap>

<select id="getMyMessage" parameterType="_int" resultMap="message">
SELECT
ID,
USER_ID,
MESSAGE,
MESSAGE_TYPE
FROM message
WHERE USER_ID = #{id}
</select>

<select id="getAccount" parameterType="_int" resultMap="account">
SELECT *
FROM account WHERE ID = #{id}
</select>

<select id="getAccountByName" parameterType="string" resultMap="account">
SELECT *
FROM account WHERE USER_NAME = #{userName}
</select>
</mapper>

在没有做和缓存相关的任何配置前
Reader reader = Resources
.getResourceAsReader("com/liyixing/ibatis/data/ibatis.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder()
.build(reader);
SqlSession session = factory.openSession();
IAccountDao accountDao = session.getMapper(IAccountDao.class);
Account account0 = accountDao.getAccount(1);
Account account1 = accountDao.getAccount(1);
Account account2 = accountDao.getAccountByName("liyixing");
Account account3 = accountDao.getAccountByName("liyixing");
这里account0,account1,account2,account3 四个对象,在eclipse的debug可以看到对象的唯一标示id



account0,account1通过同一个方法(select id="getAccount")来获取的
发现account0,account1是同一个对象。因此得出默认的ibatis开启了session缓存。
account2与account3相同,但是和account0,account1他两的对象标示不相同。说明默认的ibatis的缓存是针对select id,来处理的。

修改配置
<settings>
<setting name="cacheEnabled" value="false" />
</settings>
结果相同和上面相同。


update对其的影响
Reader reader = Resources
.getResourceAsReader("com/liyixing/ibatis/data/ibatis.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder()
.build(reader);
SqlSession session = factory.openSession();
IAccountDao accountDao = session.getMapper(IAccountDao.class);
Account account0 = accountDao.getAccount(1);
Account account1 = accountDao.getAccount(1);
Account account2 = accountDao.getAccountByName("liyixing");
Account account3 = accountDao.getAccountByName("liyixing");
int x = accountDao.updateAccount(1);
Account account5 = accountDao.getAccount(1);
Account account6 = accountDao.getAccountByName("liyixing");
Account account7 = accountDao.getAccountByName("liyi");
这里有一句修改的语句




可以看出来,account5在修改之后,查询的,是一个新的对象,可以得出update是会清理缓存。
Account account6 = accountDao.getAccountByName("liyixing");
Account account7 = accountDao.getAccountByName("liyi");
可以看出update清理的缓存是全局的。那么会不会只是针对对象的主键来清理缓存的呢?
Reader reader = Resources
.getResourceAsReader("com/liyixing/ibatis/data/ibatis.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder()
.build(reader);
SqlSession session = factory.openSession();
IAccountDao accountDao = session.getMapper(IAccountDao.class);
Account account0 = accountDao.getAccount(1);
Account account1 = accountDao.getAccount(1);
Account account2 = accountDao.getAccountByName("liyixing");
Account account3 = accountDao.getAccountByName("liyixing");
Account account8 = accountDao.getAccountByName("liyimao");
int x = accountDao.updateAccount(1);
Account account5 = accountDao.getAccount(1);
Account account6 = accountDao.getAccountByName("liyixing");
Account account7 = accountDao.getAccountByName("liyi");
Account account9 = accountDao.getAccountByName("liyimao");
这里的name liyixing和liyimao是两个不同的主键值。
然后修改发现account8,和account9也是不同的对象。因此得出update清理的缓存涉及的范围很广。至于会不会影响到其他对象,比如Message对象呢?
Reader reader = Resources
.getResourceAsReader("com/liyixing/ibatis/data/ibatis.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder()
.build(reader);
SqlSession session = factory.openSession();
IAccountDao accountDao = session.getMapper(IAccountDao.class);
IMessageDao messageDao = session.getMapper(IMessageDao.class);
Account account0 = accountDao.getAccount(1);
Account account1 = accountDao.getAccount(1);
Account account2 = accountDao.getAccountByName("liyixing");
Account account3 = accountDao.getAccountByName("liyixing");
Account account8 = accountDao.getAccountByName("liyimao");
Message message0 = messageDao.getMessage(1);
Message message2 = messageDao.getMessage(1);
int x = accountDao.updateAccount(1);
Message message1 = messageDao.getMessage(1);
Account account5 = accountDao.getAccount(1);
Account account6 = accountDao.getAccountByName("liyixing");
Account account7 = accountDao.getAccountByName("liyi");
Account account9 = accountDao.getAccountByName("liyimao");

System.out.println("age:" + account0.getMessages().size());
debug


可以看出来其他对象也影响了。

上面的调试结果,可以从源码中看出来。
但是源码的话看起来可能需要更多的时间。因此做了这个测试。

不同的session中,缓存是不共享的。


二级缓存,在sql映射文件中
<cache/>
语句的效果如下:
 映射语句文件中的所有select语句将会被缓存。
 映射语句文件中的所有insert,update和delete语句会刷新缓存。
 缓存会使用Least Recently Used(LRU,最近最少使用的)算法来收回。
 根据时间表(比如no Flush Interval,没有刷新间隔),缓存不会以任何时间顺序来刷新。
 缓存会存储列表集合或对象(无论查询方法返回什么)的1024个引用。
 缓存会被视为是read/write(可读/可写)的缓存,意味着对象检索不是共享的,而且可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。注意这里的readyonly是只只有在读的时候才不会出现线程问题。而写的时候可能会出现线程问题。

<cache
eviction="FIFO"
flushInterval="60000"
size="512"
readOnly="true"/>
创建了一个FIFO缓存,并每隔60秒刷新,存数结果对象或列表的512个引用,而且返回的对象被认为是只读的,因此在不同线程中的调用者之间修改它们会导致冲突。


可用的收回策略有:
 LRU – 最近最少使用的:移除最长时间不被使用的对象。
 FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
 SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
 WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
默认的是LRU。
flushInterval(刷新间隔)可以被设置为任意的正整数,而且它们代表一个合理的毫秒形式的时间段。默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。
size(引用数目)可以被设置为任意正整数,要记住你缓存的对象数目和你运行环境的可用内存资源数目。默认值是1024。
readOnly(只读)属性可以被设置为true或false。只读的缓存会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。可读写的缓存会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是false。
readOnly关于这个属性,不是很理解。

使用自定义缓存
<cache type=”com.domain.something.MyCustomCache”/>
type属性指定别的缓存实现。
org.mybatis.cache.Cache实现这个接口。默认的缓存时间,用的是org.apache.ibatis.cache.impl.PerpetualCache
要给缓存传递出了以上的属性之外的其他属性,通过property子元素
<cache readOnly="false">
<property name="" value=""/>
</cache>

针对语句的缓存设置
<select ... flushCache=”false” useCache=”true”/>
<insert ... flushCache=”true”/>
<update ... flushCache=”true”/>
<delete ... flushCache=”true”/>
上面都是默认值

缓存配置共享
<cache-ref namespace=”com.someone.application.data.SomeMapper”/>
比如我在Account.xml配置了缓存
<mapper namespace="com.liyixing.ibatis.dao.IAccountDao">
<cache readOnly="false" />

在Message.xml要应用这个配置
<mapper namespace="com.liyixing.ibatis.dao.IMessageDao">
<cache-ref namespace="com.liyixing.ibatis.dao.IAccountDao"/>
  • 大小: 2.4 KB
  • 大小: 6 KB
  • 大小: 2.8 KB
分享到:
评论

相关推荐

    iBATIS缓存

    **iBATIS缓存**是数据库访问框架iBATIS中的一个重要特性,用于提高数据查询的效率,减少不必要的数据库访问。iBATIS缓存分为一级缓存和二级缓存,它们在提升应用程序性能方面起着关键作用。 一级缓存是SqlSession...

    iBATIS缓存介绍

    ### iBATIS缓存介绍 #### 一、缓存介绍 **1.1 缓存对象** 理论上,Web分层设计的各个层都可以有缓存,Web中的任何对象都可以成为缓存的对象。例如: - **HTTP请求结果的缓存**:如页面数据或API响应。 - **...

    解决IBatis缓存动态字段问题

    ### 解决IBatis缓存动态字段问题 #### 背景与问题描述 在使用IBatis框架处理数据库操作时,可能会遇到动态数据表名、动态字段名的情况。这种情况下,由于IBatis的缓存机制,可能导致字段找不到的问题。具体表现为...

    iBATIS缓存的使用方法

    ### iBATIS缓存的使用方法 在数据库访问框架iBATIS中,缓存机制是一项重要的功能,它能够显著提高应用程序的性能。本文将详细介绍iBATIS中的缓存使用方法,包括缓存模型的配置、不同类型的缓存控制器以及如何在SQL...

    ibatis 缓存配置策略

    以下是对iBatis缓存配置策略的深入解析: 首先,iBatis 的 Cache 键(key)是由多个因素组成的,包括对象的hashCode、checksum、查询参数、sqlmap ID、SQL语句以及调用方法名。由于这些因素的多样性,即使是微小的...

    ibatis缓存介绍 - 勇泽 - 博客园.mht

    ibatis缓存介绍 - 勇泽 - 博客园ibatis缓存介绍 - 勇泽 - 博客园ibatis缓存介绍 - 勇泽 - 博客园ibatis缓存介绍 - 勇泽 - 博客园

    Java ibatis缓存技术

    ### Java ibatis缓存技术详解 #### 一、ibatis缓存概述 ibatis是一款流行的持久层框架,它简化了Java应用程序与数据库之间的交互过程。ibatis提供了多种特性,其中包括缓存机制,这对于提高应用程序的性能至关重要...

    Java_ibatis缓存技术

    本文将深入探讨Java_iBatis缓存技术,包括它的概念、类型、配置以及在实际应用中的注意事项。 首先,缓存是一种存储机制,用于临时存放频繁访问的数据,减少数据库的读取次数,从而提高系统响应速度。在iBatis中,...

    iBATIS缓存介绍[借鉴].pdf

    本文将详细介绍iBATIS缓存的概念、类型以及配置方法。 一.缓存介绍 缓存,简单来说,是为了减少对数据库的频繁访问,将常用数据存储在快速访问的介质中。这有助于降低延迟,提高应用的响应速度。 1.1 缓存对象:...

    ibatis 缓存 - 24小时学习网.mht

    ibatis 缓存 - 24小时学习网ibatis 缓存 - 24小时学习网ibatis 缓存 - 24小时学习网ibatis 缓存 - 24小时学习网ibatis 缓存 - 24小时学习网

    ibatis-缓存使用示例

    总之,iBATIS缓存是提升系统效率的关键技术之一,理解其工作机制并恰当运用,对于构建高效、稳定的应用至关重要。通过"ibatis-缓存使用示例"的学习,开发者能更好地掌握这一技巧,从而在实际项目中发挥出更大的价值...

    Java_ibatis-cache.rar_cache

    本篇将深入探讨iBatis缓存技术,旨在帮助你理解并掌握如何在实际项目中有效应用iBatis缓存。 首先,我们要了解iBatis的缓存分为一级缓存和二级缓存。一级缓存是SqlSession级别的,也称为本地缓存,它存储在...

    ibatis_数据缓存

    iBatis 数据缓存机制是提高数据库访问性能的重要手段,它允许将查询结果存储在内存中,以便后续相同查询能够快速获取数据,而无需每次都执行SQL查询。在深入理解iBatis的Cache概念之前,首先需要知道iBatis是一个轻...

    ibatis培训教程

    - **iBATIS缓存机制**: - 一级缓存: 自动启用,存储在会话级别,用于存储SQL执行的结果。 - 二级缓存: 需要手动启用,存储在映射文件级别,可以在多个会话之间共享数据。 - **缓存配置**: - 在`SqlMapConfig.xml`...

    ibatis 数据缓存.pdf

    ibatis 数据缓存,讨论了ibatis 数据缓存方面的概念,即用法,用到ibatis 数据缓存的可以参考一下

    J2EE WEB缓存技术详解.doc

    **ibatis缓存机制** - ibatis(现MyBatis)框架也提供了缓存机制,包括一级缓存(本地缓存,类似于JCS的内存区域)和二级缓存(跨SQL会话的缓存,类似JCS的磁盘区域或远程区域)。这表明,缓存机制是提高数据访问...

    ibatis开发手册

    #### 四、ibatis缓存机制 - **MEMORY类型Cache与WeakReference**: - 内存级别的缓存,使用WeakReference可以避免内存泄漏的风险。 - **LRU型Cache**:Least Recently Used,最近最少使用的缓存策略,当缓存满时,...

Global site tag (gtag.js) - Google Analytics