1. 程式人生 > 資訊 >電動汽車公司 Rivian 第四季度淨虧損 24.61 億美元,盤後股價大跌 13%

電動汽車公司 Rivian 第四季度淨虧損 24.61 億美元,盤後股價大跌 13%

引言

什麼是快取:
    存在於記憶體中的臨時資料。
為什麼使用快取:
    減少和資料庫的互動次數,提高執行效率。
什麼樣的資料能用快取,什麼資料不能使用:
    適用於快取:
        經常查詢並且不經常改變的
        資料的正確與否對最終結果影響不大(因為快取代表著會與資料庫資料不同)
不適用於快取:
經常改變的資料
資料的正確與否對最終結果影響很大的
例如:商品的庫存,銀行的匯率,股市的牌價

一級快取

定義
mybatis中SqlSession物件的快取。當我們執行查詢之後,查詢的結果會同時存入到SqlSession為我們提供的一塊區域中。該區域的結構是一個Map。當我們再次查詢同樣的資料,mybatis會先去SqlSession中檢視是否有,有的話直接拿出來用。
當SqlSession物件消失時,一級快取也就消失了。

一級快取演示

    @Test
    public void testFirstLevelCache(){
        User user1 = dao.findById(41);
        System.out.println(user1);
        User user2 = dao.findById(41);
        System.out.println(user2);

        System.out.println(user1 == user2);
    }

只進行一次查詢,第二次查詢使用的是一級快取,獲取的物件也是相同地址的。

    @Test
    public void testFirstLevelCache(){
        User user1 = dao.findById(41);
        System.out.println(user1);

        session.close();
        session = factory.openSession();
        dao = session.getMapper(UserDao.class);
        /**可用:session.clearCache(); 清空快取**/

        User user2 = dao.findById(41);
        System.out.println(user2);

        System.out.println(user1 == user2);
    }

執行了兩次查詢,物件地址不相同,證明第二個user是再new一次的

如果一級快取中的資料域資料庫不一致如何做到同步

更新辦法

    <update id="updateUser" parameterType="user">
        update user set id = #{id}
        <if test="username != null and username != ''">
            ,username = #{username}
        </if>
        <if test="address != null and address != ''">
            ,address = #{address}
        </if>
        <if test="sex != null and sex != ''">
            ,sex = #{sex}
        </if>
        <if test="birthday != null">
            ,birthday = #{birthday}
        </if>
         where id = #{id}
    </update>

演示

    @Test
    public void testFirstLevelCache(){
        User user1 = dao.findById(41);
        System.out.println(user1);

        User user = new User();
        user.setId(41);
        user.setUsername("clear cache");
        user.setSex("女");
        dao.updateUser(user);

        User user2 = dao.findById(41);
        System.out.println(user2);

        System.out.println(user1 == user2);
    }

可以看出更新後,就不會從一級快取中查詢,而是進行一次新的查詢

原因

當呼叫SqlSession的修改,新增,刪除,commit(),close()等方法時,就會清空一級快取

二級快取

定義
指的是Mybatis中SqlSessionFactory物件的快取。由同一個SqlSessionFactory物件建立的SqlSession共享其快取。

二級快取的使用步驟
第一步:讓mybatis框架支援二級快取(在SqlMapConfig.xml中配置)

    <settings>
        <setting name="cacheEnabled" value="true"/>
    </settings>

第二步:讓當前的對映檔案支援二級快取(在UserDao.xml中配置)

    <!--開啟user支援二級快取-->
    <cache></cache>

第三步:讓當前的操作支援二級快取(在select標籤中配置)

    <!--根據id查詢單個使用者-->
    <select id="findById" resultType="com.czy.domain.User" parameterType="INT" useCache="true">
        select * from user where id = #{id};
    </select>

測試

    @Test
    public void testSecondLevelCache(){
        SqlSession session1 = factory.openSession();
        UserDao dao1 = session1.getMapper(UserDao.class);
        User user1 = dao1.findById(41);
        System.out.println(user1);
        session1.close(); //一級快取消失


        SqlSession session2 = factory.openSession();
        UserDao dao2 = session2.getMapper(UserDao.class);
        User user2 = dao2.findById(41);
        System.out.println(user2);
        session2.close();

        System.out.println(user1 == user2);
    }

只進行了一次查詢,第二次直接呼叫快取,由於儲存的是資料不是物件,故比較結果為false