Loading

MyBatis笔记(五)

1. 多对一

什么是多对一呢?

  • 多个学生对应一个老师

1.1 数据库设计

CREATE TABLE `teacher` (
    `id` INT(10) NOT NULL,
    `name` VARCHAR(30) DEFAULT NULL,
    PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

INSERT INTO teacher(`id`, `name`) VALUES (1, '张三');

CREATE TABLE `student` (
    `id` INT(10) NOT NULL,
    `name` VARCHAR(30) DEFAULT NULL,
    `tid` INT(10) DEFAULT NULL,
    PRIMARY KEY (`id`),
    KEY `fktid` (`tid`),
    CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;


INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('1', '小明', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('2', '小红', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('3', '小张', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('4', '小李', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('5', '小王', '1');

image-20210412093855997

1.2 搭建测试环境

  1. 编写实体类POJO

    public class Teacher {
        private int id;
        private String name;
        
        // 无参构造
        // 有参构造
        // get、set方法
        // toString方法
    }
    
    public class Student {
        private int id;
        private String name;
        //多个学生可以是同一个老师,即多对一
        private Teacher teacher;
        
        // 无参构造
        // 有参构造
        // get、set方法
        // toString方法
    }
    
  2. 编写实体类对应的Mapper接口

    public interface StudentMapper {
    }
    
    public interface TeacherMapper {
    }
    
  3. 编写接口对应的mapper.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="top.linzeliang.mapper.StudentMapper">
     
    </mapper>
    
    <?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="top.linzeliang.mapper.TeacherMapper">
     
    </mapper>
    

1.3 按查询嵌套处理

  1. 给StudentMapper增加方法

    //获取所有学生及对应老师的信息
    public List<Student> getStudents();
    
  2. 编写对应的Mapper文件

    <!--    需求:获取所有学生及对应老师的信息
            思路:
                1. 获取所有学生的信息
                2. 根据获取的学生信息的老师ID->获取该老师的信息
                3. 思考问题,这样学生的结果集中应该包含老师,该如何处理呢,数据库中我们一般使用关联查询?
                    1. 做一个结果集映射:StudentTeacher
                    2. StudentTeacher结果集的类型为 Student
                    3. 学生中老师的属性为teacher,对应数据库中为tid。
                       多个 [1,...)学生关联一个老师=> 一对一,一对多
                    4. 查看官网找到:association – 一个复杂类型的关联;使用它来处理关联查询
    -->
    <select id="getStudents" resultMap="StudentMap">
        select *
        from student;
    </select>
    <resultMap id="StudentMap" type="student">
        <association property="teacher" column="tid" javaType="teacher" select="getTeacher"/>
    </resultMap>
    
    
    
    <!--
            这里传递过来的id,只有一个属性的时候,下面可以写任何值
            association中column多参数配置:
                column="{key=value,key=value}"
                其实就是键值对的形式,key是传给下个sql的取值名称,value是片段一中sql查询的字段名。
    -->
    <select id="getTeacher" resultType="Teacher">
        select *
        from teacher
        where id = #{tid};
    </select>
    
  3. 进行测试

1.4 按结果嵌套处理

个人认为这种容易理解一些

  1. 接口方法编写

    //获取所有学生及对应老师的信息
    public List<Student> getStudents(); 
    
  2. 编写对应的mapper配置文件

    <select id="getStudents" resultMap="StudentMap">
        select t1.id id, t1.name sname, t2.id tid, t2.name tname
        from student t1,
        teacher t2
        where t1.tid = t2.id;
    </select>
    <resultMap id="StudentMap" type="student">
        <id property="id" column="id"/>
        <result property="name" column="sname"/>
        <association property="teacher" javaType="Teacher">
            <id property="id" column="tid"/>
            <result property="name" column="tname"/>
        </association>
    </resultMap>
    
  3. 进行测试

2. 一对多

  • 一个老师对应多个学生

2.1 搭建测试环境

  • 实体类的编写

    public class Student {
        private int id;
        private String name;
        private int tid;
        
        // 无参构造
        // 有参构造
        // get、set方法
        // toString方法
    }
    
    public class Teacher {
        private int id;
        private String name;
        //一个老师多个学生
        private List<Student> students;
        
        // 无参构造
        // 有参构造
        // get、set方法
        // toString方法
    }
    

2.2 按查询嵌套处理

  1. TeacherMapper接口编写方法

    //获取指定老师,及老师下的所有学生
    public Teacher getTeacher(int id);
    
  2. 编写接口对应的Mapper配置文件(多了ofType的这个属性)

    <select id="getTeacher" resultMap="TeacherMap">
        select *
        from teacher
        where id = #{id};
    </select>
    <resultMap id="TeacherMap" type="Teacher">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <!-- column是一对多的外键 , 写的是一的主键的列名 -->
        <collection property="students" column="id" javaType="ArrayList" ofType="Student" select="getStudent"/>
    </resultMap>
    
    <select id="getStudent" resultType="Student">
        select *
        from student
        where tid = #{id}
    </select>
    
  3. 进行测试

2.3 按结果嵌套处理

  1. TeacherMapper编写方法

    //获取指定老师,及老师下的所有学生
    public Teacher getTeacher(int id);
    
  2. 编写接口对应的Mapper配置文件

    <select id="getTeacher" resultMap="TeacherMap">
        select t1.id tid, t1.name tname, t2.id sid, t2.name sname
        from teacher t1,
        student t2
        where t1.id = t2.tid
        and t1.id = #{id};
    </select>
    <resultMap id="TeacherMap" type="Teacher">
        <id property="id" column="tid"/>
        <result property="name" column="tname"/>
        <collection property="students" ofType="Student">
            <id property="id" column="sid"/>
            <result property="name" column="sname"/>
            <result property="tid" column="tid"/>
        </collection>
    </resultMap>
    
  3. 进行测试

3. ResultMap总结

  • 如果属性是JavaBean对象,则使用关联(association)
  • 如果属性是集合,则使用集合(collection)
  • 则association是用于一对一和多对一;collecion适用于一对多的关系
  • javaType和ofType都是用于指定对象类型的
    • javaType是用来指定pojo中属性的类型
    • ofType指的是映射到list集合属性中的pojo的类型
posted @ 2021-04-12 16:25  linzeliang  阅读(65)  评论(0)    收藏  举报