国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

通過項目逐步深入了解Mybatis(四)

kuangcaibao / 841人閱讀

摘要:相關閱讀通過項目逐步深入了解一通過項目逐步深入了解二通過項目逐步深入了解三本項目所有代碼及文檔都托管在地址延遲加載什么是延遲加載可以實現高級映射使用實現一對一及一對多映射,具備延遲加載功能。一級緩存是級別的緩存。

相關閱讀:

1、通過項目逐步深入了解Mybatis<一>

2、通過項目逐步深入了解Mybatis<二>

3、通過項目逐步深入了解Mybatis<三>

本項目所有代碼及文檔都托管在 Github地址:https://github.com/zhisheng17/mybatis

延遲加載 什么是延遲加載?

resultMap可以實現高級映射(使用association、collection實現一對一及一對多映射),association、collection具備延遲加載功能。
需求:
如果查詢訂單并且關聯查詢用戶信息。如果先查詢訂單信息即可滿足要求,當我們需要查詢用戶信息時再查詢用戶信息。把對用戶信息的按需去查詢就是延遲加載。

延遲加載:先從單表查詢、需要時再從關聯表去關聯查詢,大大提高 數據庫性能,因為查詢單表要比關聯查詢多張表速度要快。

打開延遲加載開關

在mybatis核心配置文件中配置:

lazyLoadingEnabled、aggressiveLazyLoading

設置項 描述 允許值 默認值
lazyLoadingEnabled 全局性設置懶加載。如果設為‘false’,則所有相關聯的都會被初始化加載。 true false false
aggressiveLazyLoading 當設置為‘true’的時候,懶加載的對象可能被任何懶屬性全部加載。否則,每個屬性都按需加載。 true false true

        
        
使用 association 實現延遲加載

需求:查詢訂單并且關聯查詢用戶信息

Mapper.xml

需要定義兩個 mapper 的方法對應的 statement。

1、只查詢訂單信息

SQL 語句: select * from orders

在查詢訂單的 statement 中使用 association 去延遲加載(執行)下邊的 statement (關聯查詢用戶信息)


    

2、關聯查詢用戶信息

通過上面查詢訂單信息中的 user_id 來關聯查詢用戶信息。使用 UserMapper.xml 中的 findUserById

SQL語句:select * from user where id = user_id

上邊先去執行 findOrdersUserLazyLoading,當需要去查詢用戶的時候再去執行 findUserById ,通過 resultMap的定義將延遲加載執行配置起來。也就是通過 resultMap 去加載 UserMapper.xml 文件中的 select = findUserById

延遲加載的 resultMap

    
        
        
        
        
        
        
        
        
        
    
OrderMapperCustom.java
public List findOrdersUserLazyLoading() throws Exception;
測試代碼:
@Test
    public void testFindOrdersUserLazyLoading() throws Exception
    {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //創建OrdersMapperCustom對象,mybatis自動生成代理對象
        OrdersMapperCustom ordersMapperCustom = sqlSession.getMapper(OrdersMapperCustom.class);
        //查詢訂單信息
        List list = ordersMapperCustom.findOrdersUserLazyLoading();
        //遍歷所查詢的的訂單信息
        for (Orders orders : list)
        {
            //查詢用戶信息
            User user = orders.getUser();
            System.out.println(user);
        }
        sqlSession.close();
    }
測試結果:

整個延遲加載的思路:

1、執行上邊mapper方法(findOrdersUserLazyLoading),內部去調用cn.zhisheng.mybatis.mapper.OrdersMapperCustom 中的 findOrdersUserLazyLoading 只查詢 orders 信息(單表)。

2、在程序中去遍歷上一步驟查詢出的 List,當我們調用 Orders 中的 getUser 方法時,開始進行延遲加載。

3、延遲加載,去調用 UserMapper.xml 中 findUserbyId 這個方法獲取用戶信息。

思考:

不使用 mybatis 提供的 association 及 collection 中的延遲加載功能,如何實現延遲加載??

實現方法如下:

定義兩個mapper方法:

1、查詢訂單列表

2、根據用戶id查詢用戶信息

實現思路:

先去查詢第一個mapper方法,獲取訂單信息列表

在程序中(service),按需去調用第二個mapper方法去查詢用戶信息。

總之:

使用延遲加載方法,先去查詢 簡單的 sql(最好單表,也可以關聯查詢),再去按需要加載關聯查詢的其它信息。

一對多延遲加載

上面的那個案例是一對一延遲加載,那么如果我們想一對多進行延遲加載呢,其實也是很簡單的。

一對多延遲加載的方法同一對一延遲加載,在collection標簽中配置select內容。

延遲加載總結:

作用:

當需要查詢關聯信息時再去數據庫查詢,默認不去關聯查詢,提高數據庫性能。
只有使用resultMap支持延遲加載設置。

場合:

當只有部分記錄需要關聯查詢其它信息時,此時可按需延遲加載,需要關聯查詢時再向數據庫發出sql,以提高數據庫性能。

當全部需要關聯查詢信息時,此時不用延遲加載,直接將關聯查詢信息全部返回即可,可使用resultType或resultMap完成映射。

查詢緩存 什么是查詢緩存?

mybatis提供查詢緩存,用于減輕數據壓力,提高數據庫性能。

mybaits提供一級緩存,和二級緩存。

一級緩存是SqlSession級別的緩存。在操作數據庫時需要構造 sqlSession對象,在對象中有一個數據結構(HashMap)用于存儲緩存數據。不同的sqlSession之間的緩存數據區域(HashMap)是互相不影響的。

二級緩存是mapper級別的緩存,多個SqlSession去操作同一個Mapper的sql語句,多個SqlSession可以共用二級緩存,二級緩存是跨SqlSession的。

為什么要用緩存?

如果緩存中有數據就不用從數據庫中獲取,大大提高系統性能。

一級緩存

工作原理

第一次發起查詢用戶id為1的用戶信息,先去找緩存中是否有id為1的用戶信息,如果沒有,從數據庫查詢用戶信息。

得到用戶信息,將用戶信息存儲到一級緩存中。

如果sqlSession去執行commit操作(執行插入、更新、刪除),清空SqlSession中的一級緩存,這樣做的目的為了讓緩存中存儲的是最新的信息,避免臟讀。

第二次發起查詢用戶id為1的用戶信息,先去找緩存中是否有id為1的用戶信息,緩存中有,直接從緩存中獲取用戶信息。

一級緩存測試

Mybatis 默認支持一級緩存,不需要在配置文件中配置。

所以我們直接按照上面的步驟進行測試:

//一級緩存測試
    @Test
    public void  testCache1() throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //創建UserMapper對象,mybatis自動生成代理對象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //查詢使用的是同一個session
        //第一次發起請求,查詢Id 為1的用戶信息
        User user1 = userMapper.findUserById(1);
        System.out.println(user1);
        //第二次發起請求,查詢Id 為1的用戶信息
        User user2 = userMapper.findUserById(1);
        System.out.println(user2);
        sqlSession.close();
    }

通過結果可以看出第二次沒有發出sql查詢請求,

所以我們需要在中間執行 commit 操作

//如果sqlSession去執行commit操作(執行插入、更新、刪除),
// 清空SqlSession中的一級緩存,這樣做的目的為了讓緩存中存儲的是最新的信息,避免臟讀。
//更新user1的信息,
user1.setUsername("李飛");
//user1.setSex("男");
//user1.setAddress("北京");
userMapper.updateUserById(user1);
//提交事務,才會去清空緩存
sqlSession.commit();

測試

一級緩存應用

正式開發,是將 mybatis 和 spring 進行整合開發,事務控制在 service 中。

一個 service 方法中包括很多 mapper 方法調用。

service{

     //開始執行時,開啟事務,創建SqlSession對象

     //第一次調用mapper的方法findUserById(1)

     //第二次調用mapper的方法findUserById(1),從一級緩存中取數據

     //方法結束,sqlSession關閉

}

如果是執行兩次service調用查詢相同的用戶信息,不走一級緩存,因為session方法結束,sqlSession就關閉,一級緩存就清空。

二級緩存

原理

首先開啟mybatis的二級緩存。

sqlSession1去查詢用戶id為1的用戶信息,查詢到用戶信息會將查詢數據存儲到二級緩存中。

如果SqlSession3去執行相同 mapper下sql,執行commit提交,清空該 mapper下的二級緩存區域的數據。

sqlSession2去查詢用戶id為1的用戶信息,去緩存中找是否存在數據,如果存在直接從緩存中取出數據。

二級緩存與一級緩存區別,二級緩存的范圍更大,多個sqlSession可以共享一個UserMapper的二級緩存區域。

UserMapper有一個二級緩存區域(按namespace分) ,其它mapper也有自己的二級緩存區域(按namespace分)。

每一個namespace的mapper都有一個二緩存區域,兩個mapper的namespace如果相同,這兩個mapper執行sql查詢到數據將存在相同的二級緩存區域中。

開啟二級緩存

mybaits的二級緩存是mapper范圍級別,除了在SqlMapConfig.xml設置二級緩存的總開關,還要在具體的mapper.xml中開啟二級緩存

在 SqlMapConfig.xml 開啟二級開關


然后在你的 Mapper 映射文件中添加一行: ,表示此 mapper 開啟二級緩存。

調用 pojo 類實現序列化接口

二級緩存需要查詢結果映射的pojo對象實現java.io.Serializable接口實現序列化和反序列化操作(因為二級緩存數據存儲介質多種多樣,在內存不一樣),注意如果存在父類、成員pojo都需要實現序列化接口。

public class Orders implements Serializable
public class User implements Serializable

測試

//二級緩存測試
    @Test
    public void testCache2() throws Exception
    {
        SqlSession sqlSession1 = sqlSessionFactory.openSession();
        SqlSession sqlSession2 = sqlSessionFactory.openSession();
        SqlSession sqlSession3 = sqlSessionFactory.openSession();


        //創建UserMapper對象,mybatis自動生成代理對象
        UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
        //sqlSession1 執行查詢 寫入緩存(第一次查詢請求)
        User user1 = userMapper1.findUserById(1);
        System.out.println(user1);
        sqlSession1.close();


        //sqlSession3  執行提交  清空緩存
        UserMapper userMapper3 = sqlSession3.getMapper(UserMapper.class);
        User user3 = userMapper3.findUserById(1);
        user3.setSex("女");
        user3.setAddress("山東濟南");
        user3.setUsername("崔建");
        userMapper3.updateUserById(user3);
        //提交事務,清空緩存
        sqlSession3.commit();
        sqlSession3.close();
        
        //sqlSession2 執行查詢(第二次查詢請求)
        UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
        User user2 = userMapper2.findUserById(1);
        System.out.println(user2);
        sqlSession2.close();
   }

結果

useCache 配置

在 statement 中設置 useCache=false 可以禁用當前 select 語句的二級緩存,即每次查詢都會發出sql去查詢,默認情況是true,即該sql使用二級緩存。