首先我们来说一下定义:
一级缓存,就是在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.
四月 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.
四月 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.
四月 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.
结果是只是执行了一次查询,二级缓存已经生效,到这里一二级缓存应该就懂了;