Mybatis09_一對一、一對多、多對多、延遲載入

weixin_44051048發表於2020-11-29

(1)查詢:

1、 一對一 查詢

查詢user表及其對應的account表的資料

方式一: 利用繼承的方式來解決(不常用)

(繼承了某一類的全部基本屬性,在該類中就有了資料庫所對應的欄位)

實體類:
在這裡插入圖片描述

用於查詢的實體類:

(繼承了Account類,就有了account表要對應的屬性)

在這裡插入圖片描述

對映檔案:(查詢user表和account表)

要查詢的資訊為user表和account表中對應的資訊,寫一個類,裡面有account表中的屬性,
在繼承user類,該類中就有了user表和account表中的所有屬性

查詢結果會根據  查詢資料庫的結果的欄位名  和  對映類的類名對應
<!--一對一表,使用繼承的方式進行封裝(不常用)-->
<select id="findAllAccountUsers" resultType="com.zy.domain.AccountUser2">
    select  *  from account,user where user.id = account.uid;
</select>

測試方法:

public static void main(String[] args) throws IOException {
   InputStream in = Resources.getResourceAsStream("Mybatis_config.xml");
   SqlSession sqlSession = new SqlSessionFactoryBuilder().build(in).openSession();
   IAccountDao iAccountDao = sqlSession.getMapper(IAccountDao.class);
   List<AccountUser2> all = iAccountDao.findAllAccountUsers();
   for (AccountUser2 account : all) {
      System.out.println(account.toString());
   }
   sqlSession.close();
   in.close();
}

方式二:利用對映檔案的重新指定封裝類對應的每一個資料庫列表值(常用)

封裝的實體類:
在這裡插入圖片描述

對映檔案:

在這裡插入圖片描述

2、 一對多 的查詢

​需求:
​		查詢所有使用者資訊及使用者關聯的賬戶資訊。(user表和account表進行關聯)
分析:
​	   使用者資訊和他的賬戶資訊為一對多關係,並且查詢過程中如果使用者沒有賬戶資訊,
	   此時也要將使用者資訊查詢出來,我們想到了左外連線查詢比較合適。

建立存放資料的實體類:userList

一個user裡面對應著裡面有多個使用者Account

在這裡插入圖片描述

對映檔案資訊:

實體類中的每一個欄位,對應著查詢到的資料中的哪一個欄位??

在這裡插入圖片描述

測試類

public static void main(String[] args) throws Exception {
   InputStream in = Resources.getResourceAsStream("Mybatis_config.xml");
   SqlSession sqlSession = new SqlSessionFactoryBuilder().build(in).openSession();
   IUserDao iUserDao = sqlSession.getMapper(IUserDao.class);
   List<UserList> all = iUserDao.findUserListAll();
   for (UserList temp:all) {
      System.out.println(temp.toString());
   }
}

3、多對多的查詢:

​例項:使用者和角色(就相當於兩個一對多)

​		一個使用者可以對應多個角色

​		一個角色可以對應對個使用者

步驟:

​	1、建立兩張表:使用者表,角色表
​			    讓使用者表和角色表具有多對多的關係。
				需要使用中間表,中間表中包使用者表和角色表的關係
				
​	2、建立兩個實體類:使用者實體類和角色實體類
​				讓使用者和角色的實體類能體現出來多對多的關係
​					(各自實體類包含對方一個集合引用)

​	3、建立兩個配置檔案
​				使用者的配置檔案
​				角色的配置檔案

​	4、實現配置:
​				當我們查詢使用者時,可以同時得到使用者所包含的角色資訊
​				當我們查詢角色時,可以同時得到角色的所賦予的使用者資訊

在這裡插入圖片描述

(可以看出一個user可能對應著兩個角色,一個角色可能對應著兩個user)

一個User對應多個Role

​實體類:
在這裡插入圖片描述

對映檔案:

<resultMap id="UserRoleMap" type="com.zy.domain.UserRoleList">
    <result property="username"  column="username"></result>
    <result property="birthday"  column="birthday"></result>
    <result property="sex"  column="sex"></result>
    <result property="address"  column="address"></result>
    <!-- 實體類中的集合的對應 -->
    <collection property="roles" ofType="com.zy.domain.UserRoleList">
        <id property="roleId" column="id"></id>
        <result property="roleName" column="role_name"></result>
        <result property="roleDesc" column="role_desc"></result>
    </collection>
</resultMap>

<select id="findYYY" resultMap="UserRoleMap">
    SELECT
    u.*,
    r.id as rid,
    r.role_name ,
    u.role_desc
FROM
    ROLE u
        INNER JOIN
    USER_ROLE ur
    ON ( u.id = ur.uid)
        INNER JOIN
    role r
    ON (r.id = ur.rid);
</select>

測試方法:

public static void main(String[] args) throws IOException {
   InputStream in = Resources.getResourceAsStream("Mybatis_config.xml");
   SqlSession sqlSession = new SqlSessionFactoryBuilder().build(in).openSession();
   IUserDao iUserDao = sqlSession.getMapper(IUserDao.class);
   List<UserRoleList> all = iUserDao.findYYY();
   for (UserRoleList temp:all) {
      System.out.println(temp.toString());
   }
}

一個Role對應多個user

	和上面類似,相當於寫一個一對多,
	一個Role中有一個user集合
	在配置配置檔案即可


(2)、 Mybatis的延遲載入:

1、什麼叫延遲載入??

​就是在需要用到資料時才進行載入,不需要用到資料時就不載入資料。

延遲載入也稱懶載入.按需載入

2、 什麼叫立即載入??

不管用不用資料,只要方法被呼叫,馬上發起查詢

3、延遲載入的好處與壞處:

好處:
		先從單表查詢,需要時再從關聯表去關聯查詢(一次性查出來,太浪費空間),
		大大提高資料庫效能,因為查詢單表要比關聯查詢多張錶速度要快。

壞處 :
		因為只有當需要用到資料時,才會進行資料庫查詢,這樣在大批量資料查詢時,
		因為查詢工作也要消耗時間,所以可能造成使用者等待時間變長,造成使用者體驗下降。

4、經常 什麼時候採用延遲載入?

關係表中有四種關係: 一對一      一對多    多對一    多對多

當關係為: 一對多    多對多(相當於一對多)  總而言之對應的多個的時候進行延遲載入

為什麼對應多個的時候進行延遲載入??

​	延遲查詢可以做到:  先從單表中查詢,需要時在從關聯表中關聯查詢對應的多條資料,
				       這樣大大提高了資料庫的效能。

5、什麼時候採用立即載入?

​關係表中有四種關係: 一對一      一對多    多對一    多對多
	
​當關係為: 一對一    多對一(相當於一對一) 總而言之對應的一個的時候進行立即載入
	
	為什麼對應一個的時候進行立即載入??
			立即查詢可以做到: 一條只對應一條,直接載入出來就完成了

6、使用 assocation 標籤 實現延遲載入

​	一對一進行的延遲載入:

​			第一步:寫響應的介面

​			第二步:IAccountDao.xml 對映配置檔案:
<mapper namespace="com.zy.Dao.IAccountDao">
        <resultMap type="com.zy.domain.AccountUserList" id="accountUserListMap">
            <id column="aid" property="id"/>
            <result column="uid" property="uid"/>
            <result column="money" property="money"/>
            <!--association標籤:處理單一的關聯物件 處理單一屬性的關聯關係 -->
            <!-- javaType屬性:該屬性的型別是什麼-->
            <!-- 根據什麼方法進行進一步查詢   IUserDao介面中的findById的方法  該方法需要一個id傳入uid(uid相當於是兩張表有聯絡的鍵)-->
            <!-- select屬性:傳送哪一條sql語句-->
            <!-- column屬性:用哪個列的值作為條件去查詢關聯的物件,我們要傳遞給 select 對映的引數-->
            <association property="user" javaType="com.zy.domain.User" select="com.zy.Dao.IUserDao.findById" column="uid"></association>
        </resultMap>

        <select id="findAccountUserList" resultMap="accountUserListMap">
            <!-- 為什麼關聯查詢,只寫個就可以了??不需要子查詢??-->
            <!-- 應為在上面的對映關係中就可以進行進一步通過uid對user表進行查詢-->
            select * from account
       </select>
</mapper>
​					指向的IUserDao介面的findById方法已經寫好

​			第三步:在主配置檔案中開啟延遲配置(詳細去看Mybatis官方文件)
<!-- 配置引數 -->
<settings>
    <!--開啟延遲載入的開關 ,當開啟時,所有關聯物件都會延遲載入-->
    <setting name="lazyLoadingEnabled" value="true"/>
    <!-- 開啟時,任一方法的呼叫都會載入該物件的所有延遲載入屬性。 否則,每個延遲載入屬性會按需載入-->
    <setting name="aggressiveLazyLoading" value="false"/>
</settings>
  帶延遲的和不帶延遲的分別呼叫測試方法發現:

​			不帶延遲的立馬查詢    帶延遲沒有立刻查詢

在這裡插入圖片描述

7、使用 Collection 標籤 實現延遲載入

相關文章