MyBatis一級緩存,二級緩存的實現

本文章介紹實現:

一級緩存:

是指SqlSession。一級緩存的做用域是一個SqlSessionMybatis默認開啓一級緩存java

在同一個SqlSession中,執行相同的查詢SQL,第一次會去查詢數據庫,並寫到緩存中;第二次直接從緩存中取。當執行SQL時兩次查詢中間發生了增刪改操做,則SqlSession的緩存清空。mysql


二級緩存:

是指mapper映射文件。二級緩存的做用域是同一個namespace下的mapper映射文件內容,多個SqlSession共享。Mybatis須要手動設置啓動二級緩存sql

在同一個namespace下的mapper文件中,執行相同的查詢SQL,第一次會去查詢數據庫,並寫到緩存中;第二次直接從緩存中取。當執行SQL時兩次查詢中間發生了增刪改操做,則二級緩存清空。數據庫


 

一.一級緩存的生命週期:

1.MyBatis開啓一個會話時,建立SqlSession對象,Excutor對象,PerpetualCache對象。apache

2.會話結束時或SqlSession調用close()方法,釋放建立的3個對象。緩存

3.SqlSession調用clearCache()方法否,會清空所有一級緩存當對象仍然存在,可重複使用。session

4.SqlSession執行修改刪除添加操做時,會清空PerpetualCache對象。mybatis

 


 

二.二級緩存的過時時間:

1.二級緩存有過時時間,並非key-value的過時時間,而是這個cache的過時時間,是flushInterval,意味着整個清空緩存cache,因此不須要後臺線程去定時檢測。app

2.每當存取數據的時候,都有檢測一下cache的生命時間,默認是1小時,若是這個cache存活了一個小時,那麼將整個清空一下。工具

注意:

因爲二級緩存的數據不必定都是存儲到內存中,它的存儲介質多種多樣,因此須要給緩存的對象執行序列化。

若是該類存在父類,那麼父類也要實現序列化。


 

一級緩存實現:

搭建MyBatis環境:

1.db.properties

1 jdbc.driver=com.mysql.jdbc.Driver
2 jdbc.url=jdbc:mysql://localhost:3306/(數據庫)
3 jdbc.username=root
4 jdbc.password=123456

 

2.mybatis-config.xml

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <!DOCTYPE configuration
 3         PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 4         "http://mybatis.org/dtd/mybatis-3-config.dtd">
 5 <configuration>
 6     <!--加載數據庫配置文件-->
 7     <properties resource="db.properties"/>
 8     <settings>
 9         <!--打印執行過程,因爲一級緩存是自動開啓的,不須要手動開啓-->
10         <setting name="logImpl" value="STDOUT_LOGGING"/>
11     </settings>
12     <!--給ccom.Charon.enty包下全部的實體類指定別名-->
13     <typeAliases>
14         <package name="com.Charon.enty"/>
15     </typeAliases>
16 
17     <!-- 數據庫鏈接環境的配置 -->
18     <environments default="development">
19         <environment id="development">
20             <!-- 事務管理器JDBC -->
21             <transactionManager type="JDBC" />
22             <!-- 數據源-->
23             <dataSource type="POOLED">
24                 <property name="driver" value="${jdbc.driver}"/>
25                 <property name="url" value="${jdbc.url}" />
26                 <property name="username" value="${jdbc.username}" />
27                 <property name="password" value="${jdbc.password}" />
28             </dataSource>
29         </environment>
30     </environments>
31     <mappers>
32         <!--必須全包名,否則找不到-->
33         <mapper resource="com/Charon/dao/userMapper.xml"></mapper>
34     </mappers>
35 </configuration>

 

3.userMapper.xml

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE mapper
 3         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 4         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 5 <mapper namespace="com.Charon.dao.UserMapper">
 6     <select id="findUserAll" resultType="user">
 7         SELECT
 8         id id,
 9         username username,
10         userpwd userpassword
11         FROM
12         user
13     </select>
14 </mapper>

 

4.接口UserMapper

 1 package com.Charon.dao;
 2 
 3 import com.Charon.enty.User;
 4 
 5 import java.util.List;
 6 
 7 /**
 8  * @Description TODO
 9  * @Author Charon <1819248612@qq.com>
10  * @create 2020-10-27-21:44
11  * @Version 1.0.0
12  */
13 public interface UserMapper {
14     //查詢數據庫用戶信息
15     List<User> findUserAll();
16 }

 

5.實體類User

**
 * @Description TODO 用戶實體類
 * @Author Charon <1819248612@qq.com>
 * @create 2020-10-27-21:37
 * @Version 1.0.0
 */
public class User {
    private Integer id;
    private String username;
    private String userpassword;
    
    //getter ,serter方法省略        
}

 

6.工具類

 1 package com.Charon.utile;
 2 
 3 import org.apache.ibatis.io.Resources;
 4 import org.apache.ibatis.session.SqlSession;
 5 import org.apache.ibatis.session.SqlSessionFactory;
 6 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
 7 
 8 import java.io.IOException;
 9 import java.io.InputStream;
10 import java.io.Reader;
11 
12 /**
13  * @Description TODO  代理工廠類
14  * @Author Charon <1819248612@qq.com>
15  * @create 2020-10-21-8:59
16  * @Version 1.0.0
17  */
18 public class MyBatisUtil {
19 
20     private final  static SqlSessionFactory sqlSessionFactory;
21 
22     static {
23         String resource="mybatis-config.xml";
24         Reader reader =null;
25         try {
26             reader = Resources.getResourceAsReader(resource);
27         } catch (IOException e) {
28             e.printStackTrace();
29         }
30         sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
31     }
32 
33     /**
34      * 獲取SqlSessionFactory
35      * @return SqlSessionFactory
36      */
37     public static SqlSessionFactory getSqlSessionFactory(){
38         return sqlSessionFactory;
39     }
40 
41     /**
42      * 獲取SqlSession
43      * @return SqlSession
44      */
45     public static SqlSession getSqlSession(){
46         return sqlSessionFactory.openSession();
47     }
48 
49     /**
50      * 關閉SqlSession
51      */
52     public  static void closeSession(SqlSession sqlSession){
53         if (sqlSession!=null)
54             sqlSession.close();
55     }
56 }

 

7.測試,這裏調用了兩次查詢

 @Test
    public void test() {
        SqlSession sqlSession = MyBatisUtil.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
       //第一次查詢
        List<User> userAll = mapper.findUserAll();
        for (int i = 0; i < userAll.size(); i++) {
            User user = userAll.get(i);
            System.out.println(user);
        }
       // 第二次查詢
        List<User> userAlls = mapper.findUserAll();
        for (int i = 0; i < userAlls.size(); i++) {
            User user = userAlls.get(i);
            System.out.println(user);
        }
    }

 

8.結果,經過運行結果能夠看出當前程序只調用了一次sql

 

 9.屏蔽一級緩存

在userMapper.xml查詢添加一個條件

flushCache=true

 

 

 10.屏蔽一級緩存後,展現效果

 


 

二級緩存實現

1.在mybatis-config.xml中設置

 

2.接口UserMapper

 1 package com.Charon.dao;
 2 
 3 import com.Charon.enty.User;
 4 
 5 import java.util.List;
 6 
 7 /**
 8  * @Description TODO
 9  * @Author Charon <1819248612@qq.com>
10  * @create 2020-10-27-21:44
11  * @Version 1.0.0
12  */
13 public interface UserMapper {
14     //查詢數據庫用戶信息
15     List<User> findUserAll();
16 
17     void updateUser(User user);
18 }

 

4.userMapper.xml

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE mapper
 3         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 4         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 5 <mapper namespace="com.Charon.dao.UserMapper">
 6     <!--flushCache=true:屏蔽一級緩存-->
 7     <select id="findUserAll" resultType="user">
 8         SELECT
 9         id id,
10         username username,
11         userpwd userpassword
12         FROM
13         user
14     </select>
15     <update id="updateUser" parameterType="user"  flushCache="true">
16         UPDATE user SET username=#{username},userpwd=#{userpassword} WHERE id=#{id}
17     </update>
18     <!--開啓本mapper的namespance下的二級緩存(默認的)-->
19     <cache></cache>
20 </mapper>

 

5.實體類實現Serializable接口

package com.Charon.enty;

import java.io.Serializable;

/**
 * @Description TODO 用戶實體類
 * @Author Charon <1819248612@qq.com>
 * @create 2020-10-27-21:37
 * @Version 1.0.0
 */
public class User implements Serializable{
    private Integer id;
    private String username;
    private String userpassword;

    //忽略getter setter方法
}

 

6.測試

 

 7.先把sqlSession註釋掉,查看一下二級緩存

 

 8.解注SqlSession3查看二級緩存

 


 

其餘配置(useCache和flushCache):

1.MyBatis還能夠配置userCache和flushCache等配置項。

2.useCache是用來設置是否禁用二級緩存的,在userMapper.xml中設置useCache=false能夠禁用當前select語句的二級緩存

,即每次查詢都會發出sql去查詢,默認狀況是true,即該sql使用二級緩存。

使用演示

<select id="findUserAll" resultType="user" useCache="false">

 

 

3.flushCache:

這種狀況是針對每次查詢都須要最新的數據sql,要設置成useCache=false,禁用二級緩存,直接從數據庫中獲取。
在mapper的同一個namespace中,若是有其它insert、update、delete操做數據後須要刷新緩存,若是不執行刷新緩存會出現髒讀。

設置statement配置中的flushCache=」true」 屬性,默認狀況下爲true,

即刷新緩存,若是改爲false則不會刷新。使用緩存時若是手動修改數據庫表中的查詢數據會出現髒讀。

<update id="updateUser" parameterType="user"  flushCache="true">

 

通常下執行完commit操做都須要刷新緩存,flushCache=true表示刷新緩存,這樣能夠避免數據庫髒讀。因此咱們不用設置,默認便可
相關文章
相關標籤/搜索