1. 程式人生 > >MyBatis學習筆記(5)

MyBatis學習筆記(5)

MyBatis入門之延遲載入

resultMap可以實現高階對映(使用association、collection實現一對一及一對多對映),association、collection具備延遲載入功能。

延遲載入:先從單表查詢、需要時再從關聯表去關聯查詢,大大提高資料庫效能,因為查詢單表要比關聯查詢多張錶速度要快。

使用association實現延遲載入

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

在查詢部落格的statement中使用association去延遲載入下邊的satatement(部落格作者,即關聯的使用者):

<select
id="findBlogAndUser" resultMap="BlogAndUser"> SELECT * FROM tbl_blog </select>

通過上邊的blogUserId來查詢關聯資訊:

 <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
    select 
        userId, userName
    from
tbl_user where userId = #{userid,jdbcType=INTEGER} </select>
  • 延遲載入resultMap
<resultMap type="com.icss.po.Blog" id="BlogAndUser">
    <id property="blogid" column="blogId" />
    <result property="blogtitle" column="blogTitle" />
    <result property="blogcontent"
column="blogContent" /> <association property="user" column="blogUserId" select="com.icss.dao.UserMapper.selectByPrimaryKey" javaType="com.icss.po.User"> <id property="userid" column="userId"/> <result property="username" column="userName" /> </association> </resultMap>

與非延遲載入的主要區別就在association標籤屬性多了select和column

  • 延遲載入配置

在mybatis核心配置檔案中配置:lazyLoadingEnabled、aggressiveLazyLoading

設定項 描述 允許值 允許值
lazyLoadingEnabled 全域性性設定懶載入。如果設為‘false’,則所有相關聯的都會被初始化載入 true/false false
aggressiveLazyLoading 當設定為‘true’的時候,懶載入的物件可能被任何懶屬性全部載入。否則,每個屬性都按需載入。 true/false true
<settings>

        <setting name="lazyLoadingEnabled" value="true"/>

        <setting name="aggressiveLazyLoading" value="false"/>

    </settings>
  • 測試程式碼
@Test
    public void testfindBlogAndUserLoading() throws Exception{

        SqlSession sqlSession =null;

        try {

            //mybatis配置檔案
            String resourse = "SqlMapConfig.xml";

            //獲取配置檔案流

            InputStream is = Resources.getResourceAsStream(resourse);

            //建立會話工廠
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

            //通過會話工廠獲取SqlSession
            sqlSession = sqlSessionFactory.openSession();

            //獲取代理物件
            BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);

            List<Blog> list = blogMapper.findBlogAndUser();

            for(int i=0;i<list.size();i++){

                Blog blog = list.get(i);

                System.out.println("部落格標題:"+blog.getBlogtitle());
                System.out.println("部落格內容:"+blog.getBlogcontent());

                User user = blog.getUser();

                System.out.println("部落格作者:"+user.getUsername());

            }

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            sqlSession.close();
        }

    }

延遲載入思考

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

實現方法如下:

定義兩個mapper方法:

  • 查詢部落格列表
  • 根據使用者id查詢使用者資訊

實現思路:

先去查詢第一個mapper方法,獲取部落格資訊列表;在程式中(service),按需去呼叫第二個mapper方法去查詢使用者資訊。

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

結果

DEBUG [main] - Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 552364977.
DEBUG [main] - Setting autocommit to false on JDBC Connection [[email protected]20ec6bb1]
DEBUG [main] - ==>  Preparing: SELECT * FROM tbl_blog 
DEBUG [main] - ==> Parameters: 
DEBUG [main] - <==      Total: 1
部落格標題:Mybatis入門
部落格內容:Mybatis入門程式內容
DEBUG [main] - ==>  Preparing: select userId, userName from tbl_user where userId = ? 
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - <==      Total: 1
部落格作者:Mr_Li
DEBUG [main] - Resetting autocommit to true on JDBC Connection [[email protected]20ec6bb1]
DEBUG [main] - Closing JDBC Connection [[email protected]20ec6bb1]
DEBUG [main] - Returned connection 552364977 to pool.

注意

寫程式碼過程中發現一個異常,然後並不是我自己引起的異常,而是因為匯入的mybatis包版本問題,異常程式碼如下:

java.lang.NullPointerException
    at com.icss.TestMybatis.testfindBlogAndUserLoading(TestMybatis.java:333)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

這是mybatis依賴包OGNL 2.6.9的一個bug,可以通過升級mybatis版本到 3.3.0及以上來解決此問題。

相關推薦

MyBatis學習筆記5——

SqlSession 例項在 MyBatis 中是非常強大的一個類。在這裡你會看到所有執行語句、提交或回滾事務和獲取對映器例項的方法。 在 SqlSession 類中有超過 20 個方法,所以將它們組合成易於理解的分組。 執行語句方法 這些方法被用來執行定義在

mybatis學習筆記(5)-配置檔案SqlMapConfig

本文主要講解SqlMapConfig配置檔案 SqlMapConfig.xml中配置的內容和順序如下 properties(屬性)settings(全域性配置引數)typeAliases(類型別名)typeHandlers(型別處理器)objectFactory(物件工

mybatis學習筆記(5)-配置檔案

mybatis學習筆記(5)-SqlMapConfig 標籤: mybatis 本文主要講解SqlMapConfig配置檔案 SqlMapConfig.xml中配置的內容和順序如下 properties(屬性) settings(全域

MyBatis學習筆記(5)

MyBatis入門之延遲載入 resultMap可以實現高階對映(使用association、collection實現一對一及一對多對映),association、collection具備延遲載入功能。 延遲載入:先從單表查詢、需要時再從關聯表去關聯查詢,大

MyBatis學習筆記5:認識使用typeHandlers配置型別處理器

簡述 註冊了的型別處理器會用於處理下面兩種情形: 為PreparedStatement設定一個引數,將引數從Java型別轉為JDBC型別。 從ResultSet中取出一個值,將結果從JDBC型別轉為Java型別。 型別處理器可分為以下兩類: MyB

myBatis學習筆記5)——一對多關聯表查詢

需求 上一篇筆記是一對一,一個學生對應一個老師,本次我們修改一下需求,一個老師有多個學生 參考:myBatis學習筆記(4)——一對一關聯表查詢 老師類: package com.bank.en

Mybatis學習筆記之一——牛刀小試

ans ive man 配置 typealias 操作 acc esp 配置文件 1、Mybaits核心對象SqlSession的作用:   (1)向SQL語句傳入參數;   (2)執行SQl語句;   (3)獲取執行SQL語句的結果;   (4)事務的控制; 2

mysql學習筆記(5-DDL命令)

mysql服務器端命令: DDL:數據定義語言,主要用於管理數據庫組件,例如表、索引、視圖、用戶、存儲過程 CREATE、ALTER、DROP DML:數據操縱語言,主要用管理表中的數據,實現數據的增、刪、改、查; INSERT, DELETE, UPDAT

python學習筆記5-自定義函數

函數調用 筆記 取值 修改 args pytho class 名稱 func 1 自定義函數   (1)函數代碼塊以def關鍵字開頭,然後函數標識符名稱和圓括號   (2)任何傳入參數和自變量必須放在圓括號中間。圓括號之間可以用於定義參數   (3)函數的第一行語句可以選擇

Jmeter學習筆記5-檢查點

sogo arc logs blog 繼續 sample com arch 毫秒 1.定義:Jmeter中的檢查點就是斷言中的響應斷言。 2.通過實例進行介紹: 以sogou.com搜索為例,檢查搜索關鍵字,search.jmx badboy錄制後導入Jmeter 集行參數

Python學習筆記5 【轉載】基本矩陣運算_20170618

ros class 簡單 lba spa 使用 常見 port 模塊 需要 numpy 庫支持 保存鏈接 http://www.cnblogs.com/chamie/p/4870078.html 1.numpy的導入和使用 from numpy import *;

mybatis學習筆記

mybatis 學習 小於號 雙引號 引號 bsp 學習筆記 nbsp 大於 &lt; < 小於號 &gt; > 大於號 &amp; &a

學習筆記-5.3 shell編程2

shell編程25.3 shell編程2條件判斷: 如果用戶不存在 添加用戶,給密碼並顯示添加成功 否則 顯示如果已經存在,沒有添加bash中如何實現條件判斷?條件測試類型: 整數測試 字符測試 文件測試條件測試的表達式: [ expressopm ]

scalikejdbc 學習筆記(5)

() div mono arr where turn operation into class 常用增刪改查操作: import scalikejdbc._ import scalikejdbc.config._ object CommonOperation { d

mybatis學習筆記(三)-- 優化數據庫連接配置

bsp pro 新建 數據 配置信息 onf ron XML oca 原來直接把數據庫連接配置信息寫在conf.xml配置中,如下 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configura

myBatis學習筆記(10)——使用攔截器實現分頁查詢

條件 iba execute rri itl alias property gen func 1. Page package com.sm.model; import java.util.List; public class Page<T&g

FreeRTOS學習筆記5-靜態方式創建任務函數

api函數 depth 還需要 而不是 ica alloc nbsp 分配 類型 配置完成後的進行任務創建,使用靜態方式創建任務時需要使將宏 configSUPPORT_STATIC_ALLOCATION設置為 1,即使用靜態內存。還需要將函數 vApplicationGe

mybatis學習筆記(10)-一對一查詢

creat art ota div system spl 指定 tor block mybatis學習筆記(10)-一對一查詢

mybatis學習筆記(14)-查詢緩存之中的一個級緩存

set mybatis 運行時 二級緩存 ria ice rac com 配置 mybatis學習筆記(14)-查詢緩存之中的一個級緩存

LR學習筆記5-LR界面分析3

數據 -html 統計 統計信息 ip地址 目錄 str 設置方法 文件中 本次最後一次介紹LR的界面了,這次學完,LR的三大組件就有了一定的了解了。 --Analysis基礎知識 --了解Analysis報告 --Analysis分析基礎 --IP欺詐 1、Analysi