8.1 一对一(多对一)查询
查询学生对象,学生对象中含有班级信息。
package com.itany.ms.dao;
import com.itany.ms.entity.Stu;
import java.util.List;
public interface StuMapper {
// 查询所有学生(含该学生所属班级信息)
List<Stu> selectAll();
}
1.方式1
<?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.itany.ms.dao.StuMapper">
<!--
resultType 默认对象关系映射
c.id 是 Stu中 clazz属性的id的属性值, 所以要取个别名 叫 "clazz.id"
-->
<select id="selectAll" resultType="com.itany.ms.entity.Stu" >
select
s.id,s.name,s.sex,s.class_id classId,
c.id "clazz.id",c.name "clazz.name",c.loc "clazz.loc"
from t_stu s
inner join t_class c on s.class_id = c.id
</select>
</mapper>
2.方式2(常用)
java代码不变,仅仅是映射方式(xml代码)不同。
<!--
一对一(多对一)配置对应关系使用 association 标签
property 表示 在一方(Stu)中的属性名
javaType 表示 该属性的Java的类型(没有配置别名时,需要写类的全名)
-->
<resultMap id="stuMap1" type="com.itany.ms.entity.Stu">
<id column="id" property="id" ></id>
<result column="name" property="name" ></result>
<result column="sex" property="sex" ></result>
<result column="class_id" property="classId" ></result>
<association property="clazz" javaType="com.itany.ms.entity.Clazz">
<!-- 此处的映射写法和 外侧的 相同 -->
<id column="cid" property="id" ></id>
<result column="cname" property="name" ></result>
<result column="loc" property="loc" ></result>
</association>
</resultMap>
<select id="selectAll" resultMap="stuMap1" >
select
s.id,s.name,s.sex,s.class_id,
c.id cid,c.name cname,c.loc loc
from t_stu s
inner join t_class c on s.class_id = c.id
</select>
3.方式3
<!--
association 标签的 resultMap 属性表示 引用其他的 resultMap标签的配置来封装对象
如果是 其他mapper文件中的resultMap标签,则其值是 该mapper文件的namespace的值 + "." + resultMap标签id的值
如果是 当前mapper文件中的resultMap标签,则其值是 resultMap标签id的值(namespace的值可以省略)
-->
<resultMap id="stuMap2" type="com.itany.ms.entity.Stu">
<id column="id" property="id" ></id>
<result column="name" property="name" ></result>
<result column="sex" property="sex" ></result>
<result column="class_id" property="classId" ></result>
<association property="clazz" javaType="com.itany.ms.entity.Clazz" resultMap="com.itany.ms.dao.ClazzMapper.classMap1" ></association>
</resultMap>
<select id="selectAll" resultMap="stuMap2" >
select
s.id,s.name,s.sex,s.class_id,
c.id cid,c.name cname,c.loc loc
from t_stu s
inner join t_class c on s.class_id = c.id
</select>
ClazzMapper.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.itany.ms.dao.ClazzMapper">
<resultMap id="classMap1" type="com.itany.ms.entity.Clazz">
<id column="cid" property="id" ></id>
<result column="cname" property="name" ></result>
<result column="loc" property="loc" ></result>
</resultMap>
</mapper>
4.方式4
使用子查询。
<?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.itany.ms.dao.ClazzMapper">
<resultMap id="classMap1" type="com.itany.ms.entity.Clazz">
<id column="cid" property="id" ></id>
<result column="cname" property="name" ></result>
<result column="loc" property="loc" ></result>
</resultMap>
<select id="selectById" resultMap="classMap1" >
select
id cid, name cname, loc
from t_class
where id = #{id}
</select>
</mapper>
<!-- association 标签
select 属性 表示 调用 其他的 方法
如果调用的方法在 其他mapper文件中, 使用 该mapper文件的namespace的值 + "." + 对应方法标签id的值
column 属性 表示 调用 上述的 方法时,把该列的 值作为参数传入 上述的方法。
上述的 此种 映射操作,会出现 N + 1 的查询效率问题,所以一般不建议使用
-->
<resultMap id="stuMap3" type="com.itany.ms.entity.Stu">
<id column="id" property="id" ></id>
<result column="name" property="name" ></result>
<result column="sex" property="sex" ></result>
<result column="class_id" property="classId" ></result>
<association property="clazz" javaType="com.itany.ms.entity.Clazz"
select="com.itany.ms.dao.ClazzMapper.selectById"
column="class_id"
></association>
</resultMap>
<select id="selectAll" resultMap="stuMap3" >
select
id, name, sex, class_id
from t_stu
</select>
8.2 一对多查询
查询班级以及其包含的学生
有三种方式(和 一对一的方式2 到 方式4 类似),只要将
association
标签名 改为collection
javaType
属性名 改为ofType
(表示集合的泛型)
<!-- 以方式2为例(常用) -->
<resultMap id="classMap2" type="com.itany.ms.entity.Clazz">
<id column="cid" property="id" ></id>
<result column="cname" property="name" ></result>
<result column="loc" property="loc" ></result>
<collection property="stus" ofType="com.itany.ms.entity.Stu" >
<!-- 此处的映射写法和 外侧的 相同 -->
<id column="id" property="id" ></id>
<result column="name" property="name" ></result>
<result column="sex" property="sex" ></result>
<result column="class_id" property="classId" ></result>
</collection>
</resultMap>
<select id="seletAll" resultMap="classMap2" >
select
c.id cid, c.name cname, c.loc,
s.id, s.name, s.sex, s.class_id
from t_class c
left join t_stu s on c.id = s.class_id
</select>