MyBatis学习笔记(9)------一级缓存

一般提到 MyBatis 缓存都是指二级缓存,一级缓存(本地缓存)默认会启用,并且不能控制,因此很少会提到。

新建测试类:

	@Test
	public void testL1Cache() {
		SqlSession sqlSession = getSqlSession();
		SysUser user1 = null;
		
		try {
			UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
			//查询id=1的用户
			user1 = userMapper.selectById(1L);
			//对当前获取的对象重新赋值
			user1.setUserName("new name");
			//再次查询id相同的用户
			SysUser user2 = userMapper.selectById(1L);
			//虽然没有更新数据库,但是这个用户名和user1重新赋值的名字相同
			Assert.assertEquals("new name", user2.getUserName());
			//user2和user1完全就是同一个实例
			Assert.assertEquals(user1, user2);
		} finally {
			//关闭当前的sqlSession
			sqlSession.close();
		}
		
		System.out.println("开启新的SqlSession");
		//开始另外一个新的session
		sqlSession = getSqlSession();
		try {
			UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
			//查询id=1的用户
			SysUser user2 = userMapper.selectById(1L);
			//第二个session获取的用户名仍然是admin
			Assert.assertNotEquals("new name", user2.getUserName());
			//这里的user2和前一个session查询的结果是两个不同的实例
			Assert.assertNotEquals(user1, user2);
			//执行删除操作
			userMapper.deleteUserById(1002L);
			//获取user3
			SysUser user3 = userMapper.selectById(1L);
			//这里的user2和user3是两个不同的实例
			Assert.assertNotEquals(user2, user3);
		} finally {
			//关闭sqlSession
			sqlSession.close();
		}
	}

输出日志:

DEBUG [main] - ==>  Preparing: select * from sys_user where id = ? 
DEBUG [main] - ==> Parameters: 1(Long)
TRACE [main] - <==    Columns: id, user_name, user_password, user_info, create_time
TRACE [main] - <==        Row: 1, admin, 12345, <<BLOB>>, 2019-01-06 10:35:24.0
DEBUG [main] - <==      Total: 1
开启新的SqlSession
DEBUG [main] - ==>  Preparing: select * from sys_user where id = ? 
DEBUG [main] - ==> Parameters: 1(Long)
TRACE [main] - <==    Columns: id, user_name, user_password, user_info, create_time
TRACE [main] - <==        Row: 1, admin, 12345, <<BLOB>>, 2019-01-06 10:35:24.0
DEBUG [main] - <==      Total: 1
DEBUG [main] - ==>  Preparing: {call delete_user_by_id(?)} 
DEBUG [main] - ==> Parameters: 1002(Long)
DEBUG [main] - <==    Updates: 1
DEBUG [main] - ==>  Preparing: select * from sys_user where id = ? 
DEBUG [main] - ==> Parameters: 1(Long)
TRACE [main] - <==    Columns: id, user_name, user_password, user_info, create_time
TRACE [main] - <==        Row: 1, admin, 12345, <<BLOB>>, 2019-01-06 10:35:24.0
DEBUG [main] - <==      Total: 1

在第一次执行 selectById 方法获取 SysUser 数据时,真正执行了数据库查询,得到了user1。第二次执行获取 user2 的时候,从日志可以看出,在”开启新的sqlSession“ 这行日志的上面,只有一次查询,也就是说第二次查询并没有执行数据库操作。从测试代码看,user1 重新设置了 userName 的值,之后没有进行数据库操作,后来获取的 user2 对象的 userName 值和重新设置后的值一样,user1 和 user2 是同一个对象。

MyBatis 的一级缓存存在于 SqlSession 的生命周期中,在同一个 sqlsession 中查询时,MyBtis 会把执行的方法和参数通过算法生成缓存的键值,将键值和查询结果存入一个 Map 中。如果同一个 SqlSession 中执行的方法和参数完全一致,那么会生成相同的键值,当 Map 缓存对象中已经存在该键值时,则返回缓存中的对象。

在第二个 SqlSession 中,又重新查询了 user2,user2 是一个新的实例,和user1没有关系,因为一级缓存是和 SqlSession 绑定的,只存在于 SqlSession 的生命周期中。

接下来执行了一个 deleteById 操作,然后使用相同的方法和参数获取了 user3 实例,从日志和结果上看,user3 和 user2 也是完全不同的两个对象。这是因为任何的 INSERT、UPDATE、DELETE 操作都会清空一级缓存。

猜你喜欢

转载自blog.csdn.net/BZeHong/article/details/87074603