resultMap可以實現高級映射(使用association、collection實現一對一及一對多映射),association、collection具備延遲加載功能。
延遲加載:先從單表查詢、需要時再從關聯表去關聯查詢,大大提高數據庫性能,因為查詢單表要比關聯查詢多張表速度要快。
在查詢博客的statement中使用association去延遲加載下邊的satatement(博客作者,即關聯的用戶):
<select id="findBlogAndUser" resultMap="BlogAndUser"> SELECT * FROM tbl_blog </select>通過上邊的blogUserId來查詢關聯信息:
<select id="selectByjava.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 |
不使用mybatis提供的association及collection中的延遲加載功能,如何實現延遲加載??
實現方法如下:
定義兩個mapper方法:
查詢博客列表根據用戶id查詢用戶信息實現思路:
先去查詢第一個mapper方法,獲取博客信息列表;在程序中(service),按需去調用第二個mapper方法去查詢用戶信息。
總之,使用延遲加載方法,先去查詢簡單的sql(最好單表,也可以關聯查詢),再去按需要加載關聯查詢的其它信息。
寫代碼過程中發現一個異常,然后并不是我自己引起的異常,而是因為導入的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官方issue說明: https://github.com/mybatis/mybatis-3/issues/224
新聞熱點
疑難解答