结合实际生活来看联表,拿一个习以为常的例子来说,学生和老师:
多个学生对应一个老师 -- 多对一 (当然是在一个课堂上,嘻嘻)
一个老师对应多个学生 -- 一对多 (同上)
在实际操作时,我们需要看到的结果往往不是一个常见的类型(int,String,或者实体类),而往往
是下面这个样子:
也就是我们看到的显示具体的对应关系,这时候常见的类型要实现这样的效果是非常困难的(当然大佬
除外),MyBatis 的创建者也考虑到了这个问题,所以 resultMap 应运而生。
直译过来就是结果映射,所谓映射简单来说就是一个地方映射到另一个地方,所以结果映射就是将原先
的结果应该到另一个地方进行处理,相当于去调用另一个函数。
<resultMap id="" type="" autoMapping="" >resultMap>
1、id:
当前命名空间中的一个唯一标识,用于标识一个结果映射。即 resultMap 的名字(需唯一)
2、type:
类的完全限定名, 或者一个类型别名. 即 返回值类型(往往是实体类,视情况而定)。
3、autoMapping:
如果设置这个属性,MyBatis 将会为本结果映射开启或者关闭自动映射。
这个属性会覆盖全局的属性 autoMappingBehavior。默认值:未设置(unset)。
这个属性并不多用,默认值就可以。
<select id="selectUsers" resultMap="userResultMap">
select user_id, user_name, hashed_password
from some_table
where id = #{id}
select>
映射到下面的标签中:
各个子属性中的属性:
properity: 呈现给用户的新列名(相当于起别名)
column : 数据库中表的列名
<resultMap id="userResultMap" type="User">
<id property="id" column="user_id" />
<result property="username" column="user_name"/>
<result property="password" column="hashed_password"/>
resultMap>
1、id:
对应一张表中的id属性,也是唯一的。
2、result:
对应表中的其他属性(sex,name,address,and so on)
3、association:
需要连接的表,例如 多个学生对应一个老师(在代码中会有深刻的体现)。
这个属性有它自己的子属性 -- 与 resultMap 的子属性类似(id,name,and so on)
4、collection:
复杂类型的集合,在处理一对多的问题时比较常用,拿学生老师的例子来说,一个老师对应多个
学生,所以说 实体类 Teacher 中有一个属性是 List<Student> 的,这时候就需要用该属性
啦。(具体实现会在代码中有深刻展现,请继续往下看)
关于 resutlMap 的详细使用及相关的更多属性,在MaBatis 相关文档中有详细的介绍,有所疑问的
小伙伴可以访问官网进行深刻的学习。
Mybatis中文文档
MyBatis英文文档
teacher table:
student table:
1、新增两张表,所以需要两个实体类:
Student.java
package rj.cool.bean;
public class Student {
private int id;
private String name;
private int tid;
// 多个学生对应一个老师
private Teacher teacher;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getTid() {
return tid;
}
public void setTid(int tid) {
this.tid = tid;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", tid=" + tid +
'}';
}
}
Teacher.java
package rj.cool.bean;
import java.util.List;
public class Teacher {
private int id;
private String name;
// 一对多的关系
private List<Student> students;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
@Override
public String toString() {
return "Teacher{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
2、需要有 映射文件 进行查询:
按照我们之前说的面向接口开发,有所疑问的小伙伴可以到我创建的 MyBatis 专栏进行查阅。
所以我们先创建接口,然后再创建映射文件。
StudentMapper.java – Student映射文件对应的接口:
package rj.cool.dao;
import rj.cool.bean.Student;
import java.util.List;
public interface StudentMapper {
public void addStudent();
public void delStudent();
public void updateStudent();
public List selectStudent();
public List<Student> findAllStudent();
}
StudentMapper.xml
<mapper namespace="rj.cool.dao.StudentMapper">
<select id="selectStudent" resultMap="StudentTeacher">
SELECT s.id sid ,s.name sname ,t.id tid,t.name tname FROM student s,teacher t WHERE s.tid = t.id
select>
<resultMap id="StudentTeacher" type="rj.cool.bean.Student">
<id column="sid" property="id"/>
<result column="sname" property="name"/>
<association property="teacher" javaType="rj.cool.bean.Teacher">
<id column="tid" property="id"/>
<result column="tname" property="name"/>
association>
resultMap>
mapper>
TeacherMapper.java – Teacher 映射文件对应的接口:
package rj.cool.dao;
import rj.cool.bean.Student;
import rj.cool.bean.Teacher;
import java.util.List;
public interface TeacherMapper {
public void addTeacher();
public void delTeacher();
public void updateTeacher();
public Teacher selectTeacher(int id);
public List<Teacher> findAllTeacher();
public Teacher selectMyStudents(int id);
}
TeacherMapper.xml:
<mapper namespace="rj.cool.dao.TeacherMapper">
<select id="selectMyStudents" resultMap="TeacherStudent" parameterType="int">
SELECT s.id sid ,s.name sname ,t.id tid,t.name tname FROM student s,teacher t WHERE s.tid = t.id and t.id = #{id}
select>
<resultMap id="TeacherStudent" type="rj.cool.bean.Teacher">
<id column="tid" property="id"/>
<result column="tname" property="name"/>
<collection property="students" ofType="rj.cool.bean.Student">
<id column="sid" property="id"/>
<result column="sname" property="name"/>
collection>
resultMap>
<select id="selectTeacher" parameterType="int" resultType="rj.cool.bean.Teacher">
select * from teacher where id=#{id}
select>
mapper>
3、告诉 Mybatis 配置文件去那里找对应的映射文件:
// 在 MyBatis-config.xml 中增加如下内容:
<mappers>
<mapper resource="rj/cool/dao/UserMapper.xml"/>
<mapper resource="rj/cool/dao/StudentMapper.xml"/>
<mapper resource="rj/cool/dao/TeacherMapper.xml"/>
mappers>
4、测试:
多对一:
@Test
public void selectStudent() throws IOException {
SqlSession session = MyBatisDButils.getSession();
// List list = session.getMapper(StudentMapper.class).selectStudent();
List<Student> list = session.selectList("rj.cool.dao.StudentMapper.selectStudent");
for(Student s:list) {
System.out.println("sid :" + s.getId() + " sname" + s.getName() + " tid" + s.getTeacher().getId() + " tname" + s.getTeacher().getName() );
}
session.close();
}
@Test
public void selectMyStudents() throws IOException {
SqlSession session = MyBatisDButils.getSession();
Teacher teacher = session.selectOne("rj.cool.dao.TeacherMapper.selectMyStudents",1);;
System.out.println("tid:" + teacher.getId() + " tname :" + teacher.getName());
// List students = session.getMapper(TeacherMapper.class).selectMyStudents(1);
List<Student> students = teacher.getStudents();
// List students = session.selectList("rj.cool.dao.TeacherMapper.selectMyStudents",1);
for (Student student : students) {
System.out.println("sid :" + student.getId() + " sname" + student.getName());
}
}
到此,用 resultMap 实现联表的介绍就结束了,在本文中,可能有不足的地方或者疏漏的地方,希望各
位看官发现有误的地方能够悉数指出,在下万分感激。
如需要详细源码的小伙伴,欢迎随时私聊我。