MyBatis多对一SQL查询

1、多对一的概念

  • 多个学生,对应一个老师

  • 对于学生而言,多个学生关联一个老师 (关联)【多对一】

  • 对于老师而言,一个老师有多个学生(集合)【一对多】

    image-20210112143131703

2、搭建数据库

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

3、搭建项目环境

  1. 编写实体类

    学生类Student

    public class Student {
        private Integer id;
        private String name;
        //多个学生可以是同一个老师,即多对一
        private Teacher teacher;
        // 构造器
        // toString
        // getter and setter
    }
    

    老师类Teacher

    public class Teacher {
        private Integer id;
        private String name;
        // 构造器
        // toString
        // getter and setter
    }
    
  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="com.jh.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="com.jh.mapper.TeacherMapper">
    
    </mapper>
    
  4. 在核心配置文件中注册xml文件

    <mappers>
        <mapper class="com.jh.mapper.TeacherMapper"/>
        <mapper class="com.jh.mapper.StudentMapper"/>
    </mappers>	
    

4、按照查询嵌套处理

需求:获取所有学生及对应老师的信息

思路

  1. 查询所有的学生信息
  2. 根据学生信息中的老师tid,查询对应的老师信息
  3. 返回值中包含了teacher的消息resultType不可用,怎么解决?
    1. 使用结果集映射:resultMap
    2. resultMap的type是Student
    3. student中的属性为teacher,对应数据库中为tid
    4. 使用association实现复杂类型的关联,处理关联查询

具体实现

  1. 编写mapper接口方法

    public interface StudentMapper {
        List<Student> getStudentList();
    }
    
  2. 编写xml配置文件

    <select id="getStudentList" resultMap="studentTeacher">
        select * from student;
    </select>
    <resultMap id="studentTeacher" type="com.jh.domain.Student">
        <!--association关联属性 property属性名 javaType属性类型 column在多的一方的表中的列名-->
        <association property="teacher" column="tid" javaType="com.jh.domain.Teacher" select="getTeacher"/>
    </resultMap>
    <!--
    	这里传递过来的id,只有一个属性的时候,下面可以写任何值
    	association中column多参数配置:
           column="{key=value,key=value}"
    	其实就是键值对的形式,key是传给下个sql的取值名称,value是片段一中sql查询的字段名。
    -->
    <select id="getTeacher" resultType="com.jh.domain.Teacher">
        select * from teacher where id = #{id};
    </select>
    
  3. 编写测试

    测试结果如下

    Student{id=1, name='小明', teacher=Teacher{id=1, name='廖老师'}}
    Student{id=2, name='小红', teacher=Teacher{id=1, name='廖老师'}}
    Student{id=3, name='小张', teacher=Teacher{id=1, name='廖老师'}}
    Student{id=4, name='小李', teacher=Teacher{id=1, name='廖老师'}}
    Student{id=5, name='小王', teacher=Teacher{id=1, name='廖老师'}}
    

5、按照结果嵌套处理

除了上面这种方式,我们还可以按照结果进行嵌套处理;

  1. 编写mapper接口

    public interface StudentMapper {
        List<Student> getStudentList();
    }
    
  2. 编写xml配置文件

    <!-- 按照结果嵌套处理 -->
    <select id="getStudentList" resultMap="StudentTeacher">
        select s.id sid, s.name sname, t.id tid, t.name tname
        from mybatis.student s,
             mybatis.teacher t
        where s.id = t.id;
    </select>
    
    <resultMap id="StudentTeacher" type="com.jh.domain.Student">
        <id property="id" column="sid"/>
        <result property="name" column="sname"/>
        <!-- 关联对象property关联对象在Student实体类中的属性 -->
        <association property="teacher" javaType="com.jh.domain.Teacher">
            <result column="tname" property="name"/>
            <result column="tid" property="id"/>
        </association>
    </resultMap>
    
  3. 测试结果

    Student{id=1, name='小明', teacher=Teacher{id=1, name='廖老师'}}
    Student{id=2, name='小红', teacher=Teacher{id=1, name='廖老师'}}
    Student{id=3, name='小张', teacher=Teacher{id=1, name='廖老师'}}
    Student{id=4, name='小李', teacher=Teacher{id=1, name='廖老师'}}
    Student{id=5, name='小王', teacher=Teacher{id=1, name='廖老师'}}
    

总结

  • 按照查询进行嵌套处理就像SQL中的子查询
  • 按照结果进行嵌套处理就像SQL中的联表查询
posted @ 2021-01-12 19:31  天下御免  阅读(184)  评论(0编辑  收藏  举报