自测一下mybatis的一级缓存和二级缓存

首先我们来说一下定义:

一级缓存,就是在SqlSession上的缓存;

二级缓存,就是在SQLSessionFactory上的缓存。

在没有任何配置的情况下,mybatis默认开启一级缓存;

public static void main(String[] args) {
		Logger log = Logger.getLogger(Test.class);
		SqlSession sqlSession=null;
		try {
			sqlSession = CreatFactoryUtils.openSqlSession();
			UserDao mapper=sqlSession.getMapper(UserDao.class);
			List<User> list = mapper.findUser();
			log.info("================"+list);
			log.info("再次调用此查询,看是否还执行sql");
			List<User> listNew = mapper.findUser();
			log.info("================"+listNew);
		} catch (Exception e) {
		}finally {
			if (sqlSession!=null) {
				sqlSession.close();
			}
		}

打印结果如下:

DEBUG 2018-04-30 01:36:36,529 org.apache.ibatis.datasource.pooled.PooledDataSource:Created connection 1445157774.
DEBUG 2018-04-30 01:36:36,533 dao.UserDao.findUser:==>  Preparing: select id,username,userpwd from t_users 
DEBUG 2018-04-30 01:36:36,574 dao.UserDao.findUser:==> Parameters: 
DEBUG 2018-04-30 01:36:36,592 dao.UserDao.findUser:<==      Total: 1
四月 30, 2018 1:36:36 上午 [mybatis.Test]  UNKNOWN METHOD
信息: ================[User [id=1, username=dddd, userpwd=123]]
四月 30, 2018 1:36:36 上午 [mybatis.Test]  UNKNOWN METHOD
信息: 再次调用此查询,看是否还执行sql
四月 30, 2018 1:36:36 上午 [mybatis.Test]  UNKNOWN METHOD
信息: ================[User [id=1, username=dddd, userpwd=123]]
DEBUG 2018-04-30 01:36:36,602 org.apache.ibatis.transaction.jdbc.JdbcTransaction:Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@56235b8e]
DEBUG 2018-04-30 01:36:36,602 org.apache.ibatis.datasource.pooled.PooledDataSource:Returned connection 1445157774 to pool.

能够看到,在两次查询过程中,只执行了一次sql语句;说明mybatis已经默认开启的一级缓存,有人会说,为什么这里不是SQLSessionFactory的缓存?  那我们接下来看:

	public static void main(String[] args) {
		Logger log = Logger.getLogger(Test.class);
		SqlSession sqlSession=null;
		SqlSession sqlSessionNew=null;
		try {
			sqlSession = CreatFactoryUtils.openSqlSession();
			UserDao mapper=sqlSession.getMapper(UserDao.class);
			List<User> list = mapper.findUser();
			sqlSession.commit();
			log.info("================"+list);
			log.info("再次调用此查询,看是否还执行sql");
			List<User> listNew = mapper.findUser();
			log.info("================"+listNew);
		} catch (Exception e) {
		}finally {
			if (sqlSession!=null) {
				sqlSession.close();
			}
			if(sqlSessionNew!=null){
				sqlSessionNew.close();
			}
		}
	}

此时的打印结果:

DEBUG 2018-04-30 02:05:38,594 org.apache.ibatis.datasource.pooled.PooledDataSource:Created connection 1445157774.
DEBUG 2018-04-30 02:05:38,595 dao.UserDao.findUser:==>  Preparing: select id,username,userpwd from t_users 
DEBUG 2018-04-30 02:05:38,631 dao.UserDao.findUser:==> Parameters: 
DEBUG 2018-04-30 02:05:38,648 dao.UserDao.findUser:<==      Total: 1
四月 30, 2018 2:05:38 上午 [mybatis.Test]  UNKNOWN METHOD
信息: ================[User [id=1, username=dddd, userpwd=123]]
四月 30, 2018 2:05:38 上午 [mybatis.Test]  UNKNOWN METHOD
信息: 再次调用此查询,看是否还执行sql
DEBUG 2018-04-30 02:05:38,661 dao.UserDao.findUser:==>  Preparing: select id,username,userpwd from t_users 
DEBUG 2018-04-30 02:05:38,661 dao.UserDao.findUser:==> Parameters: 
DEBUG 2018-04-30 02:05:38,662 dao.UserDao.findUser:<==      Total: 1
四月 30, 2018 2:05:38 上午 [mybatis.Test]  UNKNOWN METHOD
信息: ================[User [id=1, username=dddd, userpwd=123]]
DEBUG 2018-04-30 02:05:38,663 org.apache.ibatis.transaction.jdbc.JdbcTransaction:Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@56235b8e]
DEBUG 2018-04-30 02:05:38,663 org.apache.ibatis.datasource.pooled.PooledDataSource:Returned connection 1445157774 to pool.

显然执行了两次sql查询;在这需要说明一下,commit提交后,一级缓存就会失效,这是为了防止脏读,这样再次查询的时候就是从数据库执行sql了。

这就说明,一级缓存是在SQLSession上的

现在来看一下二级缓存,上面的测试代码不变,不过二级缓存首先实体类要实现Serializable接口,不然会报错的;

public class User implements Serializable{

	private String id;
	private String username;
	private String userpwd;

然后再映射文件中加入<cache></cache>

 <resultMap id="user" type="pojo.User" >  
    <id column="id" property="id"  />  
    <result column="username" property="username" />  
    <result column="userpwd" property="userpwd"  /> 
  </resultMap> 
  <cache></cache>

现在准备工作都完成了,还用刚才两次查询commit提交的的测试文件,不需要任何变化,现在一级缓存失效,那么我们开启了二级缓存,看看是否还要执行两次查询:

DEBUG 2018-04-30 02:07:27,603 org.apache.ibatis.datasource.pooled.PooledDataSource:Created connection 1864350231.
DEBUG 2018-04-30 02:07:27,606 dao.UserDao.findUser:==>  Preparing: select id,username,userpwd from t_users 
DEBUG 2018-04-30 02:07:27,643 dao.UserDao.findUser:==> Parameters: 
DEBUG 2018-04-30 02:07:27,662 dao.UserDao.findUser:<==      Total: 1
四月 30, 2018 2:07:27 上午 [mybatis.Test]  UNKNOWN METHOD
信息: ================[User [id=1, username=dddd, userpwd=123]]
四月 30, 2018 2:07:27 上午 [mybatis.Test]  UNKNOWN METHOD
信息: 再次调用此查询,看是否还执行sql
DEBUG 2018-04-30 02:07:27,742 dao.UserDao:Cache Hit Ratio [dao.UserDao]: 0.5
四月 30, 2018 2:07:27 上午 [mybatis.Test]  UNKNOWN METHOD
信息: ================[User [id=1, username=dddd, userpwd=123]]
DEBUG 2018-04-30 02:07:27,742 org.apache.ibatis.transaction.jdbc.JdbcTransaction:Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@6f1fba17]
DEBUG 2018-04-30 02:07:27,743 org.apache.ibatis.datasource.pooled.PooledDataSource:Returned connection 1864350231 to pool.

结果是只是执行了一次查询,二级缓存已经生效,到这里一二级缓存应该就懂了;



猜你喜欢

转载自blog.csdn.net/hbl6016/article/details/80146920