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

现在就会发现这次没有查找类型了

猜你喜欢

转载自blog.csdn.net/weixin_42496678/article/details/82874258