一对一级联关系在现实生活中是十分常见的,例如一个大学生只有一个学号,一个学号只属于一个学生。同样,人与身份证也是一对一的级联关系。
在 MyBatis 中,通过 <resultMap> 元素的子元素 <association> 处理一对一级联关系。
以下使用学生与学生卡编写示例,一个学生有一张学生卡。
java 持久对象:
public class Student {
int id;
String name;
private StudentCard studentCard;
}
public class StudentCard {
private int id;
private int number;
}
查询
一对一关联查询可采用以下两种方式:
- 单步查询,通过关联查询实现
- 分步查询,通过两次或多次查询,为一对一关系的实体 Bean 赋值
单步查询
<!-- StudentMapper.xml -->
<mapper namespace="cn.dt.mybatis.mapper.StudentMapper">
<resultMap type="Student" id="cardAndStu11">
<id property="id" column="id"/>
<result property="name" column="name"/>
<!-- 一对一级联查询 -->
<association property="studentCard" javaType="StudentCard">
<id property="id" column="id"/>
<result property="number" column="number"/>
</association>
</resultMap>
<select id="getStudentById" parameterType="int" resultMap="cardAndStu11">
select s.*, sc.*
from student s,
student_card sc
where s.card_id = sc.id
and s.id = #{id}
</select>
...
</mapper>
测试代码如下:
Student studentById = mapper.getStudentById(id);
log.info("find {} by id={}", studentById, id);
return studentById;
输出结果:
17:40:13.257 [main] DEBUG cn.dt.mybatis.mapper.StudentMapper.getStudentById - ==> Preparing: select s., sc. from student s, student_card sc where s.card_id = sc.id and s.id = ?
17:40:13.326 [main] DEBUG cn.dt.mybatis.mapper.StudentMapper.getStudentById - > Parameters: 7(Integer)
17:40:13.382 [main] DEBUG cn.dt.mybatis.mapper.StudentMapper.getStudentById - < Total: 1
17:40:13.383 [main] INFO cn.dt.mybatis.TestStudent - find Student(id=7, name=dt, studentCard=StudentCard(id=7, number=1)) by id=7
分步查询
<!-- StudentCardMapper.xml -->
<mapper namespace="cn.dt.mybatis.mapper.StudentCardMapper">
<select id="selectStudentCardById" resultType="StudentCard">
select *
from student_card
where id = #{id}
</select>
</mapper>
<!-- StudentMapper.xml -->
<mapper namespace="cn.dt.mybatis.mapper.StudentMapper">
<resultMap type="Student" id="cardAndStu11">
<id property="id" column="id"/>
<result property="name" column="name"/>
<!-- 一对一级联查询 -->
<association property="studentCard"
javaType="StudentCard"
column="card_id"
select="cn.dt.mybatis.mapper.StudentCardMapper.selectStudentCardById">
</association>
</resultMap>
<select id="getStudentById" parameterType="int" resultMap="cardAndStu11">
select s.*
from student s
where s.id = #{id}
</select>
...
</mapper>
测试代码如下:
Student studentById = mapper.getStudentById(id);
log.info("find {} by id={}", studentById, id);
return studentById;
输出结果:
18:00:42.892 [main] DEBUG cn.dt.mybatis.mapper.StudentMapper.getStudentById- ==> Preparing: select s.* from student s where s.id = ?
18:00:42.955 [main] DEBUG cn.dt.mybatis.mapper.StudentMapper.getStudentById - ==> Parameters: 7(Integer)
18:00:42.994 [main] DEBUG cn.dt.mybatis.mapper.StudentCardMapper.selectStudentCardById - ==> Preparing: select * from student_card where id = ?
18:00:42.995 [main] DEBUG cn.dt.mybatis.mapper.StudentCardMapper.selectStudentCardById - > Parameters: 1(Integer)
18:00:42.998 [main] DEBUG cn.dt.mybatis.mapper.StudentCardMapper.selectStudentCardById - < Total: 1
18:00:42.999 [main] DEBUG cn.dt.mybatis.mapper.StudentMapper.getStudentById - < Total: 1
18:00:42.999 [main] INFO cn.dt.mybatis.TestStudent - find Student(id=7, name=dt, studentCard=StudentCard(id=1, number=1)) by id=7
使用级联对象更新
映射文件如下:
<!-- StudentMapper.xml -->
<mapper namespace="cn.dt.mybatis.mapper.StudentMapper">
...
<insert id="insertStudent" parameterType="Student" keyProperty="id" useGeneratedKeys="true">
insert into student(name, card_id)
values (#{name}, #{studentCard.id})
</insert>
...
</mapper>
测试代码如下:
StudentCard studentCard = studentCardMapper.selectStudentCardById(1);
Student s = new Student();
s.setName("dt");
s.setStudentCard(studentCard);
mapper.insertStudent(s);
log.info("inserted {}", s);
输入结果:
18:09:42.957 [main] DEBUG cn.dt.mybatis.mapper.StudentMapper.insertStudent - ==> Preparing: insert into student(name, card_id) values (?, ?)
18:09:42.958 [main] DEBUG cn.dt.mybatis.mapper.StudentMapper.insertStudent - > Parameters: dt(String), 1(Integer)
18:09:42.962 [main] DEBUG cn.dt.mybatis.mapper.StudentMapper.insertStudent - < Updates: 1
18:09:42.966 [main] DEBUG cn.dt.mybatis.mapper.StudentMapper.getStudentById - ==> Preparing: select s.* from student s where s.id = ?
18:09:42.966 [main] DEBUG cn.dt.mybatis.mapper.StudentMapper.getStudentById - ==> Parameters: 9(Integer)
18:09:42.970 [main] DEBUG cn.dt.mybatis.mapper.StudentCardMapper.selectStudentCardById - ==> Preparing: select * from student_card where id = ?
18:09:42.971 [main] DEBUG cn.dt.mybatis.mapper.StudentCardMapper.selectStudentCardById - > Parameters: 1(Integer)
18:09:42.973 [main] DEBUG cn.dt.mybatis.mapper.StudentCardMapper.selectStudentCardById - < Total: 1
18:09:42.974 [main] DEBUG cn.dt.mybatis.mapper.StudentMapper.getStudentById - < Total: 1
18:09:42.974 [main] INFO cn.dt.mybatis.TestStudent - find Student(id=9, name=dt, studentCard=StudentCard(id=1, number=1)) by id=9
18:09:42.975 [main] INFO cn.dt.mybatis.TestStudent - inserted Student(id=9, name=dt, studentCard=StudentCard(id=1, number=1))