(九)mybatis学习之缓存

一级缓存(sqlsession缓存)

mybatis默认支持一级缓存。

在操作数据库时需要构造sqlSession对象,在sqlSession对象中有一个数据结构(hashMap)用于存储缓存数据。

不同的sqlSession之间的缓存数据区域(hashMap)是互相不影响的

示例1:

@Test
	public void findUserByIdTest() throws IOException{
		String resource = "sqlMapConfig.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		//创建会话工厂
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		//根据会话工厂创建会话
		SqlSession sqlSession= sqlSessionFactory.openSession();
		//通过sqlSession操作数据库
		//第一个参数:映射文件中的配置的id值,等于=namespace.id
		//第二个参数:指定映射文件中所匹配的parameterType类型参数
		User user = sqlSession.selectOne("xxxx.findUserById", "40287d8147b119bb0147b11c1e710000");
		
		System.out.println(user);
		
		user = sqlSession.selectOne("xxxx.findUserById", "40287d8147b119bb0147b11c1e710000");
		
		System.out.println(user);
		
		//释放资源
		sqlSession.close();
	
	}
控制台日志:

2016-04-04 16:38:29,714 [main] DEBUG [xxxx.findUserById] - ==>  Preparing: select * from tab_user where id=? 
  2016-04-04 16:38:29,763 [main] DEBUG [xxxx.findUserById] - ==> Parameters: 40287d8147b119bb0147b11c1e710000(String)
  2016-04-04 16:38:29,830 [main] DEBUG [xxxx.findUserById] - <==      Total: 1
  User [id=40287d8147b119bb0147b11c1e710000, userName=zero, nickName=卡洛, password=e10adc3949ba59abbe56e057f20f883e, sex=1, birthday=Sat Aug 02 00:00:00 GMT+08:00 2014, province=日本, city=大阪府, county=大阪市, createTime=Thu Aug 07 23:35:15 GMT+08:00 2014]
User [id=40287d8147b119bb0147b11c1e710000, userName=zero, nickName=卡洛, password=e10adc3949ba59abbe56e057f20f883e, sex=1, birthday=Sat Aug 02 00:00:00 GMT+08:00 2014, province=日本, city=大阪府, county=大阪市, createTime=Thu Aug 07 23:35:15 GMT+08:00 2014]


由日志信息中可以看出,第二次查询结果从缓存中获取的。


同一个sqlSession里就会使用到一级缓存。

二级缓存(mapper缓存)

备注:使用缓存的pojo类需要实现序列化
二级缓存是mapper级别的缓存,多个sqlSsession去操作同一个mapper的sql语句,多个sqlSession可以共用二级缓存;
二级缓存区域是按namespace划分的,即每一个namespace的mapper都有一个二级缓存区域。
如果sqlsession去执行了commit操作,那么会清空一、二缓存中的数据。
二级缓存是跨sqlSession的。
如:
sqlsession1查询用户id为1的用户信息,查询到用户信息会将数据存储到二级缓存中。
sqlsession2查询用户id为1的用户信息,会先去缓存中查找是否存在数据。


二级缓存是需要配置开启。
(1)需要在settings里开启二级缓存总开关
<!-- 开启二级缓存总开关,默认是true -->
		<setting name="cacheEnabled" value="true"/>


(2)需要在mapper.xml里开启二级缓存(开启某个mapper的二级缓存)
在userMapper.xml里开启二级缓存
<!-- 开启本mapper的namespace下的二级缓存 -->
	<cache/>

用户信息pojo类(实现序列化):
public class User implements Serializable{
	
	private List<String> idsList;

	private String id;
	private String userName;				//用户名
	private String nickName;				//昵称
	private String password;				//登录密码
	private Integer sex;					//性别
	private Date birthday;					//出生日期
	private String province;				//省
	private String city;					//市
	private String county;					//县
	private Date createTime;				//创建时间
	//...get  set

测试类:
@Test
	public void testFindUserById() throws Exception {
		
		//获取代理对象
		UserMapper userMapper = (UserMapper) context.getBean("userMapper");
		
		User user1 = userMapper.findUserById("1");
		System.out.println(user1);
		
//		User user = new User();
//		user.setId("1");
//		user.setUserName("222xxxxxx");
//		userMapper.updateUserByTrim(user);
		
		User user2 = userMapper.findUserById("1");
		System.out.println(user2);
	}

控制台日志:
  2016-04-04 17:02:05,971 [main] DEBUG [mapper.UserMapper.findUserById] - ==>  Preparing: select * from tab_user where id=? 
  2016-04-04 17:02:06,017 [main] DEBUG [mapper.UserMapper.findUserById] - ==> Parameters: 1(String)
  2016-04-04 17:02:06,046 [main] DEBUG [mapper.UserMapper.findUserById] - <==      Total: 1
  2016-04-04 17:02:06,057 [main] DEBUG [org.mybatis.spring.SqlSessionUtils] - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1860b23]
  2016-04-04 17:02:06,058 [main] DEBUG [org.springframework.jdbc.datasource.DataSourceUtils] - Returning JDBC Connection to DataSource
  User [id=1, userName=222xxxxxx, nickName=1, password=1, sex=1, birthday=null, province=null, city=null, county=null, createTime=null]
2016-04-04 17:02:06,064 [main] DEBUG [org.mybatis.spring.SqlSessionUtils] - Creating a new SqlSession
  2016-04-04 17:02:06,064 [main] DEBUG [org.mybatis.spring.SqlSessionUtils] - SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1a338a0] was not registered for synchronization because synchronization is not active
  2016-04-04 17:02:06,065 [main] DEBUG [mapper.UserMapper] - Cache Hit Ratio [mapper.UserMapper]: 0.5
  2016-04-04 17:02:06,065 [main] DEBUG [org.mybatis.spring.SqlSessionUtils] - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1a338a0]
  User [id=1, userName=222xxxxxx, nickName=1, password=1, sex=1, birthday=null, province=null, city=null, county=null, createTime=null]
由日志我们看到,第二次查询的时候是没有执行sql语句的。其中日志里有个Cache Hit Ratio [mapper.UserMapper]: 0.5,这是表示命中率。0.5的意思是,一共查询了两次(调用了两次findUserById),有一次命中(第二次从缓存中找到了)。


当在测试类里加入一个更新操作时,此时会清空缓存。
测试代码:
@Test
	public void testFindUserById() throws Exception {
		
		//获取代理对象
		UserMapper userMapper = (UserMapper) context.getBean("userMapper");
		
		User user1 = userMapper.findUserById("1");
		System.out.println(user1);
		
		User user = new User();
		user.setId("1");
		user.setUserName("222xxxxxx");
		userMapper.updateUserByTrim(user);
		
		User user2 = userMapper.findUserById("1");
		System.out.println(user2);
	}
控制台日志:
  2016-04-04 17:04:48,229 [main] DEBUG [com.mchange.v2.resourcepool.BasicResourcePool] - awaitAvailable(): [unknown]
  2016-04-04 17:04:48,570 [main] DEBUG [org.mybatis.spring.transaction.SpringManagedTransaction] - JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@f6b73d [wrapping: com.mysql.jdbc.JDBC4Connection@17845e3]] will not be managed by Spring
  2016-04-04 17:04:48,579 [main] DEBUG [mapper.UserMapper.findUserById] - ==>  Preparing: select * from tab_user where id=? 
  2016-04-04 17:04:48,627 [main] DEBUG [mapper.UserMapper.findUserById] - ==> Parameters: 1(String)
  2016-04-04 17:04:48,661 [main] DEBUG [mapper.UserMapper.findUserById] - <==      Total: 1
  2016-04-04 17:04:48,673 [main] DEBUG [org.mybatis.spring.SqlSessionUtils] - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1456008]
  2016-04-04 17:04:48,673 [main] DEBUG [org.springframework.jdbc.datasource.DataSourceUtils] - Returning JDBC Connection to DataSource
  User [id=1, userName=222xxxxxx, nickName=1, password=1, sex=1, birthday=null, province=null, city=null, county=null, createTime=null]
2016-04-04 17:04:48,675 [main] DEBUG [org.mybatis.spring.SqlSessionUtils] - Creating a new SqlSession
  2016-04-04 17:04:48,675 [main] DEBUG [org.mybatis.spring.SqlSessionUtils] - SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1e19787] was not registered for synchronization because synchronization is not active
  2016-04-04 17:04:48,720 [main] DEBUG [org.springframework.jdbc.datasource.DataSourceUtils] - Fetching JDBC Connection from DataSource
  2016-04-04 17:04:48,720 [main] DEBUG [org.mybatis.spring.transaction.SpringManagedTransaction] - JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@1952a24 [wrapping: com.mysql.jdbc.JDBC4Connection@17845e3]] will not be managed by Spring
  2016-04-04 17:04:48,720 [main] DEBUG [mapper.UserMapper.updateUserByTrim] - ==>  Preparing: update tab_user set userName=? where id=? 
  2016-04-04 17:04:48,721 [main] DEBUG [mapper.UserMapper.updateUserByTrim] - ==> Parameters: 222xxxxxx(String), 1(String)
  2016-04-04 17:04:48,722 [main] DEBUG [mapper.UserMapper.updateUserByTrim] - <==    Updates: 1
  2016-04-04 17:04:48,723 [main] DEBUG [org.mybatis.spring.SqlSessionUtils] - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1e19787]
  2016-04-04 17:04:48,723 [main] DEBUG [org.springframework.jdbc.datasource.DataSourceUtils] - Returning JDBC Connection to DataSource
  2016-04-04 17:04:48,723 [main] DEBUG [org.mybatis.spring.SqlSessionUtils] - Creating a new SqlSession
  2016-04-04 17:04:48,723 [main] DEBUG [org.mybatis.spring.SqlSessionUtils] - SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@160eaa6] was not registered for synchronization because synchronization is not active
  2016-04-04 17:04:48,723 [main] DEBUG [mapper.UserMapper] - Cache Hit Ratio [mapper.UserMapper]: 0.0
  2016-04-04 17:04:48,723 [main] DEBUG [org.springframework.jdbc.datasource.DataSourceUtils] - Fetching JDBC Connection from DataSource
  2016-04-04 17:04:48,723 [main] DEBUG [org.mybatis.spring.transaction.SpringManagedTransaction] - JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@ec9d4b [wrapping: com.mysql.jdbc.JDBC4Connection@17845e3]] will not be managed by Spring
  2016-04-04 17:04:48,723 [main] DEBUG [mapper.UserMapper.findUserById] - ==>  Preparing: select * from tab_user where id=? 
  2016-04-04 17:04:48,723 [main] DEBUG [mapper.UserMapper.findUserById] - ==> Parameters: 1(String)
  2016-04-04 17:04:48,726 [main] DEBUG [mapper.UserMapper.findUserById] - <==      Total: 1
  2016-04-04 17:04:48,726 [main] DEBUG [org.mybatis.spring.SqlSessionUtils] - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@160eaa6]
  2016-04-04 17:04:48,727 [main] DEBUG [org.springframework.jdbc.datasource.DataSourceUtils] - Returning JDBC Connection to DataSource
  User [id=1, userName=222xxxxxx, nickName=1, password=1, sex=1, birthday=null, province=null, city=null, county=null, createTime=null]

禁用二级缓存

设置useCache=false来禁用二级缓存。useCache默认值是true,即默认是先从缓存查询
<!-- 使用useCache="false"禁用缓存,默认值是true -->
	<select id="findUserById" parameterType="java.lang.String" resultType="User" useCache="false">
		select * from tab_user where id=#{id}
	</select>
此时使用该查询时,每次都会从数据库中查询获取数据了。

刷新缓存

刷新缓存就是清空缓存
使用flushCache="true"来配置刷新缓存(清空缓存),默认值就是true
一般执行完commit操作完都需要刷新缓存,是因为<insert>、<update>、<delete>标签中有个flushCache的属性,该属性值默认是true。表示执行完刷新缓存。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值