MyBatis学习系列(四)--多对一联表查询

MyBatis学习系列(四)--多对一联表查询

准备

  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');

表的内容如下:

student

id name tid
1 小明 1
2 小红 1
3 小张 1
4 小李 1
5 小王 1

teacher

id name
1 秦老师
  1. 实体类编写
import lombok.Data;

@Data
public class Teacher {

    private int id;
    private String name;
}
import lombok.Data;

@Data
public class Student {
    private int id;
    private String name;
    private Teacher teacher;

}
  1. DAO层Mapper接口
import java.util.List;

public interface StudentMapper {

    List<Student> getStudents();

    List<Student> getStudents2();
}

问题描述

找出学生对应的老师的名字

实现

SQL查询语句

SELECT s.id AS sid, s.name AS sname, t.name AS tname
FROM `student` AS s, `teacher`AS t
WHERE s.tid = t.id;

实体类Student的字段与表student的列不是一一对应的关系,所以MyBatis配置文件中的select标签中的resultType属性不符合要求,要用resultMap

<select id="getStudents2" resultMap="StudentTeacher2"><!--resultMap是配置文件中的另一个标签-->
    SELECT s.id AS sid, s.name AS sname, t.name AS tname
    FROM `student` AS s, `teacher`AS t
    WHERE s.tid = t.id;
</select>

<!--resultMap标签的type属性指定待映射的类,可以进一步精细化配置,主要依赖association子标签-->
<resultMap id="StudentTeacher2" type="com.kuang.pojo.Student">
    <result property="id" column="sid"></result>
    <result property="name" column="sname"></result>
    <association property="teacher" javaType="com.kuang.pojo.Teacher">
        <result property="name" column="tname"></result>
    </association>
</resultMap>

resultMap标签的type属性指定待映射的类,可以进一步精细化配置,主要依赖association子标签。result子标签的property属性对应实体类的字段或域,column对应数据库表中的列名。result子标签的局限性在于只能将实体类中的字段映射到表的列上,而表的列类型不能表示Java中复杂的实例对象(String,Date类型除外)。association标签可嵌套,可嵌套使得可根据表的列构建任意复杂的实例对象,因为实例对象的字段随着不断展开最终一定可以表示为原始类型或String或Date类型的集合。

扩展

上面的配置方法有SQL语句作为依托,容易想到。还有另一种配置方法,不那么常规:

<select id="getStudents" resultMap="StudentTeacher">
    SELECT * FROM `student`;
</select>
    
<resultMap id="StudentTeacher" type="com.kuang.pojo.Student">
    <result property="id" column="id"></result>
    <result property="name" column="name"></result>
    <association property="teacher" column="tid" javaType="com.kuang.pojo.Teacher" select="getTeacher">
    </association>
</resultMap>
    
<select id="getTeacher" resultType="com.kuang.pojo.Teacher">
    SELECT * FROM `teacher` WHERE id=#{tid};
</select>

这种方法的关键在于两个表联接点,即student的tid列与teacher的id列。

posted @ 2020-06-02 19:36  中知  阅读(145)  评论(0)    收藏  举报