mybatis的一对多、多对一关系

目录
1. 一对多
1.1 sql装配一对多关系
1.2 分步查询sql装配一对多关系
2. 多对一
2.1 sql装配多对一关系
2.2 分步查询sql装配多对一关系



使用mybatis操作关系型数据库的时候,往往会涉及到表数据的复杂关系。

基本知识:
     resultMap标签:定义结果映射,处理复杂关系。
     id标签:是主键映射。
     result标签:是非主键映射。
     column属性:是字段名。
     property属性:是属性名。


实例准备:数据库表 student表、college表
在这里插入图片描述
在这里插入图片描述

一、一对多
     像上面的需求,需要查询学院的同时,然后返回对应学院里面的学生信息。 学院 : 学生,就是 1:n的关系。

     注意:

     (1) collection标签:是处理一对多、多对多的关系。
     (2) ofType属性:指集合中的类型
     (3) 最后查询到的结果结构是:College对象,并且里面包含了所有对应的用户信息List。


  1. sql装配

就是一个接口查询返回装配好的信息。

(1) 需要对college实体类进行包装

public class College {
	private String collegeId;// 学院id
	private String collegeName;// 学院名称
	private List<Student> student; // 装配学院对应的学生。
	//....补全get、set方法
	}

(2) 编写接口类

public interface CollegeDao {
	College getCollegeAndStudents(String collegeId);// 更具学院的id进行查询
}

(3) 建立一对多关系的sql装配

<!-- 1对多  学院-学生  注意设置键名的时候要区分一下-->
    <resultMap type="Entity.College" id="collegeTostudents">// 相当于1(学院)
        <id column="collegeId" property="collegeId"/>
        <result column="collegeName" property="collegeName"/>
        
        <collection property="student" ofType="Entity.Student">// 相当于n(对应学生)
            <id column="studentId" property="studentId"/>
            <result column="studentName" property="studentName"/>
            <result column="pid" property="pid"/>
        </collection>
    </resultMap>
    
    <!--查询语句-->
    <select id="getCollegeAndStudents" parameterType="String" resultMap="collegeTostudents">
        
        select a.collegeId,a.collegeName,b.studentId,b.studentName,b.pid
        from college a left join student b on a.collegeId = b.pid
        where a.collegeId = #{collegeId}
    </select>

  1. 分步查询sql装配

就是从不同的接口中查询到信息,然后,在进行装配返回。

(1) 需要对college实体类进行包装

public class College {
	private String collegeId;// 学院id
	private String collegeName;// 学院名称
	private List<Student> student; // 装配学院对应的学生。
	//....补全get、set方法
	}

(2) 编写接口

public interface UserDao {// 根据pid查询的学生接口
	User getUser(String pId);
}

public interface CollegeDao {// 根据collegeId查询的学院接口
	College getCollegeAndStudents(String collegeId);
}

(3) 建立一对多关系的分步查询sql装配

<!--学生查询sql映射文件-->
<mapper namespace="Mapper.StudentDao">
    
    <select id="getStudent" parameterType="String" resultType="Entity.Student">
        select * from student where pId = #{pId}
    </select>
</mapper>


<!--学院查询sql映射文件-->
<mapper namespace="Mapper.CollegeDao">
   
    <resultMap type="Entity.College" id="collegeTostudents">// 相当于1(学院)
        <id column="collegeId" property="collegeId"/>
        <result column="collegeName" property="collegeName"/>
        
        <collection property="student" select="Mapper.StudentDao.getStudent" column="collegeId"/> // 相当于n (对应学生)
		// column 是查询学生的参数。如果是多个参数,可以用column="{collegeId=collegeId,>..}"

//并且可以实现延迟加载:collection 中里面有fetchType="lazy"
    </resultMap>
    
    <!--查询学院-->
    <select id="getCollegeAndStudents" parameterType="String" resultMap="collegeTostudents">
        
        select collegeId,collegeName
        from college
        where collegeId = #{collegeId}
    </select> 
</mapper>

返回顶部

  1. 二、多对一

     像上面的需求,查询所有的学生信息的时候,把学生对应的学院信息也查询出来。
学生:学院 ,就是 n : 1 的关系。

     注意:

     (1) Association标签:是帮助创建一个对象。
     (2) javaType属性:指对象类型
     (3) 最后查询到的结果结构是:返回学生集合List,并且每一条学生信息中都包含对应的学院信息。

  1. sql装配

(1) 需要对student实体类进行包装

public class Student {
	private String studentId;
	private String studentName;
	private String pid;
	private College college;// 学院
	// ...补全get、set方法
	}

(2) 编写接口

public interface StudentDao {
	List<Student> getStudent();
}

(3) 建立多对一关系的分步查询sql装配

<mapper namespace="Mapper.StudentDao">
    
    <resultMap type="Entity.Student" id="studentTocollege">
        
        <id column="studentId" property="studentId"/>
        <result column="studentName" property="studentName"/>
        <result column="pid" property="pid"/>
        //第一种方法
        <result column="collegeId" property="college.collegeId"/>
        <result column="collegeName" property="college.collegeName"/>
        
	// 第二种方法:或者使用association 进行对象的创建
	<!--  <association property="college" javaType="Entity.College">
            <result column="collegeId" property="collegeId"/>
        	<result column="collegeName" property="collegeName"/> 
        </association> -->
    </resultMap> 
    
    <select id="getStudent" resultMap="studentTocollege">
        
        select a.studentId,a.studentName,a.pid,b.collegeId,b.collegeName
        from student a left join college b on a.pId = b.collegeId     
    </select>
</mapper>
  1. 分步查询sql装配

(1) 需要对student实体类进行包装

public class Student {
	private String studentId;
	private String studentName;
	private String pid;
	private College college;// 学院
	// ...补全get、set方法
	}

(2) 编写接口

public interface StudentDao {// 学生查询接口
	List<Student> getStudent();
}

public interface CollegeDao {// 学院查询接口
	College getCollegeAndStudents(String collegeId);
}

(3) 建立多对一关系的分步查询sql装配

<!--学院查询-->
<mapper namespace="Mapper.CollegeDao">
    <select id="getCollegeAndStudents" parameterType="String" resultType="Entity.College">
        
        select collegeId,collegeName
        from college
        where collegeId = #{collegeId}
    </select> 
</mapper>

<!--学生查询-->
<mapper namespace="Mapper.StudentDao">
    
    <resultMap type="Entity.Student" id="studentTocollege">
        
        <id column="studentId" property="studentId"/>
        <result column="studentName" property="studentName"/>
        <result column="pid" property="pid"/>
        
        <association property="college" select="Mapper.CollegeDao.getCollegeAndStudents" column="pid"/>
    </resultMap> 
    
    <select id="getStudent" resultMap="studentTocollege">
        
        select a.studentId,a.studentName,a.pid,b.collegeId,b.collegeName
        from student a left join college b on a.pId = b.collegeId     
    </select>
</mapper>

返回顶部

注意:因为分步查询消耗比较多的资源,可以进行延迟加载设置。
在配置文件中配置全局、也可以在单个映射中设置单个延迟。

   <settings>
        <!-- 将下划线映射成驼峰式命名 -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <!-- 开启延迟加载 -->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!-- 是否检查所有数据 -->
        <setting name="aggressiveLazyLoading" value="false"/>
    </settings>

//也可以使用 fetchType="lazy" 进行延迟加载

返回顶部

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值