1. 一级缓存默认是开启的,
MyBatis 默认开启了一级缓存,一级缓存是在SqlSession 层面进行缓存的。即,同一个SqlSession ,多次调用同一个Mapper和同一个方法的同一个参数,只会进行一次数据库查询,然后把数据缓存到缓冲中,以后直接先从缓存中取出数据,不会直接去查数据库。
但是不同的SqlSession对象,因为不用的SqlSession都是相互隔离的,所以相同的Mapper、参数和方法,他还是会再次发送到SQL到数据库去执行,返回结果。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"classpath*:/spring.xml", "classpath*:/spring-servlet_.xml"})
public class test {
@Resource
SqlSessionTemplate sqlSession;
@Resource
SqlSessionFactoryBean factoryBean;
@Test
public void testWithManeulSession() throws Exception {
//同一个ManulSession下, 会开启一级缓存,
//此处直接使用注入的factoryBean 获取sqlsession(DefaultSqlSession) ,
//请于SqlSessionTemplate类区分开
SqlSessionFactory factory = factoryBean.getObject();
SqlSession manulSqlSession = factory.openSession(true);
UserMapper mapper = manulSqlSession.getMapper(UserMapper.class);
User u = mapper.selectByPrimaryKey(1);
User u_ = mapper.selectByPrimaryKey(1);
UserMapper mapper2 = manulSqlSession.getMapper(UserMapper.class);
User u2 = mapper2.selectByPrimaryKey(1);
System.out.println("同一个ManulSession下, 会开启一级缓存");
/*
运行结果
JDBC Connection [com.mysql.jdbc.JDBC4Connection@68577ba8] will not be managed by Spring
==> Preparing: select id, name, age, sex from User where id = ?
==> Parameters: 1(Integer)
<== Columns: id, name, age, sex
<== Row: 1, name1, 20, 0
<== Total: 1
同一个ManulSession下, 会开启一级缓存
* */
}
}
SqlSessionTemplate 特例
注入的单例 SqlSessionTemplate 内部包含SqlSessionProxy对象, 其是对SqlSession的代理. 构造函数如下:
public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType, PersistenceExceptionTranslator exceptionTranslator) {
Assert.notNull(sqlSessionFactory, "Property \'sqlSessionFactory\' is required");
Assert.notNull(executorType, "Property \'executorType\' is required");
this.sqlSessionFactory = sqlSessionFactory;
this.executorType = executorType;
//此处为对sqlsession的一次代理, 代码运行中,由内部类SqlSessionInterceptor 进行拦截
this.sqlSessionProxy =
new Class[]{SqlSession.class},
new SqlSessionTemplate.SqlSessionInterceptor()
);
}
private class SqlSessionInterceptor