场景
有一个学生类和一个部门类,一个学生属于一个部门,一个部门拥有多个学生。
在前面我们学生类的基础上给它加一个部门的属性
在部分的属性里,我们需要给它加一个学生的集合
也就是说,学生和部门是一对一的关系,部门和学生是一对多的关系
学生类
private Integer id;
private String name;
private String passward;
private Dept dept;
}
部门类
public class Dept {
private Integer id;
private String name;
private List<Student> stus;
}
一、ResultMap
在学习关联查询之前我们需要了解一些基础的知识
ResultMap 是我们自定义一个封装规则,看一下我们前面两个类
resultMap 有两个参数,分别是id,type
id | 唯一标识 |
---|---|
type | 自定义封装的javaBean |
- resultMap 和resultType 的区别
ResultMap 和 ReasultType 都表示查询结果集和java 对象之间的一种关系。处理查询结果集,映射到 java 对象
ResultMap 是查询结果集映射到java 对象,属性名称映射关系。使用ResultMap 可以将查询结果集中的列一一映射到Bean 对象的各个属性。
ResultType 是一种查询结果集-Bean 对象,数据类型映射关系,使用ResultType 关系,即可使Bean 对象接收查询结果集.。。该方法是通过查询结果集中每条记录(属性)的数据类型和Bean对象的数据类型作映射,若两者都相同,则表示匹配成功,Bean可以接收到查询。
二、Association 查询
association 查询也就是一对一查询
场景:通过学生id 查询这个学生的信息
问题:学生的javaBean 类里现在有了一个Dept 的属性,我们怎样得到这个属性
分析:联合查询
① 先查询到学生的信息,拿到部门id
② 通过部门id 查询到部门信息
学生对应的javaBean 里面是一个Dept 对象,但是数据表里是一个int 型的部门id,数据类型上不对应,所以不能用resultType,我们需要自定义一个封装规则。
<resultMap id="MyStudent" type="com.tulun.bean.Student">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="pssward" property="passward"/>
<association property="dept" columnPrefix="d_" javaType="com.tulun.bean.Dept">
<result column="id" property="id"/>
<result column="name" property="name"/>
</association>
</resultMap>
resultMap 的每一个子元素result 都对应了javaBean 中一个属性 和数据表中某一列的对应关系。
association :指定一个联合的javaBean对象
参数 | 作用 |
---|---|
property | 表示的是映射到对应bean类中的属性值 |
javaType | 表示的是映射到bean属性的类型,需填写该路径的全路径名 |
columnPrefix | 表示数据库字段的前缀 |
association 是resultMap 下的标签
一对一映射返回结果可以用resultMap 也可以用resultType
<select id="getStuByid" parameterType="int" resultMap="MyStudent">
select s.id,s.name,s.pssward,d.id d_id,d.name d_name
from student s,dept d
where s.d_id = d.id and s.id = #{id}
</select>
可以看到这儿是获得了一个Student 对象,以及它的属性Dept
三、Collection 查询
一对多映射
场景:通过一个部门id 得到这个部门所有信息,包括属于这个部门的学生的集合
分析:
① 通过部门id 查询到部门的信息
② 遍历student 表,判断student 的部门id 与 我们所给的是否相同
<resultMap id="MyDept" type="com.tulun.bean.Dept">
<id column="id" property="id"/>
<result column="name" property="name"/>
<collection property="stus" columnPrefix="s_" ofType="com.tulun.bean.Student">
<result column="id" property="id"/>
<result column="name" property="name"/>
<result column="pssward" property="passward"/>
</collection>
</resultMap>
collection:一对多的映射
collection 是resultMap 下的标签
collection 返回的结果只能是resultMap
参数 | 作用 |
---|---|
property | 表示的是映射到对应bean类中的属性值 |
ofType | 表示对应的bean类中的属性的类型,要使用该类型的全限定名 |
columnPrefix | 表示数据库字段的前缀 |
<select id="getDeptByid" parameterType="int" resultMap="MyDept">
select d.id,d.name,s.id s_id,s.name s_name,s.pssward s_pssward
from student s,dept d
where s.d_id = d.id and d.id = #{id};
</select>
四、分步查询
使用association 进行分布查询步骤
- 先按照学生id查询学生信息
- 再根据学生表中的did 去查询部门的信息
- 部门设置到学生当中
<resultMap id="MystudentStep" type="com.tulun.bean.Student">
<id column="id" property="id"></id>
<result column="name" property="name"></result>
<result column="passward" property="passward"></result>
<!--
association:定义关联对象的封装规则
select:表明当前属性是调用select 指定的方法查出的结果
column:指定将哪一列的值传给这个方法
流程:使用select 指定的方法(传入column 指定的这列参数的值)查出对象,
并封装给property 指定的属性
-->
<association property="dept"
select="com.tulun.dao.DeptMapper.getDeptById"
column="d_id">
</association>
</resultMap>
</resultMap>
<select id="getStuByIdStep" resultMap="MystudentStep">
select * from student where id = #{id}
</select>
discriminator
mybatis 可以使用discriminator判断某列的值,然后根据某列的值改变封装行为。
下面这个例子就是根据id 的值的不同,采用不同的封装规则
<resultMap id="distu" type="com.tulun.bean.Student">
<id column="id" property="id"></id>
<result column="name" property="name"></result>
<result column="passward" property="passward"></result>
<!--
discriminator
column:指定判定的列名
javaType:列值对应的java 类型
-->
<discriminator javaType="Integer" column="id">
<case value="1" resultType="com.tulun.bean.Student">
<association property="dept"
select="com.tulun.dao.DeptMapper.getDeptById"
column="d_id">
</association>
</case>
<case value="2" resultType="com.tulun.bean.Student">
<id column="id" property="id"></id>
<result column="name" property="name"></result>
<result column="name" property="passward"></result>
</case>
</discriminator>
</resultMap>