MyBatis 內置了一個強大的事務性查詢緩存機制(目的:優化查詢效率),它可以非常方便地配置和定製。 為了使它更加強大而且易於配置, MyBatis 3 中的緩存實現進行了許多改進。默認情況下,只啟用了本地的會話緩存,它僅僅對一個會話中的數據進行緩存。 要啟用全局的二級緩存,只需要在你的 SQL 映射文件中進行配置。
基於SqlSession級別的,簡單來說就是SqlSession未關閉的時候,對於同一條SQL語句的話,二次執行的時候,同個SqlSession只會執行一條SQL語句到資料庫當中進行查詢;
1、EmpMapper.java
public interface EmpMapper { /** * 根據僱員編號查詢僱員信息 * @param empno * @return */ Emp queryEmpByEmpno(Integer empno);}
2、EmpMapper.xml
<mapper namespace="com.cnlm.mapper.EmpMapper"> <select id="queryEmpByEmpno" resultType="com.cnlm.pojo.Emp"> select * from emp where empno = #{empno} </select></mapper>
3、SqlSessionCacheTest.java
測試代碼:SqlSession未關閉
public class SqlSessionCacheTest { SqlSessionFactory sqlSessionFactory; SqlSession sqlSession; @Before public void before() throws IOException { //當執行Test測試前都會首先執行此方法 String resource = "mybatis.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //獲取SqlSession對象 sqlSession = sqlSessionFactory.openSession(true); } @Test public void queryEmpListTest(){ EmpMapper empMapper1 = sqlSession.getMapper(EmpMapper.class); Emp empList1 = empMapper1.queryEmpByEmpno(7844); System.out.println(empList1); /** * SqlSession未關閉的時候,對於同一條SQL語句的話,二次執行的時候, * 同個SqlSession只會執行一條SQL語句到資料庫當中進行查詢。 */ EmpMapper empMapper2 = sqlSession.getMapper(EmpMapper.class); Emp empList2 = empMapper2.queryEmpByEmpno(7844); System.out.println(empList2); }}
SqlSession未關閉測試結果:
測試代碼:SqlSession關閉
public class SqlSessionCacheTest { SqlSessionFactory sqlSessionFactory; SqlSession sqlSession; @Before public void before() throws IOException { //當執行Test測試前都會首先執行此方法 String resource = "mybatis.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //獲取SqlSession對象 sqlSession = sqlSessionFactory.openSession(true); } @Test public void queryEmpListTest(){ EmpMapper empMapper1 = sqlSession.getMapper(EmpMapper.class); Emp empList1 = empMapper1.queryEmpByEmpno(7844); System.out.println(empList1); sqlSession.close(); //關閉sqlSession sqlSession = sqlSessionFactory.openSession(); EmpMapper empMapper2 = sqlSession.getMapper(EmpMapper.class); Emp empList2 = empMapper2.queryEmpByEmpno(7844); System.out.println(empList2); }}
SqlSession關閉測試結果:
測試結論:基於SqlSession級別的,簡單來說就是SqlSession未關閉的時候,對於同一條SQL語句的話,二次執行的時候,同個SqlSession只會執行一條SQL語句到資料庫當中進行查詢。如果SqlSession關閉,二次執行的時候,不同的SqlSession也會執行2條SQL語句到資料庫當中進行查詢,當然如果還想從二級緩存sqlSessionFactory中獲取數據,可以配置開啟二級緩存。
二級緩存:這個是基於sqlSessionFactory或NameSpace級別的,也就是一個Dao或者是一個Mapper級別的。根據如上一級緩存測試,當SqlSession關閉,二次執行的時候,不同的SqlSession也會執行2條SQL語句到資料庫當中進行查詢,當然如果還想從二級緩存sqlSessionFactory中獲取數據,可以配置開啟二級緩存。
1、EmpMapper.java
public interface EmpMapper { /** * 根據僱員編號查詢僱員信息 * @param empno * @return */ Emp queryEmpByEmpno(Integer empno);}
2、EmpMapper.xml
<mapper namespace="com.cnlm.mapper.EmpMapper">
<!--啟用全局的二級緩存-->
<cache readOnly="true" />
<select id="queryEmpByEmpno" resultType="com.cnlm.pojo.Emp">
select * from emp where empno = #{empno}
</select>
</mapper>
3、SqlSessionFactoryCacheTest.java
public class SqlSessionFactoryCacheTest { SqlSessionFactory sqlSessionFactory; SqlSession sqlSession; @Before public void before() throws IOException { //當執行Test測試前都會首先執行此方法 String resource = "mybatis.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //獲取SqlSession對象 sqlSession = sqlSessionFactory.openSession(true); } @Test public void queryEmpListTest(){ EmpMapper empMapper1 = sqlSession.getMapper(EmpMapper.class); Emp empList1 = empMapper1.queryEmpByEmpno(7844); System.out.println(empList1); sqlSession.close(); //關閉sqlSession sqlSession = sqlSessionFactory.openSession(); EmpMapper empMapper2 = sqlSession.getMapper(EmpMapper.class); Emp empList2 = empMapper2.queryEmpByEmpno(7844); System.out.println(empList2); }}
測試結果:
注意:二級緩存是事務性的。這意味著,當 SqlSession 完成並提交時,或是完成並回滾,但沒有執行 flushCache=true 的 insert/delete/update 語句時,緩存會獲得更新。
演示代碼結構圖
誰在最需要的時候輕輕拍著我肩膀,誰在最快樂的時候願意和我分享。我是一個包夜敲代碼,想靠技術苟且的程式設計師。如果覺得有點用的話,請毫不留情地關注、點讚、轉發。這將是我寫出更多優質文章的最強動力!