草庐IT

Mybatis关联查询【附实战案例】

会洗碗的CV工程师 2023-08-04 原文

目录

一、Mybatis一对一关联查询

1. 新增持久层接口方法

2. 新增映射文件对应的标签

3. 新增测试方法

4. 运行效果

二、Mybatis一对多关联查询

1. 新增持久层接口方法

2. 新增映射文件对应的标签

3. 新增测试方法

4. 运行效果

三、Mybatis多对多关联查询

1. 新增持久层接口方法

2. 新增映射文件对应的标签

3. 新增测试方法

4. 运行效果

四、进阶查询班级信息

1. 新增持久层接口方法

2. 新增映射文件对应的标签

3. 新增测试方法

4. 运行效果


一、Mybatis一对一关联查询

        查询学生时,将关联的一个班级对象查询出来,就是一对一关联查询。这里还新增了几个实体类

新增Classes实体类

package com.example.pojo;

import java.util.List;

public class Classes {
    private int cid;
    private String className;
    private List<Student> studentList;
    private List<Teacher> teacherList;

    public int getCid() {
        return cid;
    }

    public void setCid(int cid) {
        this.cid = cid;
    }

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    public List<Student> getStudentList() {
        return studentList;
    }

    public void setStudentList(List<Student> studentList) {
        this.studentList = studentList;
    }

    public List<Teacher> getTeacherList() {
        return teacherList;
    }

    public void setTeacherList(List<Teacher> teacherList) {
        this.teacherList = teacherList;
    }

    @Override
    public String toString() {
        return "Classes[ " +
                "cid=" + cid +
                ", className='" + className + '\'' +
                ", studentList=" + studentList + '\'' +
                ", teacherList=" + teacherList +
                " ]";
    }
}

新增Student实体类

package com.example.pojo;

public class Student {
    private int sid;
    private String name;
    private int age;
    private String sex;
    private Classes classes;

    public int getSid() {
        return sid;
    }

    public void setSid(int sid) {
        this.sid = sid;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Classes getClasses() {
        return classes;
    }

    public void setClasses(Classes classes) {
        this.classes = classes;
    }

    @Override
    public String toString() {
        return "Student[ " +
                "sid=" + sid +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                ", classes=" + classes +
                " ]";
    }
}

新增Teacher实体类 

package com.example.pojo;

import java.util.List;

public class Teacher {
    private Integer tid;
    private String tname;
    private List<Classes> classes;

    public Integer getTid() {
        return tid;
    }

    public void setTid(Integer tid) {
        this.tid = tid;
    }

    public String getTname() {
        return tname;
    }

    public void setTname(String tname) {
        this.tname = tname;
    }

    public List<Classes> getClasses() {
        return classes;
    }

    public void setClasses(List<Classes> classes) {
        this.classes = classes;
    }

    @Override
    public String toString() {
        return "Teacher[ " +
                "tid=" + tid +
                ", tname='" + tname + '\'' +
                ", classes=" + classes +
                " ]";
    }
}

1. 新增持久层接口方法

package com.example.mapper;

import com.example.pojo.Student;

import java.util.List;

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

2. 新增映射文件对应的标签

StudentMapper.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.example.mapper.StudentMapper">
    <resultMap id="studentMapper" type="com.example.pojo.Student">
        <!-- 主键列 -->
        <id property="sid" column="sid"></id>
        <!-- 普通列 -->
        <result property="name" column="name"></result>
        <result property="age" column="age"></result>
        <result property="sex" column="sex"></result>
        <!-- 一对一对象列 property:属性名 column:关联列名 javaType:对象类型 -->
        <association property="classes" column="classId" javaType="com.example.pojo.Classes">
            <!-- 关联对象主键列 -->
            <id property="cid" column="cid"></id>
            <!-- 关联对象普通列 -->
            <result property="className" column="className"></result>
        </association>
    </resultMap>
    <!-- 多表查询,级联查询学生和其他班级 -->
    <select id="findAll" resultMap="studentMapper">
        select * from student left join classes on student.classId = classes.cid;
    </select>
</mapper>

3. 新增测试方法

    @Test
    public void testFindAll(){
        StudentMapper studentMapper = session.getMapper(StudentMapper.class);
        List<Student> all = studentMapper.findAll();
        all.forEach(System.out::println);
    }

4. 运行效果

Ok,从运行效果来看确实查询出来每个学生对应的班级了 

二、Mybatis一对多关联查询

查询班级时,将关联的学生集合查询出来,就是一对多关联查询。

1. 新增持久层接口方法

package com.example.mapper;

import com.example.pojo.Classes;

import java.util.List;

public interface ClassesMapper {
    List<Classes> findAll();
}

2. 新增映射文件对应的标签

<?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.example.mapper.ClassesMapper">
    <resultMap id="classesMapper" type="com.example.pojo.Classes">
        <id property="cid" column="cid"></id>
        <result property="className" column="className"></result>
        <!-- 集合列 property:属性名  column:关联列名  ofType:集合的泛型 -->
        <collection property="studentList" column="classId" ofType="com.example.pojo.Student">
            <id property="sid" column="sid"></id>
            <result property="name" column="name"></result>
            <result property="age" column="age"></result>
            <result property="sex" column="sex"></result>
        </collection>
    </resultMap>

    <!-- 多表查询,级联查询班级和它的学生 -->
    <select id="findAll" resultMap="classesMapper">
        select * from classes left join student on classes.cid = student.classId;
    </select>
</mapper>

3. 新增测试方法

// 测试查询一对多关联查询
    @Test
    public void testFindAllClasses(){
        ClassesMapper classesMapper = session.getMapper(ClassesMapper.class);
        List<Classes> all = classesMapper.findAll();
        all.forEach(System.out::println);
    }

4. 运行效果

OK,观察运行效果,确实是将每个班级对应的学生都查询出来了。 

三、Mybatis多对多关联查询

MyBatis多对多关联查询本质就是两个一对多关联查询。

例如有老师类和班级类:

一个老师对应多个班级,也就是老师类中有一个班级集合属性。

一个班级对应多个老师,也就是班级类中有一个老师集合属性。

本次我们的目的就是查询各个老师对应所教的的班级,并且各个班级的老师也一并查询出来,这里有点拗口。稍加理解即可。

1. 新增持久层接口方法

package com.example.mapper;

import com.example.pojo.Teacher;

import java.util.List;

public interface TeacherMapper {
    List<Teacher> findAll();
}

2. 新增映射文件对应的标签

<?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.example.mapper.TeacherMapper">
    <resultMap id="teacherMapper" type="com.example.pojo.Teacher">
        <id property="tid" column="tid"></id>
        <result property="tname" column="tname"></result>
        <collection property="classes" column="tid" ofType="com.example.pojo.Classes">
            <id property="cid" column="cid"></id>
            <result column="className" property="className"></result>
        </collection>
    </resultMap>
    <select id="findAll" resultMap="teacherMapper">
        select * from teacher left join classes_teacher
            on teacher.tid = classes_teacher.tid
            left join classes
            on classes_teacher.cid = classes.cid
    </select>
</mapper>

3. 新增测试方法

// 测试多对多关联查询
    @Test
    public void testFindAllTeacher(){
        TeacherMapper teacherMapper = session.getMapper(TeacherMapper.class);
        List<Teacher> all = teacherMapper.findAll();
        all.forEach(System.out::println);
    }

4. 运行效果

        OK,这里也是可以查询出每个老师教的班级,一个班级有多个老师,一个老师可以对应多个 班级,这就是多对多查询

四、进阶查询班级信息

        因为在前面,我们查询所有班级信息的时候,老师列表是空的,现在如果想查询班级时,将关联的老师集合查询出来,只需要修改班级映射文件的Sql语句和 <resultMap> 即可:

1. 新增持久层接口方法

List<Classes> findAll1();

2. 新增映射文件对应的标签

    <!--如果想查询班级时,将关联的老师集合查询出来,只需要修改班级
映射文件的Sql语句和 <resultMap> 即可:-->
    <resultMap id="classesMapper1" type="com.example.pojo.Classes">
        <id property="cid" column="cid"></id>
        <result property="className" column="className"></result>
        <!-- 集合列 property:属性名  column:关联列名  ofType:集合的泛型 -->
        <collection property="studentList" column="classId" ofType="com.example.pojo.Student">
            <id property="sid" column="sid"></id>
            <result property="name" column="name"></result>
            <result property="age" column="age"></result>
            <result property="sex" column="sex"></result>
        </collection>
        <collection property="teacherList" column="cid" ofType="com.example.pojo.Teacher">
            <id property="tid" column="tid"></id>
            <result property="tname" column="tname"></result>
        </collection>
    </resultMap>

    <!-- 多表查询,级联查询班级和它的学生 -->
    <select id="findAll1" resultMap="classesMapper1">
        select * from classes
            left join student
                on classes.cid = student.classId
            left join classes_teacher
                on classes.cid = classes_teacher.cid
            left join teacher
                on classes_teacher.tid = teacher.tid;
    </select>

3. 新增测试方法

    @Test
    public void testFindAllClasses1(){
        ClassesMapper classesMapper = session.getMapper(ClassesMapper.class);
        List<Classes> all = classesMapper.findAll1();
        all.forEach(System.out::println);
    }

4. 运行效果

OK,可以看到查询班级信息的时候确实将老师列表也查询出来了。

有关Mybatis关联查询【附实战案例】的更多相关文章

  1. 「Python|Selenium|场景案例」如何定位iframe中的元素? - 2

    本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决

  2. 微信小程序开发入门与实战(Behaviors使用) - 2

    @作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors    1、什么是behaviors    2、behaviors的工作方式    3、创建behavior    4、导入并使用behavior    5、behavior中所有可用的节点    6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors    1、什么是behaviorsbehaviors是小程序中,用于实现

  3. ruby &&= 边缘案例 - 2

    有点边缘情况,但知道为什么&&=会这样吗?我正在使用1.9.2。obj=Object.newobj.instance_eval{@bar&&=@bar}#=>nil,expectedobj.instance_variables#=>[],soobjhasno@barinstancevariableobj.instance_eval{@bar=@bar&&@bar}#ostensiblythesameas@bar&&=@barobj.instance_variables#=>[:@bar]#whywouldthisversioninitialize@bar?为了比较,||=将实例变量初始

  4. 你真正了解什么是接口测试么?接口实战一“篇”入魂 - 2

    最近在工作中,看到一些新手测试同学,对接口测试存在很多疑问,甚至包括一些从事软件测试3,5年的同学,在聊到接口时,也是一知半解;今天借着这个机会,对接口测试做个实战教学,顺便总结一下经验,分享给大家。计划拆分成4个模块跟大家做一个分享,(接口测试、接口基础知识、接口自动化、接口进阶)感兴趣的小伙伴记得关注,希望对你的日常工作和求职面试,带来一些帮助。注:文章较长有5000多字,希望小伙伴们认真看完,当然有些内容对小白同学不是太友好,如果你需要详细了解其中的一些概念或者名词,请在文章之后留言,后续我将针对大家的疑问,整理输出一些大家感兴趣的文章。随着开发模式的迭代更新,前后端分离已不是新的概念,

  5. FIFO实战学习-同步FIFO/异步FIFO-格雷码 - 2

    目录FIFO一.自定义同步FIFO1.1代码设计1.2Testbech1.3行为仿真***学习位宽计算函数$clog2()***$clog2()系统函数使用,可以不关注***分布式资源或者BLOCKBRAM二.异步FIFO2.1在FIFO判满的时候有两种方式:2.2异步FIFO为什么要使用格雷码2.2.1介绍格雷码2.2.2格雷码在异步FIFO中的应用2.2.2格雷码判满2.4二进制与格雷码之间的转换2.4.1二进制码转换为格雷码的方法2.4.2格雷码转换为二进制码的方法2.3实现框图2.5实现及仿真代码2.6仿真图验证2.7结论FIFO  这篇更多的是记录FIFO学习,参考了众多优秀的文章,

  6. ruby - 使用散列或案例陈述 [Ruby] - 2

    一般来说哪个更好用?:casenwhen'foo'result='bar'when'peanutbutter'result='jelly'when'stack'result='overflow'returnresult或map={'foo'=>'bar','peanutbutter'=>'jelly','stack'=>'overflow'}returnmap[n]更具体地说,什么时候应该使用案例陈述,什么时候应该只使用散列? 最佳答案 散列是一种数据结构,而case语句是一种控制结构。当你只是检索一些数据时,你应该使用散列(就像你

  7. Ruby:案例使用对象 - 2

    有没有办法在case语句的对象上隐式调用方法?即:classFoodefbar1enddefbaz...endend我希望能够做的是这样的事情......foo=Foo.newcasefoowhen.bar==1then"something"when.bar==2then"somethingelse"when.baz==3then"anotherthing"end...其中“when”语句正在评估case对象上方法的返回。这样的结构可能吗?如果是的话,我还没有弄清楚语法...... 最佳答案 FWIW,您根本不需要将对象传递给1.8

  8. Android Studio开发之使用内容组件Content获取通讯信息讲解及实战(附源码 包括添加手机联系人和发短信) - 2

    运行有问题或需要源码请点赞关注收藏后评论区留言一、利用ContentResolver读写联系人在实际开发中,普通App很少会开放数据接口给其他应用访问。内容组件能够派上用场的情况往往是App想要访问系统应用的通讯数据,比如查看联系人,短信,通话记录等等,以及对这些通讯数据及逆行增删改查。首先要给AndroidMaifest.xml中添加响应的权限配置 下面是往手机通讯录添加联系人信息的例子效果如下分成三个步骤先查出联系人的基本信息,然后查询联系人号码,再查询联系人邮箱代码 ContactAddActivity类packagecom.example.chapter07;importandroid

  9. SpringCloud入门实战(七)-Hystrix入门简介 - 2

    📝学技术、更要掌握学习的方法,一起学习,让进步发生👩🏻作者:一只IT攻城狮。💐学习建议:1、养成习惯,学习java的任何一个技术,都可以先去官网先看看,更准确、更专业。💐学习建议:2、然后记住每个技术最关键的特性(通常一句话或者几个字),从主线入手,由浅入深学习。❤️《SpringCloud入门实战系列》解锁SpringCloud主流组件入门应用及关键特性。带你了解SpringCloud主流组件,是如何一战解决微服务诸多难题的。项目demo:源码地址👉🏻SpringCloud入门实战系列不迷路👈🏻:SpringCloud入门实战(一)什么是SpringCloud?SpringCloud入门实战

  10. BigData/Cloud Computing:基于阿里云技术产品的人工智能与大数据/云计算/分布式引擎的综合应用案例目录来理解技术交互流程 - 2

    BigData/CloudComputing:基于阿里云技术产品的人工智能与大数据/云计算/分布式引擎的综合应用案例目录来理解技术交互流程目录一、云计算网站建设:部署与发布网站建设:简单动态网站搭建云服务器管理维护云数据库管理与数据迁移云存储:对象存储管理与安全超大流量网站的负载均衡二、大数据MOOC网站日志分析搭建企业级数据分析平台基于LBS的热点店铺搜索基于机器学习PAI实现精细化营销基于机器学习的客户流失预警分析使用DataV制作实时销售数据可视化大屏使用MaxCompute进行数据质量核查使用Quick BI制作图形化报表使用时间序列分解模型预测商品销量三、云安全云平台使用安全云上服务

随机推荐