單向一對一映射
場景:查詢寵物信息,關聯查詢類別信息
通過外鍵去查詢另一個表
數據庫:
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>
- property:指定屬性
- select :指定一個查詢語句該查詢語句最終能夠返回使用property指定的對象
- 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
現在就會發現這次沒有查找類型了