高级MyBatis -- resultMap实现联表(一对多,多对一)

前言:

结合实际生活来看联表,拿一个习以为常的例子来说,学生和老师:
多个学生对应一个老师 -- 多对一 (当然是在一个课堂上,嘻嘻)
一个老师对应多个学生 -- 一对多 (同上)
在实际操作时,我们需要看到的结果往往不是一个常见的类型(int,String,或者实体类),而往往
是下面这个样子:

在这里插入图片描述

也就是我们看到的显示具体的对应关系,这时候常见的类型要实现这样的效果是非常困难的(当然大佬
除外),MyBatis 的创建者也考虑到了这个问题,所以 resultMap 应运而生。

resultMap 的介绍及使用:

直译过来就是结果映射,所谓映射简单来说就是一个地方映射到另一个地方,所以结果映射就是将原先
的结果应该到另一个地方进行处理,相当于去调用另一个函数。

resultMap 的参数属性:

	<resultMap id="" type="" autoMapping="" ></resultMap>

1、id:

当前命名空间中的一个唯一标识,用于标识一个结果映射。即 resultMap 的名字(需唯一)

2、type:

类的完全限定名, 或者一个类型别名.返回值类型(往往是实体类,视情况而定)

3、autoMapping:

如果设置这个属性,MyBatis 将会为本结果映射开启或者关闭自动映射。
这个属性会覆盖全局的属性 autoMappingBehavior。默认值:未设置(unset)。
这个属性并不多用,默认值就可以。

resultMap 的属性:

	<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

<?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="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:

<?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="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>
    <!-- column 数据库中表中的字段    -->

    <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>
    <!-- 一张表对应一个映射文件 ,资源一般都是路径,所以用 '/',包名后面的类名时我们常常选择用'.'   -->
    <!-- 映射文件告诉 Mybatis 去哪里找相对应的映射文件-->
    <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<Student> 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<Student> students = session.getMapper(TeacherMapper.class).selectMyStudents(1);
        List<Student> students = teacher.getStudents();
//        List<Student> students = session.selectList("rj.cool.dao.TeacherMapper.selectMyStudents",1);
        for (Student student : students) {
            System.out.println("sid :" + student.getId() + " sname" + student.getName());
        }
    }

效果图:
在这里插入图片描述

后记:

到此,用 resultMap 实现联表的介绍就结束了,在本文中,可能有不足的地方或者疏漏的地方,希望各
位看官发现有误的地方能够悉数指出,在下万分感激。
如需要详细源码的小伙伴,欢迎随时私聊我。
原创文章 9 获赞 6 访问量 484

猜你喜欢

转载自blog.csdn.net/qq_43619271/article/details/106177298
今日推荐