MyBatis 多表关联查询 MyBatis 多表关联查询 sql样例 单表查询 多表查询-(多对一) 多表查询-(一对多) 总结

目录

  • 单表查询
  • 多表查询
    • 多对一
    • 一对多

sql样例

表结构

MyBatis  多表关联查询
MyBatis  多表关联查询
sql样例
单表查询
多表查询-(多对一)
多表查询-(一对多)
总结

表样例

MyBatis  多表关联查询
MyBatis  多表关联查询
sql样例
单表查询
多表查询-(多对一)
多表查询-(一对多)
总结

sql语句

create table student
(
    id int not null primary key,
    name varchar(20) null,
    tid int not null
);

create table teacher
(
    id int not null primary key,
    name varchar(20) not null
);

insert into student(id,name,tid) values(1,'student1',1),(2,'student2',1),(3,'student3',1),(4,'student4',2),(5,'student5',2),(6,'student6',3);

insert into teacher(id,name) values(1,'teacherA'),(2,'teacherB'),(3,'teacherC');

单表查询

单表查询非常简单,这里仅简述

例如我们要查询所有student的信息

Student

package com.szx.pojo;
import lombok.Data;
@Data
public class Student {
    private int id;
    private String name;
    private int tid;
}

这里使用了lombok插件,省略了构造、set、get等方法

StudentMapper

package com.szx.dao;
import com.szx.pojo.Student;
import java.util.List;

public interface StudentMapper {
    List<Student> getAllStudent();
}

其中getAllStudent();为方法,返回一个List

StudentMapper.xml

<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.szx.dao.StudentMapper">
    <select >
        select * from test.student;
    </select>
</mapper>
  • 绑定接口StudentMapper
  • 制定select中的id(即方法名),和resultType(返回结果)
  • 写sql查询语句

写测试类

package com.szx;

import com.szx.dao.StudentMapper;
import com.szx.pojo.Student;
import com.szx.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class ForTest {
    @Test
    public void getAllStudents() {
        SqlSession session = MybatisUtils.getSession();
        StudentMapper mapper = session.getMapper(StudentMapper.class);
        List<Student> Students = mapper.getAllStudent();
        for (Student student : Students) {
            System.out.println(student);
        }
        session.close();
    }
}

测试结果

MyBatis  多表关联查询
MyBatis  多表关联查询
sql样例
单表查询
多表查询-(多对一)
多表查询-(一对多)
总结

多表查询-(多对一)

现在我们修改需求,我们不仅要查询所有的学生信息,我们还要查询学生对应的老师是谁以及该老师的id

对应的问题

我们可以有sql语句:

select * from student as s, teacher as t where s.tid = t.id;

在我们的sql中是可以查询到的没问题

但是如果把StudentMapper.xml中select标签中的sql改成如上,我们也仅仅只能得到学生的信息

原来的方法不可行了,因为我们的Student类中仅仅只包含学生的信息,与Teacher类毫不相关

解决问题

于是我们在Student类中定义一个Teacher, 代表该学生所对应的老师的信息

Teacher类

package com.szx.pojo;
import lombok.Data;

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

Student类

package com.szx.pojo;
import lombok.Data;

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

由于student中含有的teacher并非基本类型,所以我们要用结果映射

StudentMapper接口

package com.szx.dao;
import com.szx.pojo.Student;
import java.util.List;
public interface StudentMapper {
    List<Student> getAllStudent();
}

StudentMapper.xml

<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.szx.dao.StudentMapper">
    <select >
        select s.id as sid,t.id as tid,s.name as sname,t.name as tname,s.tid
        from student as s, teacher as t
        where s.tid = t.id;
    </select>
    <resultMap >
        <result property="id" column="sid"/>
        <result property="name" column="sname"/>
        <result property="tid" column="tid"/>
        <association property="teacher" javaType="Teacher">
            <result property="id" column="tid"/>
            <result property="name" column="tname"/>
        </association>
    </resultMap>
</mapper>

其中resultMap即是结果映射,select中的AllStudent对应id为AllStudent的resultMap

property 为 pojo中定义的变量名, column为sql语句中起的别名

例如 在student类中定义的 id 在sql 起了别名 sid,而定义的teacher是一个实体类,所以用javaType。

而teacher这个类中也会有teacher自己的变量,所以进行嵌套。

注意这里的association:这是表示关联关系,即student这个类中只有一个teacher(一个学生只有一个老师,学生和老师是一对多的关系,所以一个学生关联一个老师)

查询结果如下

MyBatis  多表关联查询
MyBatis  多表关联查询
sql样例
单表查询
多表查询-(多对一)
多表查询-(一对多)
总结

另一种查询方法

上面这种方法是一次性查出, 根据查询的结果进行映射,此外还可以查询两次

相当于

select * from teacher where id=(select tid from student);

StudentMapper.xml

<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.szx.dao.StudentMapper">
    <select >
        select * from student;
    </select>
    <resultMap >
        <result property="name" column="name"/>
        <result property="id" column="id"/>
        <result property="tid" column="tid"/>
        <association property="teacher" column="tid" javaType="Teacher" select="getTeacherByID">
            <result property="id" column="id"/>
            <result property="name" column="name"/>
        </association>
    </resultMap>
    <select  >
        select * from teacher where id=#{tid}
    </select>
</mapper>

先选择所有的学生,然后根据学生的tid查询老师,仍然可以得到相同的结果.

多表查询-(一对多)

现在我们要查询老师和其学生的信息。这可和刚才有点不一样,刚才我们要查学生和他的老师,现在我们要查询老师和他对应的所有学生

改变实体类

一个老师对应多个学生,我们在teacher中定义一个student的List即可

Teacher类

package com.szx.pojo;
import lombok.Data;
import java.util.List;

@Data
public class Teacher {
    private int id;
    private String name;
    private List<Student> students;
}

Student类

package com.szx.pojo;
import lombok.Data;

@Data
public class Student {
    private int id;
    private String name;
    private int tid;
}

TeacherMapper接口

package com.szx.dao;
import com.szx.pojo.Teacher;
import java.util.List;
public interface TeacherMapper {
    List<Teacher> getAllTeacher();
}

TeacherMapper.xml

<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.szx.dao.TeacherMapper">
    <select >
        select t.id as tid,s.id as sid,t.name as tname,s.name as sname,s.tid
        from teacher as t,student as s
        where t.id = s.tid;
    </select>
    <resultMap >
        <result property="id" column="tid"/>
        <result property="name" column="tname"/>
        <collection property="students" ofType="Student">
            <result property="id" column="sid"/>
            <result property="name" column="sname"/>
            <result property="tid" column="tid"/>
        </collection>
    </resultMap>
</mapper>

因为teacher中的students是一个List,即teacher中有多个student,这是集合关系,所以用collection

而List中的类型为Student,所以ofType为Student

至此我们能得到查询结果

查询结果

MyBatis  多表关联查询
MyBatis  多表关联查询
sql样例
单表查询
多表查询-(多对一)
多表查询-(一对多)
总结

总结

MyBatis的多表查询,只要注意是一对多还是多对一的关系。

确定之后,一个个对应pojo中的变量名和sql中的变量名即可

至于两种方式,写一次查询更为简洁,方便调试,结果映射也容易理解。

  • [x] 一次查询

  • [ ] 两次查询