MyBatis学习笔记(三)缓存

缓存概述

缓存主要用来提高查询的性能,减少跟数据库交互的次数,减轻数据库承受的压力。适用于读多写少的场景,如果数据变化频率非常高,则不适用。
MyBatis的缓存分为一级缓存和二级缓存

一级缓存特点

一级缓存默认级别是SqlSession级别的缓存,每个SqlSession缓存的数据不能共存,两次查询之间的更新操作(增删改)会刷新一级缓存。或者调用SqlSession的close方法时,此时一级缓存不存在。
具体测试:

  1. 两次查询数据库中的数据,存入user对象中,第二次查询将会从一级缓存中取出该对象。对比查询出来的对象的内存地址,输出结果为true,表示两次得到的对象是相同的,控制台输出也可以看出可以看出,第二次并未从数据库进行查询
//两次直接查询,第二次未进行数据库的查询
	@Test
	public void getUserByIdTest1() {
		SqlSession sqlSession =null;
		try {
			sqlSession=SqlSessionFactoryUtils.openSqlSession();
			// 获得mapper对象,用工具类直接调用静态方法获得SqlSession对象
			IUserMapping userMapper = sqlSession.getMapper(IUserMapping.class);
			System.out.println("第一次查询--------------------------------------------");
			User user1 = userMapper.getUserById(3);
			//以下的测试在此处增改
			System.out.println("第二次查询--------------------------------------------");
			User user2=userMapper.getUserById(3);
			//两次输出结果
			System.out.println(user1==user2);
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			//用完关闭
			if(sqlSession!=null) {
				sqlSession.close();
			}
		}
	}

测试结果:
在这里插入图片描述

  1. 在两次查询过程中间修改user对象的username属性。对象中的username属性在缓存中被修改,所以第二次输出的是修改后的值,即是从一级缓存中获取的对象
				System.out.println("第一次查询--------------------------------------------");
				User user1 = userMapper.getUserById(3);
				System.out.println("第一次查询:"+user1.getUsername());
				
				//创建一个User对象,对User的属性进行修改
				user1.setUsername("李四");
				
				System.out.println("第二次查询------------------------------------------");
				User user2=userMapper.getUserById(3);
				System.out.println("第二次查询:"+user2.getUsername());
				//两次输出结果
				System.out.print("内存地址对比:");
				System.out.println(user1==user2);

输出结果如下:
在这里插入图片描述

  1. 在两次查询的之间进行修改数据库信息的操作,可以从控制台输出看出,两次查询的结果是不一致的,第二次查询的结果不再是从缓存中获取,而是从数据库中再次进行查询,返回一个新的user对象
				IUserMapping userMapper = sqlSession.getMapper(IUserMapping.class);
				System.out.println("第一次查询--------------------------------------------");
				User user1 = userMapper.getUserById(3);
				System.out.println(user1.getUsername());
				 
				//修改用户名
				User user = new User();
				user.setId(3);
				user.setUsername("小小鸟");
				userMapper.update(user);
				
				System.out.println("第二次查询--------------------------------------------");
				User user2=userMapper.getUserById(3);
				System.out.println(user2.getUsername());
				//两次输出结果
				System.out.print("内存地址对比:");
				System.out.println(user1==user2);
				sqlSession.commit();

在这里插入图片描述

  1. 增加第三次查询,在查询前关闭SqlSession,在第三次查询时是从数据库中查询。
				System.out.println("第三次查询--------------------------------------------");
				sqlSession.close();
				sqlSession=SqlSessionFactoryUtils.openSqlSession();
				// 获得mapper对象,用工具类直接调用静态方法获得SqlSession对象
				userMapper = sqlSession.getMapper(IUserMapping.class);
				User user3 = userMapper.getUserById(3);
				System.out.print("第一次和第三次内存地址对比:");
				System.out.println(user3==user1);

在这里插入图片描述

二级缓存

二级缓存是SqlSessionFactory级别的缓存:SqlSessionFactory工厂对象只有一个,所有的SqlSession对象共享同行一个SqlSessionFactory

  1. 开启起二级缓存(默认处于开始状态),在我们的mybatis-config.xml主配置文件中进行配置
<!-- 开启二级缓存 -->
	<settings>
		<setting name="cacheEnbaled" value="true"/>
	</settings>
  1. 在映射器的xml文件中开启二级缓存
<!-- 开启二级缓存 -->
	<cache></cache>
  1. 默认的二级缓存配置会有如下的特点:
  • 所有的Select语句将会被缓存
  • 所有的更新语句(insert、update、delete)将会刷新缓存
  • 缓存将会采用LRU(LeastRecently Used 最近最少使用)
  • 算法来回收,还有FIFO(先进先出)等其他算法,建议采用LRU
  • 缓存会存储1024个对象的引用
    代码验证:
@Test
		public void getUserByIdTest4() {
			SqlSession sqlSession =null;
			try {
				sqlSession=SqlSessionFactoryUtils.openSqlSession();
				// 获得mapper对象,用工具类直接调用静态方法获得SqlSession对象
				IUserMapping userMapper = sqlSession.getMapper(IUserMapping.class);
				System.out.println("第一次查询--------------------------------------------");
				User user1 = userMapper.getUserById(3);
				System.out.println(user1.getUsername());
				System.out.println("第二次查询--------------------------------------------");
				User user2=userMapper.getUserById(3);
				System.out.println(user2.getUsername());
				
				System.out.println("第三次查询--------------------------------------------");
				sqlSession.close();
				sqlSession=SqlSessionFactoryUtils.openSqlSession();
				// 获得mapper对象,用工具类直接调用静态方法获得SqlSession对象
				userMapper = sqlSession.getMapper(IUserMapping.class);
				User user3 = userMapper.getUserById(3);
				User user4=userMapper.getUserById(3);
				User user5=userMapper.getUserById(3);
				System.out.println(user3);
				System.out.println(user4);
				System.out.println(user5);
			} catch (Exception e) {
				e.printStackTrace();
			}finally {
				//用完关闭
				if(sqlSession!=null) {
					sqlSession.close();
				}
			}
		}

在这里插入图片描述
开启二级缓存,从控制台输出的结果,可以看出在关闭SqlSession后,数据仍旧是存在缓存中的(二级缓存),并没有向数据库查询数据。在关闭SqlSession后,以及缓存的数据是已经被清空,SqlSession会向上从二级缓存中查询数据,结尾处输出了user3、user4、user5三次获得的对象内存地址,可以看出,后续从缓存中取出的对象每次的内存地址都是不一样的。

Ehcahe缓存框架

EhCache是一个纯粹的Java进程内的缓存框架。

  • 添加EhCache需要的jar包
    在这里插入图片描述
  • 引入EhCache配置文件
    解压jsqlparser-0.9.5.jar可获得配置文件,配置文件和mybatis的住配置文件放一起(此处为mybatis-config.xml)
    在配置ehcache-failsafe.xml配置文件中有相应配置信息,可按需进行修改,此处暂默认
    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            maxElementsOnDisk="10000000"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU">
        <persistence strategy="localTempSwap"/>
    </defaultCache>
  • 配置MyBatis的二级缓存采用EhCache
    在我们的映射器的配置文件中开启缓存
<!-- 开启Encache二级缓存 -->
	<cache type="org.mybatis.caches.ehcache.EhcacheCache"></cache>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值