iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >MyBatis 多表关联查询
  • 838
分享到

MyBatis 多表关联查询

mybatisjavamysql 2023-09-01 14:09:03 838人浏览 八月长安
摘要

✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识

在这里插入图片描述

✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。
🍎个人主页:Java Fans的博客
🍊个人信条:不迁怒,不贰过。小知识,大智慧。
💞当前专栏:SSM 框架从入门到精通
✨特色专栏:国学周更-心性养成之路
🥭本文内容:mybatis 多表关联查询

文章目录

在这里插入图片描述

一对多查询

一对多关联查询是指在查询一方对象的时候,同时将其所关联的多方对象也都查询出来。下面以班级 Classes 与学生 Student 间的一对多关系为例进行演示。一个班级有多个学生,一个学生只属于一个班级。数据库 student 表里面有个字段 classno 是外键,对应主键表 Class 的主键 cid

项目案例:查询班级号为 1801 的班级,同时遍历该班级的所有的学生信息

实现步骤:

【1】在 MySQL 中创建数据库 studentdb,创建表 studentclasses,并添加若干测试用的数据记录,SQL 语句如下:

CREATE DATABASE studentdb;USE  studentdb ;DROP TABLE IF EXISTS  student ;CREATE TABLE  student  (   id  INT(11) NOT NULL,   studentname  VARCHAR(20) DEFAULT NULL,   gender  CHAR(2) DEFAULT NULL,   age  INT(11) DEFAULT NULL,   classno VARCHAR(10),   PRIMARY KEY ( id )) INSERT  INTO  student ( id , studentname , gender , age , classno ) VALUES (1,'张飞','男',18,'201801'),(2,'李白','男',20,'201801'),(3,'张无忌','男',19,'201801'),(4,'赵敏','女',17,'201801');CREATE TABLE classes (cid VARCHAR (30),cname VARCHAR (60)); INSERT INTO classes (cid, cname) VALUES('201801','计算机软件1班');INSERT INTO classes (cid, cname) VALUES('201802','计算机软件2班');

【2】创建实体类 ClassesStudent

Student 类如下:

package cn.kGC.my01.entity;import lombok.Data;@Datapublic class Student {    private String sid;    private String sname;    private String sex;    private Integer age;    //添加额外属性:所在班级    private  Classes classes;    public String show(){        return "学生编号:"+getSid()+",学生姓名:"+getSname()+",学生性别:"+getSex()+",学生年龄:"+getAge();    }}

Classes 类如下:

package cn.kgc.my01.entity;import lombok.Data;import java.util.List;@Datapublic class Classes {    private String cid;    private String cname;    //添加额外属性    private List<Student> students;    public String show(){        return "班级编号:"+getCid()+",班级名称:"+getCname()+",班级学生:";    }}

【3】创建 ClassesMapper.java 接口,并添加 findClassesById 方法

package cn.kgc.my01.mapper;import cn.kgc.my01.entity.Classes;public interface ClassesMapper {    Classes findClassesById(String id);}

【4】创建 ClassesMapper.xml 映射文件,有以下两种方式:

方式一:多表连接查询方式。

这种方式只用到1条 SQL 语句,代码如下所示:

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"        "https://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="cn.kgc.my01.mapper.ClassesMapper">    <!--方式一:多表连接查询方式,只用到 1sql语句-->    <resultMap id="classResultMap" type="classes">        <id property="cid" column="cid"/>        <result property="cname" column="cname"/>        <!--关联属性的映射关系-->        <collection property="students" ofType="Student">            <id property="sid" column="id"/>            <result property="sname" column="studentname"/>            <result property="sex" column="gender"/>            <result property="age" column="age"/>        </collection>    </resultMap>    <select id="findClassesById" resultMap="classResultMap">        select cid,cname,id,studentname,gender,age from classes,student        where classes.cid=student.classno and classes.cid=#{cid}    </select></mapper>

注意: 中,如果字段名与属性名相同时,可以在 中添加 autoMapping=“true”开启自动映射

另外,在 “一方” 的映射文件中使用 标签体现出两个实体对象间的关联关系。其两个属性的解释如下:

  • property:指定关联属性,即 Class 类中的集合属性 students
  • ofType:集合属性的泛型类型,即 Student

方式二:多表单独查询方式。

多表连接查询方式是将多张表进行连接,连为一张表后进行查询。其查询的本质是一张表。而多表单独查询方式是多张表各自查询各自的相关内容,需要多张表的联合数据,再将主表的查询结果联合其它表的查询结果,封装为一个对象。

多个查询是可以跨越多个映射文件的,即是可以跨越多个namespace 的。在使用其它 namespace 的查询时,添加上其所在的 namespace 即可。这种方式要用到2条 SQL 语句,代码如下所示:

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"        "Https://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="cn.kgc.my01.mapper.ClassesMapper">   <!--方式二:多表单独查询方式,也就是分步查询-->    <resultMap id="classResultMap2" type="classes">        <id property="cid" column="cid"/>        <result property="cname" column="cname"/>        <!--关联属性的映射关系-->        <collection property="students" ofType="Student">            <id property="sid" column="id"/>            <result property="sname" column="studentname"/>            <result property="sex" column="gender"/>            <result property="age" column="age"/>        </collection>    </resultMap>    <!-- 以下注释部分属于方式二: 多表单独查询方式 -->    <resultMap id="studentResultMap" type="student">        <id property="sid" column="id" />        <result property="sname" column="studentname" />        <result property="sex" column="gender" />        <result property="age" column="age" />    </resultMap>    <resultMap id="classesResultMap" type="classes">        <id property="cid" column="cid" />        <result property="cname" column="cname" />    <!-- 关联属性的映射关系 -->    <!-- 集合的数据来自指定的select查询,该select查询的动态参数来自column指定的字段值 -->        <collection property="students" ofType="Student" select="selectStudentsByClasses" column="cid"/>    </resultMap>    <!-- 多表单独查询,查多方的表 -->    <select id="selectStudentsByClasses" resultMap="studentResultMap">        select * from student where calssno=#{cid}    </select>    <!-- 多表单独查询,查一方的表 -->     <select id="findClassesById" parameterType="String" resultMap="classesResultMap">        select cid,cname from classes        where cid=#{cid}    </select></mapper>

在这里插入图片描述
【5】创建 ClassesMapperTest 测试类,并添加如下方法:

package cn.kgc.my01.mapper;import cn.kgc.my01.entity.Classes;import cn.kgc.my01.entity.Student;import junit.framework.TestCase;import org.apache.ibatis.io.Resources;import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory;import org.apache.ibatis.session.SqlSessionFactoryBuilder;import org.junit.Before;import org.junit.Test;import java.io.IOException;import java.io.InputStream;import java.util.List;public class ClassesMapperTest{    SqlSessionFactory factory=null;    @Before    public void init(){        try {            System.out.println("########");            InputStream resourceAsStream = Resources.getResourceAsStream("config/mybatis-config.xml");            factory = new SqlSessionFactoryBuilder().build(resourceAsStream);        } catch (IOException e) {            e.printStackTrace();        }    }    @Test    public void testFindClassesById() {        SqlSession sqlSession = factory.openSession(true);        ClassesMapper mapper = sqlSession.getMapper(ClassesMapper.class);        Classes classesById = mapper.findClassesById("201801");        System.out.println(classesById.show());        List<Student> students = classesById.getStudents();        for (Student student : students) {            System.out.println(student.show());        }    }}

方式一:多表连接查询方式测试结果:

DEBUG [main] - ==>  Preparing: select cid,cname,id,studentname,gender,age from  classes,student where classes.cid=student.classno and classes.cid=?DEBUG [main] - ==> Parameters: 201801(String)DEBUG [main] - <==      Total: 4班级编号:201801,班级名称:计算机软件1,班级学生:学生编号:1,学生姓名:张飞,学生性别:男,学生年龄:18学生编号:2,学生姓名:李白,学生性别:男,学生年龄:20学生编号:3,学生姓名:张无忌,学生性别:男,学生年龄:19学生编号:4,学生姓名:赵敏,学生性别:女,学生年龄:17

可以发现,只有一条 SQL 语句,并且是多表联查。

方式二:多表单独查询方式测试结果:

2023-02-15 10:56:49,965 [main] DEBUG DEBUG [main] - ==>  Preparing: select cid,cname from classes where cid=?DEBUG [main] - ==> Parameters: 201801(String)DEBUG [main] - ====>  Preparing: select * from student where classno=?DEBUG [main] - ====> Parameters: 201801(String)DEBUG [main] - <====      Total: 4DEBUG [main] - <==      Total: 1班级编号:201801,班级名称:计算机软件1,班级学生:学生编号:1,学生姓名:张飞,学生性别:男,学生年龄:18学生编号:2,学生姓名:李白,学生性别:男,学生年龄:20学生编号:3,学生姓名:张无忌,学生性别:男,学生年龄:19学生编号:4,学生姓名:赵敏,学生性别:女,学生年龄:17

可以发现,其 SQL 语句是两条,即各查各的,共用同一个参数。第 1 条先查一方的表,第 2 条再查多方的表。

多对一查询

多对一关联查询是指在查询多方对象的时候,同时将其所关联的一方对象也查询出来。

由于在查询多方对象时也是一个一个查询,所以多对一关联查询,其实就是一对一关联查询。即一对一关联查询的实现方式与多对一的实现方式是相同的。 配置多对一关联的重点在于“多方”的映射文件要有 属性关联“一方”。

项目案例: 查询学号为1的学生,同时获取他所在班级的完整信息

实现步骤:

【1】创建 StudentMapper.java 接口,并添加方法 searchStudentsById(int id) 如下:

package cn.kgc.my01.mapper;import cn.kgc.my01.entity.Student;public interface StudentMapper {    public Student searchStudentsById(int id);}

【2】创建 StudentMapper.xml 映射文件,有以下两种方式:

方式一:多表联合查询。

 <!-- 多表联合查询 -->    <resultMap id="studentResultMapper" type="student">        <id property="sid" column="id" />        <result property="sname" column="studentname" />        <result property="sex" column="gender" />        <result property="age" column="age" />        <!-- 关联属性 -->        <association property="classes" javaType="classes">            <id property="cid" column="cid" />            <result property="cname" column="cname" />        </association>    </resultMap>    <!-- 多表连接查询 -->    <select id="searchStudentsById" parameterType="int" resultMap="studentResultMapper">        select cid,cname,id,studentname,gender,age from classes,student        where classes.cid=student.classno        and student.id=#{id}    </select>

方式二:多表单独查询。

    <!-- 以下注释的是方式二:多表单独查询 -->    <resultMap id="studentResultMap2" type="student">        <id property="sid" column="id" />        <result property="sname" column="studentname" />        <result property="sex" column="gender" />        <result property="age" column="age" />        <!-- 关联属性 -->        <association property="classes" javaType="classes" select="findClassesById" column="classno"/>    </resultMap>    <select id="searchStudentsById" resultMap="studentResultMap2">        select id,studentname,gender,age,classno from student where id=#{id}    </select>    <select id="findClassesById" parameterType="String" resultType="classes">        select cid,cname from classes where cid=#{cid}    </select> 

在这里插入图片描述

【3】创建 StudentMapperTest 测试类,并添加如下方法:

package cn.kgc.my01.mapper;import cn.kgc.my01.entity.Classes;import cn.kgc.my01.entity.Student;import junit.framework.TestCase;import org.apache.ibatis.io.Resources;import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory;import org.apache.ibatis.session.SqlSessionFactoryBuilder;import org.junit.Before;import org.junit.Test;import java.io.IOException;import java.io.InputStream;public class StudentMapperTest {    SqlSessionFactory factory=null;    @Before    public void init(){        try {            InputStream resourceAsStream = Resources.getResourceAsStream("config/mybatis-config.xml");            factory = new SqlSessionFactoryBuilder().build(resourceAsStream);        } catch (IOException e) {            e.printStackTrace();        }    }    @Test    public void testSearchStudentsById() {        SqlSession sqlSession = factory.openSession(true);        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);        Student student = mapper.searchStudentsById(1);        System.out.println(student.show());        System.out.println("所在班级:");        Classes classes=student.getClasses();        System.out.println(classes.toString());    }}

方式一:多表联合查询方式测试结果:

DEBUG [main] - ==>  Preparing: select cid,cname,id,studentname,gender,age from      classes,student where classes.cid=student.classno and student.id=?DEBUG [main] - ==> Parameters: 1(Integer)DEBUG [main] - <==      Total: 1学生编号:1,学生姓名:张飞,学生性别:男,学生年龄:18所在班级:Classes(cid=201801, cname=计算机软件1, students=null)

可以发现,它发出的 SQL 语句是多表查询。

方式一:多表单独查询方式测试结果:

DEBUG [main] - ==>  Preparing: select id,studentname,gender,age,classno from student where id=?DEBUG [main] - ==> Parameters: 1(Integer)DEBUG [main] - ====>  Preparing: select cid,cname from classes where cid=?DEBUG [main] - ====> Parameters: 201801(String)DEBUG [main] - <====      Total: 1DEBUG [main] - <==      Total: 1学生编号:1,学生姓名:张飞,学生性别:男,学生年龄:18所在班级:Classes(cid=201801, cname=计算机软件1, students=null)

可以发现,它发出的 SQL 语句是两条,即各查各的,共用同一个参数。

自连接查询

自连接的查询可以用一对多来处理,也可以用多对一来处理。例如,员工表,每个员工都有一个上司,但上司同时也是员工表的一条记录,这种情况可用自连接查询出每个员工对应的上司信息,也可以查出每个上司有哪些下属员工。

使用多对一的方式实现自连接

项目案例:查询员工的信息及对应的上司信息。

思路分析: 可将员工当做多方,上司当做一方。

实现步骤:

【1】修改数据库。

添加一个表 employee 并插入测试数据,具体如下:

create table employee (empid double ,empname varchar (60),job varchar (60),leader double ); insert into employee (empid, empname, job, leader) values('1','jack','clerk','3');insert into employee (empid, empname, job, leader) values('2','mike','salesman','3');insert into employee (empid, empname, job, leader) values('3','john','manager','4');insert into employee (empid, empname, job, leader) values('4','smith','president',NULL);insert into employee (empid, empname, job, leader) values('5','rose','salesman','3');

【2】创建实体类 Employee,代码如下:

package cn.kgc.my01.entity;public class Employee {private int empid;private String empname;private String job;private Employee leader;public int getEmpid() {return empid;}public void setEmpid(int empid) {this.empid = empid;}public String getEmpname() {return empname;}public void setEmpname(String empname) {this.empname = empname;}public String getJob() {return job;}public void setJob(String job) {this.job = job;}public Employee getLeader() {return leader;}public void setLeader(Employee leader) {this.leader = leader;}public String toString(){return "员工编号:"+getEmpid()+",员工姓名:"+getEmpname()+",员工职位:"+getJob();}}

可以发现,里面存在着嵌套,Employee 里面的一个属性 leader 本身就是 Employee 类型。

【3】创建 EmployeeMapper.java 接口,添加 findEmployeeAndLeaderById 方法如下:

package cn.kgc.my01.mapper;import cn.kgc.my01.entity.Employee;public interface EmployeeMapper {    Employee findEmployeeAndLeaderById(int id);}

【4】创建 EmployeeMapper.xml 映射文件,代码如下:

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"        "https://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="cn.kgc.my01.mapper.EmployeeMapper">    <resultMap id="empResultMap" type="employee">        <id property="empid" column="empid" />        <result property="empname" column="empname" />        <result property="job" column="job" />        <association property="leader" javaType="Employee"                     select="findEmployeeAndLeaderById" column="leader"/>    </resultMap>    <select id="findEmployeeAndLeaderById" parameterType="int" resultMap="empResultMap">        select * from employee where empid=#{empid}    </select></mapper>

【5】创建 EmployeeMapperTest.java 测试类

package cn.kgc.my01.mapper;import cn.kgc.my01.entity.Classes;import cn.kgc.my01.entity.Employee;import cn.kgc.my01.entity.Student;import junit.framework.TestCase;import org.apache.ibatis.io.Resources;import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory;import org.apache.ibatis.session.SqlSessionFactoryBuilder;import org.junit.Before;import org.junit.Test;import java.io.IOException;import java.io.InputStream;import java.util.Scanner;public class EmployeeMapperTest {    SqlSessionFactory factory=null;    @Before    public void init(){        try {            InputStream resourceAsStream = Resources.getResourceAsStream("config/mybatis-config.xml");            factory = new SqlSessionFactoryBuilder().build(resourceAsStream);        } catch (IOException e) {            e.printStackTrace();        }    }    @Test    public void testFindEmployeeAndLeaderById() {        SqlSession sqlSession = factory.openSession(true);        EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);        Employee employee=mapper.findEmployeeAndLeaderById(1);        Employee leader=employee.getLeader();        System.out.println(employee.toString());        System.out.println("他的上司是:"+leader.toString());        //System.out.println("他的上司的上司是:"+leader.getLeader().toString());    }}

测试结果: 查询员工

DEBUG [main] - ==>  Preparing: select * from employee where empid=?DEBUG [main] - ==> Parameters: 1(Integer)DEBUG [main] - ====>  Preparing: select * from employee where empid=?DEBUG [main] - ====> Parameters: 3(Integer)DEBUG [main] - ======>  Preparing: select * from employee where empid=?DEBUG [main] - ======> Parameters: 4(Integer)DEBUG [main] - <======      Total: 1DEBUG [main] - <====      Total: 1DEBUG [main] - <==      Total: 1员工编号:1,员工姓名:jack,员工职位:clerk他的上司是:员工编号:3,员工姓名:john,员工职位:manager

从上面的 SQL 语句中发现,出现了 3 条 SQL 语句,这个查询存在嵌套,先查员工1,然后查他的直接上司3,再查上司的上司4。这种情况不影响什么,甚至可以实现直接输出上司的上司,但要注意输出语句不要出现地柜,即输出语句不要出现输出上司。

要同时查上司的上司,只需要在上面的测试类中多加一条语句:

System.out.println("他的上司的上司是:"+leader.getLeader().toString());

使用一对多的方式实现自连接

项目案例:查询某位领导及其直接下属员工。

思路分析: 可用一对多的方式来实现,员工(领导)当作一方,员工(下属)当作多方。

实现步骤:

【1】修改实体类 Employee,代码如下:

package cn.kgc.my01.entity;import java.util.List;public class Employee {private int empid;private String empname;private String job;//员工的上司private Employee leader;//员工的下属private List<Employee> employees;public List<Employee> getEmployees() {return employees;}public void setEmployees(List<Employee> employees) {this.employees = employees;}public int getEmpid() {return empid;}public void setEmpid(int empid) {this.empid = empid;}public String getEmpname() {return empname;}public void setEmpname(String empname) {this.empname = empname;}public String getJob() {return job;}public void setJob(String job) {this.job = job;}public Employee getLeader() {return leader;}public void setLeader(Employee leader) {this.leader = leader;}public String toString(){return "员工编号:"+getEmpid()+",员工姓名:"+getEmpname()+",员工职位:"+getJob();}}

【2】在 EmployeeMapper.java 接口中,添加 findLeaderAndEmployeesById 方法如下:

Employee findLeaderAndEmployeesById(int id);

【3】在 EmployeeMapper.xml 映射文件中,添加 findEmployeeAndLeaderById 的映射方法内容如下:

    <!-- 一对多的方式实现自连接 -->    <resultMap id="empResultMap2" type="employee">        <id property="empid" column="empid" />        <result property="empname" column="empname" />        <result property="job" column="job" />        <!-- 关联属性的映射关系        集合的数据来自指定的select查询,该select查询的动态参数来自column指定的字段值 -->        <collection property="employees" ofType="employee"                    select="selectEmployeesByLeader" column="empid"/>    </resultMap>    <select id="selectEmployeesByLeader" resultType="employee">        select * from employee where leader=#{empid}    </select>    <select id="findLeaderAndEmployeesById" parameterType="int" resultMap="empResultMap2">        select * from employee where empid=#{empid}    </select>

【4】在 EmployeeMapperTest.java 测试类中,添加如下内容:

    @Test    public void testTestFindLeaderAndEmployeesById() {        SqlSession sqlSession = factory.openSession(true);        EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);        Employee leader=mapper.findLeaderAndEmployeesById(4);        List<Employee> employees = leader.getEmployees();        System.out.println(leader.toString());        System.out.println("他的直接下属有:");        for (Employee employee : employees) {            System.out.println(employee.toString());        }    }

测试结果: 查询经理

DEBUG [main] - ==>  Preparing: select * from employee where empid=?DEBUG [main] - ==> Parameters: 4(Integer)DEBUG [main] - ====>  Preparing: select * from employee where leader=?DEBUG [main] - ====> Parameters: 4.0(Double)DEBUG [main] - <====      Total: 1DEBUG [main] - <==      Total: 1员工编号:4,员工姓名:smith,员工职位:president他的直接下属有:员工编号:3,员工姓名:john,员工职位:manager

多对多查询

原理: 多对多可以分拆成两个一对多来处理,需要一个中间表,各自与中间表实现一对多的关系。

项目案例:一个学生可以选人修多门课程,一门课程可以给多个学生选修,课程与学生之间是典型的多对多。实现查询一个学生信息,同时查出他的所有选修课,还有实现查询一门课程信息,同时查出所有的选修了该课程的学生信息。

思路分析: 多对多需要第三表来体现,数据库中除了课程表,学生表,还需要学生课程表。

实现步骤:

【1】修改数据库,代码如下:

CREATE DATABASE studentdb;USE  studentdb ;DROP TABLE IF EXISTS  student ;CREATE TABLE  student  (   id  INT(11) NOT NULL,   studentname  VARCHAR(20) DEFAULT NULL,   gender  CHAR(2) DEFAULT NULL,   age  INT(11) DEFAULT NULL,   classno VARCHAR(10),   PRIMARY KEY ( id )) INSERT  INTO  student ( id , studentname , gender , age , classno ) VALUES (1,'张飞','男',18,'201801'),(2,'李白','男',20,'201801'),(3,'张无忌','男',19,'201801'),(4,'赵敏','女',17,'201801');CREATE TABLE classes (cid VARCHAR (30),cname VARCHAR (60)); INSERT INTO classes (cid, cname) VALUES('201801','计算机软件1班');INSERT INTO classes (cid, cname) VALUES('201802','计算机软件2班');CREATE TABLE employee (empid DOUBLE ,empname VARCHAR (60),job VARCHAR (60),leader DOUBLE ); INSERT INTO employee (empid, empname, job, leader) VALUES('1','jack','clerk','3');INSERT INTO employee (empid, empname, job, leader) VALUES('2','mike','salesman','3');INSERT INTO employee (empid, empname, job, leader) VALUES('3','john','manager','4');INSERT INTO employee (empid, empname, job, leader) VALUES('4','smith','president',NULL);INSERT INTO employee (empid, empname, job, leader) VALUES('5','rose','salesman','3');CREATE TABLE course (courseid DOUBLE ,coursename VARCHAR (90)); INSERT INTO course (courseid, coursename) VALUES('1','java');INSERT INTO course (courseid, coursename) VALUES('2','Android');INSERT INTO course (courseid, coursename) VALUES('3','PHP');CREATE TABLE studentcourse (id DOUBLE ,studentid DOUBLE ,courseid DOUBLE ); INSERT INTO studentcourse (id, studentid, courseid) VALUES('1','1','1');INSERT INTO studentcourse (id, studentid, courseid) VALUES('2','1','2');INSERT INTO studentcourse (id, studentid, courseid) VALUES('3','2','1');INSERT INTO studentcourse (id, studentid, courseid) VALUES('4','2','2');INSERT INTO studentcourse (id, studentid, courseid) VALUES('5','3','1');INSERT INTO studentcourse (id, studentid, courseid) VALUES('6','3','2');INSERT INTO studentcourse (id, studentid, courseid) VALUES('7','1','3');

【2】新增实体类 Course 和修改实体类 Student 。

Course 类如下:

package cn.kgc.my01.entity;import lombok.Data;import java.util.List;@Datapublic class Course {    private int courseid;    private String coursename;    private List<Student> students;    public String toString(){        return "课程编号:"+getCourseid()+",课程名称:"+getCoursename();    }}

Student类如下,添加一个属性courses和getter,setter方法。

    private List<Course> courses;    public List<Course> getCourses() {        return courses;    }    public void setCourses(List<Course> courses) {        this.courses = courses;    }

【3】新建 StudentMapper.java 接口,并添加一个方法如下:

package cn.kgc.my01.mapper;import cn.kgc.my01.entity.Student;public interface StudentMapper {    public Student searchStudentById(int id);}

【4】配置对应的 StudentMapper.xml 映射,代码如下:

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"        "https://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="cn.kgc.my01.mapper.StudentMapper">    <resultMap id="studentMap2" type="student">        <id property="sid" column="id" />        <result property="sname" column="studentname" />        <result property="sex" column="gender" />        <result property="age" column="age" />        <!-- 关联属性的映射关系 -->        <collection property="courses" ofType="Course">            <id property="courseid" column="courseid" />            <result property="coursename" column="coursename" />        </collection>    </resultMap>    <!-- 多表连接查询 -->    <select id="searchStudentById" parameterType="int" resultMap="studentMap2">        select student.id,studentname,gender,age,course.courseid,coursename from course,student,studentcourse        where course.courseid=studentcourse.courseid        and student.id=studentcourse.studentid and student.id=#{id}    </select></mapper>

【5】创建测试类 StudentMapperTest 类

package cn.kgc.my01.mapper;import cn.kgc.my01.entity.Classes;import cn.kgc.my01.entity.Course;import cn.kgc.my01.entity.Student;import junit.framework.TestCase;import org.apache.ibatis.io.Resources;import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory;import org.apache.ibatis.session.SqlSessionFactoryBuilder;import org.junit.Before;import org.junit.Test;import java.io.IOException;import java.io.InputStream;import java.util.List;public class StudentMapperTest {    SqlSessionFactory factory=null;    @Before    public void init(){        try {            InputStream resourceAsStream = Resources.getResourceAsStream("config/mybatis-config.xml");            factory = new SqlSessionFactoryBuilder().build(resourceAsStream);        } catch (IOException e) {            e.printStackTrace();        }    }    @Test    public void testSearchStudentsById() {        SqlSession sqlSession = factory.openSession(true);        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);        Student student = mapper.searchStudentById(1);        System.out.println(student.show());        System.out.println("-----该生选修了以下课程:-----------");        List<Course> courses=student.getCourses();        for(Course course:courses){            System.out.println(course.toString());        }    }}

测试结果:

在这里插入图片描述

【6】新建 CourseMapper.java 接口,并添加一个方法如下:

package cn.kgc.my01.mapper;import cn.kgc.my01.entity.Course;public interface CourseMapper {    //根据id查找课程,即时获取选个性该课程的学生    public Course searchCourseById(int id);}

【7】配置对应的 CourseMapper.xml 映射,代码如下:

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"        "https://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="cn.kgc.my01.mapper.CourseMapper">  <resultMap id="courseMap" type="course">    <id property="courseid" column="courseid" />    <result property="coursename" column="coursename" />    <!-- 关联属性的映射关系 -->    <collection property="students" ofType="Student">      <id property="sid" column="id" />      <result property="sname" column="studentname" />      <result property="sex" column="gender" />      <result property="age" column="age" />    </collection>  </resultMap>  <!-- 多表连接查询 -->  <select id="searchCourseById" parameterType="int" resultMap="courseMap">    select student.id,studentname,gender,age,course.courseid,coursename from course,student,studentcourse    where course.courseid=studentcourse.courseid    and student.id=studentcourse.studentid and course.courseid=#{courseid}  </select></mapper>

【8】创建测试类 CourseMapperTest 类

package cn.kgc.my01.mapper;import cn.kgc.my01.entity.Course;import cn.kgc.my01.entity.Employee;import cn.kgc.my01.entity.Student;import junit.framework.TestCase;import org.apache.ibatis.io.Resources;import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory;import org.apache.ibatis.session.SqlSessionFactoryBuilder;import org.junit.Before;import org.junit.Test;import java.io.IOException;import java.io.InputStream;import java.util.List;public class CourseMapperTest{    SqlSessionFactory factory=null;    @Before    public void init(){        try {            InputStream resourceAsStream = Resources.getResourceAsStream("config/mybatis-config.xml");            factory = new SqlSessionFactoryBuilder().build(resourceAsStream);        } catch (IOException e) {            e.printStackTrace();        }    }    @Test    public void testSearchCourseById() {        SqlSession sqlSession = factory.openSession(true);        CourseMapper mapper = sqlSession.getMapper(CourseMapper.class);        Course course = mapper.searchCourseById(1);        System.out.println(course.toString());        System.out.println("-------该课程有以下学生选修:------");        List<Student> students=course.getStudents();        for(Student student:students){            System.out.println(student.show());        }    }}

测试效果:

在这里插入图片描述


  码文不易,本篇文章就介绍到这里,如果想要学习更多Java系列知识点击关注博主,博主带你零基础学习Java知识。与此同时,对于日常生活有困扰的朋友,欢迎阅读我的第四栏目《国学周更—心性养成之路》,学习技术的同时,我们也注重了心性的养成。

在这里插入图片描述

来源地址:https://blog.csdn.net/hh867308122/article/details/129005131

您可能感兴趣的文档:

--结束END--

本文标题: MyBatis 多表关联查询

本文链接: https://www.lsjlt.com/news/388607.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • MyBatis 多表关联查询
    ✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识...
    99+
    2023-09-01
    mybatis java mysql
  • mybatis-plus 多表关联条件分页查询
    此处以一对多,条件分页查询为例: 一.表结构: 主表 CREATE TABLE `t_user` ( `id` bigint NOT NULL AUTO_INCREMENT, `user_name` varchar(255) DEFAU...
    99+
    2023-08-20
    mybatis mysql java
  • Mybatis表的关联查询详情
    目录导语什么时候用<resultMap>标签映射什么时候用<association>&<collection>Mybatis表的关联查询一对多查询多对一查询一...
    99+
    2024-04-02
  • Mysql 多表关联查询
    文章目录 1. Mysql中表之间的关系1.1 多表关系1.2 外键约束 2. 多表联合查询2.1 交叉连接查询:笛卡尔积2.2 内连接查询:inner join2.3 外连接查询2.3.1 左连接:2.3.2 右连接:2.3....
    99+
    2023-08-21
    mysql 数据库 sql
  • mybatis-plus多表关联查询功能的实现
    学习目标: mybatis-plus多表关联查询 学习内容: mybatis-plus多表关联查询 实体类部分代码 @Data @AllArgsConstructor @NoAr...
    99+
    2024-04-02
  • MySQL的多表关联查询
    一、多表关联查询 多表关联查询是使用一条SQL语句,将关联的多张表的数据查询出来。 1.1 交叉查询 交叉查询就是将多张表的数据没有条件地连接在一起进行展示。 1.1.1 语法 使用交叉查询类别和商品 -- 目标:查询所有分类,以及每个分类...
    99+
    2023-08-22
    mysql 数据库 java
  • Mybatis-多表联查
    多表联查 一、步骤一:创建pojo实体类二、步骤二:明确两个实体类之间的关系三、步骤三:修改pojo实体类四、步骤四:编写Mapper接口五、步骤五:编写Mapper映射文件题目1:通过订单i...
    99+
    2023-09-02
    mybatis java 数据库
  • Mybatis-Plus多表关联查询的使用案例解析
    目录项目的目录结构:有以下四个包:有表结构如下: 首先配置pom.xml配置文件1.pojo包中有dept和emp两个实例类2.在Emp的mapper映射文件(.xml)中...
    99+
    2023-05-20
    Mybatis-Plus多表关联查询 Mybatis-Plus多表查询
  • spring boot集成mybatis-plus——Mybatis Plus 多表联查(包含分页关联查询,图文讲解)...
    Mybatis Plus 多表联查(包含分页关联查询,图文讲解)  更新时间 2023-01-03 21:41:38 大家好,我是小哈。 本小节中,我们将学习如何通过 Mybatis Plus 实现多表关联查询,以及...
    99+
    2023-08-31
    mybatis spring boot java 数据库 mysql
  • MyBatis 多表联合查询及优化方法
    目录背景正文关于优化这篇文章我打算来简单的谈谈 mybatis 的多表联合查询。起初是觉得挺简单的,没必要拿出来写,毕竟 mybatis 这东西现在是个开发的都会用,而且网上的文章也...
    99+
    2022-11-13
    MyBatis 多表联合查询 MyBatis 多表查询
  • MySQL联合查询(多表查询)
    一、内连接 select *from 表1 [ inner | cross ] join 表2 [ on过滤条件 ] [ where查询条件 ] ; [ inner | cross ]: join 内连接关键字(必须要有...
    99+
    2023-09-14
    mysql 数据库 database
  • Mybatis-plus多表查询
    如题有一个用户表,有一个订单表,此时你想查询用户的时候把他附属的订单也查到 一对多 user pojo package com.suse.entity;import com.baomidou.myba...
    99+
    2023-09-09
    mybatis java mysql
  • 使用AOP+反射实现自定义Mybatis多表关联查询
    目录一、需求二、核心代码MapToDoMapIDualMapperDualMapperDoMapAspect三、使用方法SysUserSysRoleSysPermissionSysU...
    99+
    2024-04-02
  • 详解mybatis多对一关联查询的方式
    根据ID查询学生信息,要求该学生的教师和班级信息一并查出 第一种关联方式 1.修改实体类Student,追加关联属性,用于封装关联的数据 修改完以后重新生成get set方法还有t...
    99+
    2024-04-02
  • MySQL多表关联查询实例分析
    本篇内容介绍了“MySQL多表关联查询实例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!数据库设计范式目前数据库设计有五种范式 , 一般...
    99+
    2023-06-30
  • mysql 多表关联查询如何改进
    mysql 多表关联查询怎么优化好呢 🚨 使用正确的连接类型优化 WHERE 子句为关联字段创建索引减少查询的字段考虑使用分布式查询尽量避免子查询优化连接顺序利用 EXPLAIN 分析查询分解复杂查询使用视图...
    99+
    2023-08-28
    mysql 数据库 sql 多表 优化
  • Hibernate多表关联查询怎么实现
    本篇内容介绍了“Hibernate多表关联查询怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、Hibernate简介Hiberna...
    99+
    2023-06-17
  • MyBatis中怎么进行一对多关联查询
    在MyBatis中进行一对多关联查询可以通过在映射文件中使用嵌套查询来实现。具体步骤如下: 在映射文件中定义两个查询语句,一个用于...
    99+
    2024-04-08
    MyBatis
  • oracle多表关联查询如何实现
    在Oracle数据库中,可以使用SQL语句实现多表关联查询。以下是一个示例: 假设有两个表:表A和表B,它们有一个共同的字段ID可以...
    99+
    2024-04-09
    oracle
  • MySQL详细讲解多表关联查询
    目录数据库设计范式外键内连接 外连接结语数据库设计范式 目前数据库设计有五种范式 , 一般我们数据库只需要满足前三项即可 第一范式 : 确保每列保持原子性 什么是原子性 意...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作