目录
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。
-
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>
-
分步查询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>
-
二、多对一
像上面的需求,查询所有的学生信息的时候,把学生对应的学院信息也查询出来。
学生:学院 ,就是 n : 1 的关系。
(1) Association标签:是帮助创建一个对象。
(2) javaType属性:指对象类型
(3) 最后查询到的结果结构是:返回学生集合List,并且每一条学生信息中都包含对应的学院信息。
-
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>
-
分步查询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" 进行延迟加载