一,MyBatis一級緩存(本地緩存)java
<select id="selectStudentByIdAndName" flushCache=」true」 resultType="student"> select * from student where sid=#{Sid} and s_name=#{Sname} </select>
public class MyBatisTest { public static void main( String[] args ) { SqlSession openSession = null; try { //mybatis配置文件 String resourse="mybatis-cfg.xml"; //經過 Resources 工具類將 ti -config.xm 配置文件讀入 Reader InputStream inputStream=Resources.getResourceAsStream(resourse); //經過 SqlSessionFactoryBuilder 建造類使用 Reader 建立 SqlSessionFactory工廠對象 SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream); //經過SqlSessionFactory工廠獲得SqlSession openSession = sqlSessionFactory.openSession(); //經過反射機制來獲取對應的Mapper實例 StudentMapper mapper=openSession.getMapper(StudentMapper.class); Student student1=mapper.selectStudentByIdAndName(2,"danghh"); Student student2=mapper.selectStudentByIdAndName(2,"danghh"); System.out.println(student1); openSession.commit(); } catch (IOException e) { e.printStackTrace(); }finally { //最後必定不要忘記關閉 SqlSession ,不然會由於鏈接沒有關閉致使數據庫鏈接數過多,形成系統崩旗 openSession.close(); } } }
[DEBUG] - Setting autocommit to false on JDBC Connection[com.mysql.jdbc.JDBC4Connection@dfd3711] [DEBUG] - ==> Preparing: select * from student where sid=? and s_name=? [DEBUG] - ==> Parameters: 2(Integer), danghh(String) [DEBUG] - <== Total: 1 Student{SID=2, Sname='danghh', Sage=22, Ssex='nv', course=null}
Student{SID=2, Sname='danghh', Sage=22, Ssex='nv', course=null}
經過結果能夠看出,因爲代碼中查詢是在一個SqlSession,且兩次查詢過程當中沒有更新信息,不會致使一級緩存失效,因此結果只進行了一次數據庫查詢。mysql
那若是是在兩個SqlSession中分別進行查詢呢?算法
結果:sql
[DEBUG] - Opening JDBC Connection [DEBUG] - Checked out connection 234698513 from pool. [DEBUG] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@dfd3711] [DEBUG] - ==> Preparing: select * from student where sid=? and s_name=? [DEBUG] - ==> Parameters: 2(Integer), danghh(String) [DEBUG] - <== Total: 1 [DEBUG] - Opening JDBC Connection [DEBUG] - Created connection 1836797772. [DEBUG] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@6d7b4f4c] [DEBUG] - ==> Preparing: select * from student where sid=? and s_name=? [DEBUG] - ==> Parameters: 2(Integer), danghh(String) [DEBUG] - <== Total: 1 Student{SID=2, Sname='danghh', Sage=22, Ssex='nv', course=null} Student{SID=2, Sname='danghh', Sage=22, Ssex='nv', course=null}
[DEBUG] - ==> Preparing: select * from student where sid=? and s_name=? [DEBUG] - ==> Parameters: 2(Integer), hjj(String) [DEBUG] - <== Total: 1 [DEBUG] - ==> Preparing: update student set S_name=?,Sage=?,Ssex=? where Sid=? [DEBUG] - ==> Parameters: hjj(String), 23(Integer), null, 2(Integer) [DEBUG] - <== Updates: 1 [DEBUG] - ==> Preparing: select * from student where sid=? and s_name=? [DEBUG] - ==> Parameters: 2(Integer), hjj(String) [DEBUG] - <== Total: 1 Student{SID=2, Sname='hjj', Sage=23, Ssex='null', course=null} Student{SID=2, Sname='hjj', Sage=23, Ssex='null', course=null}
(這個參數是二級緩存的全局開關,默認值是 true ,初始狀態爲啓用狀態,因此也可忽略此步的配置)數據庫
(因爲MyBatis二級緩存和命名空間namespace是綁定的 ,即二級緩存還須要在 Mapper.xml 映射文件中配置或者在 Mapper.java 接口中配置。)緩存
代碼:安全
public class MyBatisTest { public static void main( String[] args ) { SqlSession openSession1 = null; SqlSession openSession2 = null; try { //mybatis配置文件 String resourse="mybatis-cfg.xml"; //經過 Resources 工具類將 ti -config.xm 配置文件讀入 Reader InputStream inputStream=Resources.getResourceAsStream(resourse); //經過 SqlSessionFactoryBuilder 建造類使用 Reader 建立 SqlSessionFactory工廠對象 SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream); //經過SqlSessionFactory工廠獲得SqlSession1 openSession1 = sqlSessionFactory.openSession(); StudentMapper mapper1=openSession1.getMapper(StudentMapper.class); //經過SqlSessionFactory工廠獲得SqlSession2 openSession2 = sqlSessionFactory.openSession(); StudentMapper mapper2=openSession2.getMapper(StudentMapper.class); //使用會話1進行查詢,這次查詢結果只會存儲在一級緩存中 Student student1=mapper1.selectStudentByIdAndName(2,"hjj"); System.out.println(student1); //使用會話2進行查詢,前面會話未關閉,數據不會被刷到二級緩存中,因此本次仍會執行sql Student student2=mapper2.selectStudentByIdAndName(2,"hjj"); System.out.println(student2); //使用會話2進行查詢,因爲前面已執行過該方法,因此可在一級緩存中查到 Student student3=mapper2.selectStudentByIdAndName(2,"hjj"); System.out.println(student3); openSession1.commit(); } catch (IOException e) { e.printStackTrace(); }finally { //最後必定不要忘記關閉 SqlSession ,不然會由於鏈接沒有關閉致使數據庫鏈接數過多,形成系統崩旗 openSession1.close(); } } }
[DEBUG] - Cache Hit Ratio [MyBatisDemo.StudentMapper]: 0.0 [DEBUG] - Opening JDBC Connection [DEBUG] - Checked out connection 234698513 from pool. [DEBUG] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@dfd3711] [DEBUG] - ==> Preparing: select * from student where sid=? and s_name=? [DEBUG] - ==> Parameters: 2(Integer), hjj(String) [DEBUG] - <== Total: 1 Student{SID=2, Sname='hjj', Sage=23, Ssex='null', course=null} [DEBUG] - Cache Hit Ratio [MyBatisDemo.StudentMapper]: 0.0 [DEBUG] - Opening JDBC Connection [DEBUG] - Created connection 1843368112. [DEBUG] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@6ddf90b0] [DEBUG] - ==> Preparing: select * from student where sid=? and s_name=? [DEBUG] - ==> Parameters: 2(Integer), hjj(String) [DEBUG] - <== Total: 1 Student{SID=2, Sname='hjj', Sage=23, Ssex='null', course=null} [DEBUG] - Cache Hit Ratio [MyBatisDemo.StudentMapper]: 0.0 Student{SID=2, Sname='hjj', Sage=23, Ssex='null', course=null} [DEBUG] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@dfd3711] [DEBUG] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@dfd3711] [DEBUG] - Returned connection 234698513 to pool.
該顏色:表示會話1第一次查詢的結果,因爲第一次查詢,一級緩存和二級緩存中都沒有數據,因此Mapper命中率爲0.0,且進行了數據庫查詢,並將結果存儲到會話1一級緩存中。數據結構
該顏色:表示會話2第一次查詢的結果,因爲會話1沒有關閉,因此會話1的一級緩存不會刷到Mapper的二級緩存中,而且是在會話2中第一次查詢該方法,因此Mapper命中率爲0.0,且進行了數據庫查詢,並將結果存儲到會話2的一級緩存中。mybatis
運行結果:app
[DEBUG] - Cache Hit Ratio [MyBatisDemo.StudentMapper]: 0.0 [DEBUG] - Opening JDBC Connection [DEBUG] - Checked out connection 234698513 from pool. [DEBUG] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@dfd3711] [DEBUG] - ==> Preparing: select * from student where sid=? and s_name=? [DEBUG] - ==> Parameters: 2(Integer), hjj(String) [DEBUG] - <== Total: 1 Student{SID=2, Sname='hjj', Sage=23, Ssex='null', course=null} [DEBUG] - Cache Hit Ratio [MyBatisDemo.StudentMapper]: 0.0 Student{SID=2, Sname='hjj', Sage=23, Ssex='null', course=null} [DEBUG] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@dfd3711] [DEBUG] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@dfd3711] [DEBUG] - Returned connection 234698513 to pool. [DEBUG] - Cache Hit Ratio [MyBatisDemo.StudentMapper]: 0.3333333333333333 Student{SID=2, Sname='hjj', Sage=23, Ssex='null', course=null} [DEBUG] - Cache Hit Ratio [MyBatisDemo.StudentMapper]: 0.5 Student{SID=2, Sname='hjj', Sage=23, Ssex='null', course=null}