百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

MyBatis关联 查询之多对多查询(mybatisplus多对多查询)

bigegpt 2024-08-01 11:49 4 浏览

一对一查询、 一对多查询两篇文章分别讲了关联查询中的一对一查询和一对多查询,假设有两个表A和B,那么一对一就是A表中的每行记录仅对应B表的一条记录,同理B表的一条记录只对应A表的一条记录;一对多则是A表中的单行可以与B表中的一个或多个行相关,但B表中的一个行只可以与A表中的一个行相关;那么多对多则是A表中的单行可以与B表中的一个或多个行相关,B表中的单行可以与A表中的一个或多个行相关。本文通过举例子的方式进行介绍多对多的情况。

1.案例准备

本文的例子采用人借书(一对多),书分种类(多对多),种类对应种类名字(一对一)的复杂关系来讲解多对多的关系。涉及的表分别命名为user、book、booktype、type。首先在MySQL上进行建表。

1.建立第一个表示借书者的表,即user,代码即数据如下图所示:

2.建立book表:

3.建立booktype表:

4.建立type表:

5.根据需要实现的要求,进行sql查询,代码如下:


  1. select user.id user_id,user.name user_name,book.id book_id,book.name book_name,booktype.type typeid,type.name type_name
  2. from book,booktype,user,type
  3. where user.id=book.user_id
  4. and book.id=booktype.book_id
  5. and booktype.type=type.id;

查询结果如下图所示:

2.使用MyBatis框架关联查询

1.根据数据表以及表之间的关联建立相应的实体类

1.User1类,每一个user可以借多本书,因此在User1类中添加集合属性List<Book1> book,其余属性与数据表对应即可。


  1. package com.mybatis.model.impl;
  2. import java.util.*;
  3. import java.io.Serializable;
  4. public class User1 {
  5. public Integer id;
  6. public String name;
  7. public List<Book1> book;//借的书本
  8. public Integer getId()
  9. {
  10. return this.id;
  11. }
  12. public void setId(Integer id)
  13. {
  14. this.id=id;
  15. }
  16. public String getName()
  17. {
  18. return this.name;
  19. }
  20. public void setName(String name)
  21. {
  22. this.name=name;
  23. }
  24. public List<Book1> getBook()
  25. {
  26. return this.book;
  27. }
  28. public void setBook(List<Book1> book)
  29. {
  30. this.book=book;
  31. }
  32. public String toString()
  33. {
  34. return "User [user_id="+id+",name="+name+",book="+book+"]";
  35. }
  36. }

2.建立一个Book1类,这里每一本书可以有多个种类,添加集合属性List<BookType>bookType来表示两者的关联。


  1. package com.mybatis.model.impl;
  2. import java.util.*;
  3. public class Book1 {
  4. public Integer id;
  5. public String user_id;
  6. public String name;
  7. public List<BookType> bookType;//书划分种类的集合,一本书可以被划分为好几种类,
  8. public Integer getBook_id()
  9. {
  10. return this.id;
  11. }
  12. public void setBook_id(Integer id)
  13. {
  14. this.id=id;
  15. }
  16. public String getUser_id()
  17. {
  18. return this.user_id;
  19. }
  20. public void setUser_id(String user_id)
  21. {
  22. this.user_id=user_id;
  23. }
  24. public String getBook_name()
  25. {
  26. return this.name;
  27. }
  28. public void setBook_name(String name)
  29. {
  30. this.name=name;
  31. }
  32. public List<BookType> getBookType()
  33. {
  34. return this.bookType;
  35. }
  36. public void setUser(List<BookType> bookType)
  37. {
  38. this.bookType=bookType;
  39. }
  40. public String toString()
  41. {
  42. return "Book [book_id="+id+",user_id="+user_id+",book_name="+name+",bookType="+bookType+"]";
  43. }
  44. }

3.建立BookType类,这里需要添加一个关联对象属性types,即typeid属性与type对象对应


  1. package com.mybatis.model.impl;
  2. public class BookType {
  3. public Integer id;
  4. public String book_id;
  5. public Integer type;
  6. public Type types;
  7. public Integer getId()
  8. {
  9. return this.id;
  10. }
  11. public void setId(Integer id)
  12. {
  13. this.id=id;
  14. }
  15. public String getBook_id()
  16. {
  17. return this.book_id;
  18. }
  19. public void setBook_id(String book_id)
  20. {
  21. this.book_id=book_id;
  22. }
  23. public Integer getType()
  24. {
  25. return this.type;
  26. }
  27. public void setTypeid(Integer type)
  28. {
  29. this.type=type;
  30. }
  31. public Type getTypes()
  32. {
  33. return this.types;
  34. }
  35. public void setTypes(Type types)
  36. {
  37. this.types=types;
  38. }
  39. public String toString()
  40. {
  41. return "BookType [book_id="+book_id+",type_id="+type+",typename="+types.getName()+"]";
  42. }
  43. }

4.建立Type类


  1. package com.mybatis.model.impl;
  2. public class Type {
  3. public Integer id;
  4. public String name;
  5. public Integer getId()
  6. {
  7. return this.id;
  8. }
  9. public void setId(Integer id)
  10. {
  11. this.id=id;
  12. }
  13. public String getName()
  14. {
  15. return this.name;
  16. }
  17. public void setName(String name)
  18. {
  19. this.name=name;
  20. }
  21. }

2.建立mapper接口

这里暂时只需要查询每个人对应的书及其种类的关系,因此一个方法即可搞定。接口定义如下:


  1. package com.mybatis.mapper;
  2. import java.util.*;
  3. import com.mybatis.model.impl.*;
  4. public interface BookOfUserMapper {
  5. public List<User1> getInfo();
  6. }

3.mapper文件


  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.mybatis.mapper.BookOfUserMapper">
  6. <select id="getInfo" resultMap="user1">
  7. select user.id user_id,user.name,book.id book_id,book.name book_name,booktype.type typeid,type.name type_name
  8. from book,booktype,user,type
  9. where user.id=book.user_id
  10. and book.id=booktype.book_id
  11. and booktype.type=type.id;
  12. </select>
  13. <resultMap type="com.mybatis.model.impl.User1" id="user1">
  14. <id property="id" column="user_id"/>
  15. <result property="name" column="user_name"/>
  16. <collection property="book" ofType="com.mybatis.model.impl.Book1">
  17. <id property="id" column="book_id"/>
  18. <result property="name" column="book_name"/>
  19. <collection property="bookType" ofType="com.mybatis.model.impl.BookType">
  20. <id property="book_id" column="book_id"/>
  21. <result property="type" column="typeid"/>
  22. <association property="types" javaType="com.mybatis.model.impl.Type">
  23. <id property="id" column="typeid"/>
  24. <result property="name" column="type_name"/>
  25. </association>
  26. </collection>
  27. </collection>
  28. </resultMap>
  29. </mapper>

上述mapper文件需要注意的是collection的填写,需要看其属性的层次,比如book是user的集合属性,是最外层的,而book中有个booktype集合属性,那么需要在外围的<collection...>元素中嵌套一个<collection元素>,又因为在内层collection中有一个关联对象type,则需要在内层<collection>元素中嵌套一个<association...>元素。注意嵌套与属性映射的关系。另外每个属性对应的column值则需要与sql查询语句中查询结果对应的列名相等。通过这个mapper文件,就相当于将整个复杂的表之间的关系全部映射到了User1对象中。

4.mybatis配置文件

将相应的mapper文件加载进去即可:


  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE configuration
  3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-config.dtd">
  5. <!-- XML配置文件包含对MyBatis系统的核心设置 -->
  6. <configuration>
  7. <!-- 指定MyBatis所用日志的具体实现 -->
  8. <settings>
  9. <setting name="logImpl" value="LOG4J"/>
  10. <setting name="cacheEnabled" value="false"/>
  11. </settings>
  12. <environments default="development">
  13. <environment id="development">
  14. <transactionManager type="JDBC">
  15. </transactionManager>
  16. <dataSource type="POOLED">
  17. <property name="driver" value="org.gjt.mm.mysql.Driver"/>
  18. <property name="url" value="jdbc:mysql://localhost:3306/mybatisquery?characterEncoding=UTF-8"/>
  19. <property name="username" value="root"/>
  20. <property name="password" value="root"/>
  21. </dataSource>
  22. </environment>
  23. </environments>
  24. <mappers>
  25. <mapper resource="mapper/BookOfUserMapper.xml"/>
  26. </mappers>
  27. </configuration>

5.测试

测试程序如下:


  1. package com.mybatis.test;
  2. import java.util.*;
  3. import java.io.InputStream;
  4. import org.apache.ibatis.io.*;
  5. import org.apache.ibatis.session.*;
  6. import com.mybatis.mapper.*;
  7. import com.mybatis.model.impl.*;;
  8. public class QueryTest {
  9. public static void main(String[] args) throws Exception {
  10. // TODO Auto-generated method stub
  11. // TODO Auto-generated method stub
  12. //读取MyBatis配置文件
  13. InputStream inputStream=Resources.getResourceAsStream("mybatis-config.xml");
  14. //初始化mybatis,创建SqlSessionFactory类的实例。
  15. SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
  16. //创建Session实例
  17. SqlSession session=sqlSessionFactory.openSession();
  18. BookOfUserMapper bookOfUserMapper=session.getMapper(BookOfUserMapper.class);
  19. List<User1> list3=bookOfUserMapper.getInfo();
  20. System.out.println(list3);
  21. }
  22. }

运行程序,结果如下:


  1. DEBUG [main] - <== Total: 10
  2. [User [user_id=1001,name=null,book=[Book [book_id=2001,user_id=null,book_name=算法导论,bookType=[BookType [book_id=2001,type_id=2,typename=算法]]], Book [book_id=2002,user_id=null,book_name=西游记,bookType=[BookType [book_id=2002,type_id=1,typename=名著]]]]], User [user_id=1002,name=null,book=[Book [book_id=2003,user_id=null,book_name=设计模式,bookType=[BookType [book_id=2003,type_id=2,typename=算法]]], Book [book_id=2004,user_id=null,book_name=编程思想,bookType=[BookType [book_id=2004,type_id=2,typename=算法]]]]], User [user_id=1003,name=null,book=[Book [book_id=2005,user_id=null,book_name=MySQL,bookType=[BookType [book_id=2005,type_id=2,typename=算法]]]]]]

该运行结果以集合的形式保存的,仔细查看会发现该结果与之前在sql中查询的结果一致。

6.实例文件结构

相关推荐

得物可观测平台架构升级:基于GreptimeDB的全新监控体系实践

一、摘要在前端可观测分析场景中,需要实时观测并处理多地、多环境的运行情况,以保障Web应用和移动端的可用性与性能。传统方案往往依赖代理Agent→消息队列→流计算引擎→OLAP存储...

warm-flow新春版:网关直连和流程图重构

本期主要解决了网关直连和流程图重构,可以自此之后可支持各种复杂的网关混合、多网关直连使用。-新增Ruoyi-Vue-Plus优秀开源集成案例更新日志[feat]导入、导出和保存等新增json格式支持...

扣子空间体验报告

在数字化时代,智能工具的应用正不断拓展到我们工作和生活的各个角落。从任务规划到项目执行,再到任务管理,作者深入探讨了这款工具在不同场景下的表现和潜力。通过具体的应用实例,文章展示了扣子空间如何帮助用户...

spider-flow:开源的可视化方式定义爬虫方案

spider-flow简介spider-flow是一个爬虫平台,以可视化推拽方式定义爬取流程,无需代码即可实现一个爬虫服务。spider-flow特性支持css选择器、正则提取支持JSON/XML格式...

solon-flow 你好世界!

solon-flow是一个基础级的流处理引擎(可用于业务规则、决策处理、计算编排、流程审批等......)。提供有“开放式”驱动定制支持,像jdbc有mysql或pgsql等驱动,可...

新一代开源爬虫平台:SpiderFlow

SpiderFlow:新一代爬虫平台,以图形化方式定义爬虫流程,不写代码即可完成爬虫。-精选真开源,释放新价值。概览Spider-Flow是一个开源的、面向所有用户的Web端爬虫构建平台,它使用Ja...

通过 SQL 训练机器学习模型的引擎

关注薪资待遇的同学应该知道,机器学习相关的岗位工资普遍偏高啊。同时随着各种通用机器学习框架的出现,机器学习的门槛也在逐渐降低,训练一个简单的机器学习模型变得不那么难。但是不得不承认对于一些数据相关的工...

鼠须管输入法rime for Mac

鼠须管输入法forMac是一款十分新颖的跨平台输入法软件,全名是中州韵输入法引擎,鼠须管输入法mac版不仅仅是一个输入法,而是一个输入法算法框架。Rime的基础架构十分精良,一套算法支持了拼音、...

Go语言 1.20 版本正式发布:新版详细介绍

Go1.20简介最新的Go版本1.20在Go1.19发布六个月后发布。它的大部分更改都在工具链、运行时和库的实现中。一如既往,该版本保持了Go1的兼容性承诺。我们期望几乎所...

iOS 10平台SpriteKit新特性之Tile Maps(上)

简介苹果公司在WWDC2016大会上向人们展示了一大批新的好东西。其中之一就是SpriteKitTileEditor。这款工具易于上手,而且看起来速度特别快。在本教程中,你将了解关于TileE...

程序员简历例句—范例Java、Python、C++模板

个人简介通用简介:有良好的代码风格,通过添加注释提高代码可读性,注重代码质量,研读过XXX,XXX等多个开源项目源码从而学习增强代码的健壮性与扩展性。具备良好的代码编程习惯及文档编写能力,参与多个高...

Telerik UI for iOS Q3 2015正式发布

近日,TelerikUIforiOS正式发布了Q32015。新版本新增对XCode7、Swift2.0和iOS9的支持,同时还新增了对数轴、不连续的日期时间轴等;改进TKDataPoin...

ios使用ijkplayer+nginx进行视频直播

上两节,我们讲到使用nginx和ngixn的rtmp模块搭建直播的服务器,接着我们讲解了在Android使用ijkplayer来作为我们的视频直播播放器,整个过程中,需要注意的就是ijlplayer编...

IOS技术分享|iOS快速生成开发文档(一)

前言对于开发人员而言,文档的作用不言而喻。文档不仅可以提高软件开发效率,还能便于以后的软件开发、使用和维护。本文主要讲述Objective-C快速生成开发文档工具appledoc。简介apple...

macOS下配置VS Code C++开发环境

本文介绍在苹果macOS操作系统下,配置VisualStudioCode的C/C++开发环境的过程,本环境使用Clang/LLVM编译器和调试器。一、前置条件本文默认前置条件是,您的开发设备已...