Mybatis之高級映射以及延遲加載

單向一對一映射

場景:查詢寵物信息,關聯查詢類別信息
通過外鍵去查詢另一個表
數據庫:
pets表: id,name,birth_date,type_id
types表:id,name
實體類:
Pets

private int id;
private String name;
private Date birthDate;
private int typeId;

Types

	private int id;
	private String name;

這時我們想同時查詢兩個表的內容,應該怎麼辦,在不修改實體類字段的基礎上?
這時我們就可以寫一個擴展類繼承Pets類,包含額外的字段
PetsExt:

private int tid;  //爲了區分起個別名 
private String tname;

PetsMapper.java

public interface PetsMapper { 	
public List<PetsExt> findAllPetsAndTypes();
 }

resultMap

PetsMapper.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.tf.mapper.PetsMapper">
   <resultMap id="myRusultMap" type="com.tf.domain.PetsExt">
   <id property="id" column="id"/>
   <result property="name" column="name"></result>
   <result property="birthDate" column="birth_date"></result>
   <result property="tid" column="tid"></result><!--起的別名  -->
   <result property="tname" column="tname"></result>
  <result property="typeId" column="type_id"></result>
   </resultMap>
    <select id="findAllPetsAndTypes" resultMap="myRusultMap">
      select p.*,t.id tid,t.name tname
      from pets p,types t
      where p.type_id=t.id
    </select>
</mapper>

resultType

使用resultType有兩種解決方案:
①:實體類的字段和數據庫一致
②:起別名 和實體類的字段一致
下面說一下第二種:

<selectid="findPetsAndTypes"resultType="com.tf.domain.PetsExt">
		select p.* ,t.id tid,t.name tname
			from pets p,types t
			where p.type_id = t.id
	</select>

使用resultType來進行一對一結果映射,查詢出的列的個數和映射的屬性的個數要一致。而且映射的屬性要存在一個大的對象中(擴展),它是一種平鋪式的映射,即數據庫查詢出多少條記錄,則映射成多少個對象。

對象映射:association

查詢寵物信息,關聯查詢類別信息。
一個寵物對應一個類別

<resultMap type="com.tf.domain.Pets" id="myMap">
	<id property="id" column="id"/>
	<result property="name" column="name"></result>
	<result property="birthDate" column="birth_date"></result>
	<result property="typeId" column="type_id"></result>
		<association property="types" javaType="com.tf.domain.Types">
			<id property="id" column="tid"/>
			<result property="name" column="tname"/>
		</association>
	</resultMap>

    <select id="findAllPetsAndTypes1" resultMap="myMap">
      select p.id,p.name,p.birth_date birthDate, p.type_id typeId,t.id tid,t.name tname
      from pets p,types t
      where p.type_id=t.id
    </select>

一對多映射

查詢類別信息,關聯查詢寵物信息
一個類型—>多隻寵物

<resultMap type="com.tf.domain.Types" id="typesMap">
     <id property="id" column="id"/>
     <result property="name" column="name"></result>
     <!-- 配置集合 -->
     <collection property="pets" ofType="com.tf.domain.Pets">
          <id property="id"  column="pid"/>
          <result property="name" column="pname"></result>
           <result property="birthDate" column="birthDate"></result>
     </collection>
</resultMap>
<select id="findOneTypes" resultMap="typesMap"> 
select t.*,p.id pid,p.name pname,p.birth_date birthDate
from types t
left join pets p
on t.id=p.type_id
</select>

ofType:封裝的集合的類型

延遲加載

延遲加載又叫懶加載,也叫按需加載。也就是說先加載主信息,在需要的時候,再去加載從信息。

在mybatis中,resultMap標籤的

association標籤(配置單個對象)
collection標籤(配置集合)具有延遲加載的功能。
比如:

<resultMap id="petsMap" type="com.tf.domain.Pets">
  <id property="id" column="id"/>
  <result property="name" column="name"></result>
 <result property="birthDate" column="birth_date"></result>
  <result property="typeId" column="type_id"></result>
<association property="types"
  select="com.tf.mapper.TypesMapper.findTypesById"
  column="type_id">
</association>
</resultMap>
<select id="findAllPets" resultMap="petsMap">
 select * from pets
</select>
  1. property:指定屬性
  2. select :指定一個查詢語句該查詢語句最終能夠返回使用property指定的對象
  3. column: 查詢出的寵物信息的當前列作爲參數傳遞給com.tf.mapper.TypesMapper.findTypesById方法
    而我們的測試類只想查找寵物的名字,
PetsMapper petsMapper = sqlSession.getMapper(PetsMapper.class);
	   List<Pets> list = petsMapper.findAllPets();
	   for (Pets pets : list) {
		System.out.println(pets.getName());
	}

但是我們來看打印的sql語句,不難發現把類型也查找了出來,我們把這種叫做立即加載

==>  Preparing: select * from pets 
==> Parameters: 
<==    Columns: id, name, birth_date, type_id, owner_id
<==        Row: 100, 花花, 2018-09-07, 3001, 10
====>  Preparing: select * from types where id=? 
====> Parameters: 3001(Integer)
<====    Columns: id, name
<====        Row: 3001, 貓科
<====      Total: 1
<==        Row: 105, 紅花崗, 2012-03-04, 3002, 10

那麼如何設置延遲加載呢?

設置延遲加載

mybatisConfig.xml中配置settings標籤

<settings>
<!--打印查詢語句 -->
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!-- 配置懶加載 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 積極懶加載 (按需加載)-->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>

這時我們再來看一下打印的sql語句:

==> Preparing: select * from pets

==> Parameters:

<== Columns: id, name, birth_date, type_id, owner_id

現在就會發現這次沒有查找類型了

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