zoukankan      html  css  js  c++  java
  • MyBatis 多表关联查询

    MyBatis 多表关联查询

    目录

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

    sql样例

    表结构

    t1.npg

    表样例

    t2.png

    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 id="getAllStudent" resultType="Student">
            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();
        }
    }
    

    测试结果

    t3.png

    多表查询-(多对一)

    现在我们修改需求,我们不仅要查询所有的学生信息,我们还要查询学生对应的老师是谁以及该老师的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 id="getAllStudent" resultMap="AllStudent">
            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 id="AllStudent" type="Student">
            <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(一个学生只有一个老师,学生和老师是一对多的关系,所以一个学生关联一个老师)

    查询结果如下

    t4.png

    另一种查询方法

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

    相当于

    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 id="getAllStudent" resultMap="AllStudent">
            select * from student;
        </select>
        <resultMap id="AllStudent" type="Student">
            <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 id="getTeacherByID" resultType="teacher" >
            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 id="getAllTeacher" resultMap="AllTeacher">
            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 id="AllTeacher" type="Teacher">
            <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

    至此我们能得到查询结果

    查询结果

    t5.png

    总结

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

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

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

    • [x] 一次查询

    • [ ] 两次查询

  • 相关阅读:
    /etc/security/limits.conf 配置
    docker 私有仓库镜像的存储位置
    docker 私有仓库镜像的存储位置
    docker 数据映射方案
    docker 数据映射方案
    docker 容器开启ssh服务
    docker 容器开启ssh服务
    docker 容器扩盘
    docker 容器扩盘
    Python爬虫从入门到精通——基本库re的使用:正则表达式
  • 原文地址:https://www.cnblogs.com/xun-/p/13062470.html
Copyright © 2011-2022 走看看