Mybatis的延時加載

延時加載和立即加載

  • 延遲加載:在真正使用數據時才發起查詢,不用的時候不查詢。按需加載(懶加載)
  • 立即加載:不管是否使用數據,只要一調用方法,馬上發起查詢。

Mybatis中選擇延時、立即加載

  • 一對多,多對多:通常情況下采用延遲加載。
  • 多對一,一對一:通常情況下采用立即加載。

一對一實現延時加載

需求:查詢一個賬戶時,同時查詢出該賬戶的所屬用戶信息,使用延時加載

*從表實體應該包含一個主表實體的對象引用

IAccountDao中的方法:
	/**
     * 查詢所有賬戶,同時還要獲取到當前賬戶的所屬用戶信息
     * @return
     */
    List<Account> findAll();

IAccountDao.xml文件中的配置:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sx.dao.IAccountDao">
    <!-- 定義封裝account和user的resultMap -->
    <resultMap id="accountUserMap" type="account">
        <id property="id" column="id"></id>
        <result property="uid" column="uid"></result>
        <result property="money" column="money"></result>
        <!-- 一對一的關係映射:配置封裝user的內容-->
        <!--
            select屬性制定的內容:查詢用戶的唯一標識
            column屬性指定內容:根據用戶id查詢時,所需要的參數的值
        -->
        <association property="user" column="uid" javaType="user" select="com.sx.dao.IUserDao.findById">
			 <!-- 對應的IUserDao.xml中的findById方法:根據id查詢用戶 -->
   			<!-- <select id="findById" parameterType="INT" resultType="user">
      			  select * from user where id = #{uid}
    		</select>-->
        </association>
    </resultMap>

    <!-- 查詢所有 -->
    <select id="findAll" resultMap="accountUserMap">
        select * from account
    </select>
</mapper>

要想使用延時加載,主配置文件中需要的配置
	<!--配置參數-->
    <settings>
        <!--全局延時加載-->
        <setting name="lazyLoadingEnabled" value="true"/>
        <setting name="aggressiveLazyLoading" value="false"/>
    </settings>
測試類代碼以及測試結果
public class AccountTest {

    private InputStream in;
    private SqlSession sqlSession;
    private IAccountDao accountDao;

    @Before//用於在測試方法執行之前執行
    public void init()throws Exception{
        //1.讀取配置文件,生成字節輸入流
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.獲取SqlSessionFactory
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        //3.獲取SqlSession對象
        sqlSession = factory.openSession(true);
        //4.獲取dao的代理對象
        accountDao = sqlSession.getMapper(IAccountDao.class);
    }

    @After//用於在測試方法執行之後執行
    public void destroy()throws Exception{
        //提交事務
        // sqlSession.commit();
        //6.釋放資源
        sqlSession.close();
        in.close();
    }

    /**
     * 測試查詢所有
     */
    @Test
    public void testFindAll(){
        List<Account> accounts = accountDao.findAll();
        for(Account account : accounts){
            System.out.println("--------每個account的信息------------");
            System.out.println(account);
            System.out.println(account.getUser());
        }
    }
}
延時加載

在這裏插入圖片描述

立即加載

在這裏插入圖片描述

一對多實現延時加載

需求:查詢一個用戶時,同時查詢該用戶所有的賬戶信息,使用延時加載

*主表實體應該包含從表實體的集合引用

IUserDao中的方法:
	/**
     * 查詢所有用戶,同時獲取到用戶下所有賬戶的信息
     * @return
     */
    List<User> findAll();

IUserDao.xml文件中的配置:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sx.dao.IUserDao">

    <!-- 定義User的resultMap-->
    <resultMap id="userAccountMap" type="user">
        <id property="id" column="id"></id>
        <result property="username" column="username"></result>
        <result property="address" column="address"></result>
        <result property="sex" column="sex"></result>
        <result property="birthday" column="birthday"></result>
        <!-- 配置user對象中accounts集合的映射 -->
        <collection property="accounts" ofType="account" column="id" select="com.sx.dao.IAccountDao.findAccountByUid">
		<!-- 對應的IAccountDao.xml中的方法:根據用戶id查詢賬戶列表 -->
		<!--<select id="findAccountByUid" resultType="account">
        	select * from account where uid = #{uid}
   		 </select>-->
        </collection>
    </resultMap>

    <!-- 查詢所有 -->
    <select id="findAll" resultMap="userAccountMap">
        select * from user
    </select>

    <!-- 根據id查詢用戶 -->
    <select id="findById" parameterType="INT" resultType="user">
        select * from user where id = #{uid}
    </select>
</mapper>
測試類代碼以及測試結果
public class UserTest {

    private InputStream in;
    private SqlSession sqlSession;
    private IUserDao userDao;

    @Before//用於在測試方法執行之前執行
    public void init()throws Exception{
        //1.讀取配置文件,生成字節輸入流
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.獲取SqlSessionFactory
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        //3.獲取SqlSession對象
        sqlSession = factory.openSession(true);
        //4.獲取dao的代理對象
        userDao = sqlSession.getMapper(IUserDao.class);
    }

    @After//用於在測試方法執行之後執行
    public void destroy()throws Exception{
        //提交事務
        // sqlSession.commit();
        //6.釋放資源
        sqlSession.close();
        in.close();
    }

    /**
     * 測試查詢所有
     */
    @Test
    public void testFindAll(){
        List<User> users = userDao.findAll();
        for(User user : users){
            System.out.println("-----每個用戶的信息------");
            System.out.println(user);
            System.out.println(user.getAccounts());
        }
    }
}
測試結果

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章