请选择 进入手机版 | 继续访问电脑版

Mybatis 复杂查询(多对多、一对多、多对一)

[复制链接]
滚雪球少年 发表于 2020-12-31 18:58:15 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题
  我们知道,在 Mybatis 中完成单表查询是很容易的,而多表查询是 Mybatis 框架中的一个重难点,需熟练掌握。

   文章目次

  
  
1、多对多查询

用户和小组为多对多的关系,需求为:通过用户 id 查找其所有的小组信息
数据库设计如下:

实体类:
  1. public class User {    private int uId;    private String uName;    private List groupList;
复制代码
一个 User 对应多个 Group ,用一个 List 存储
  1. public class Group {    private int gId;    private String gName;    private List userList;
复制代码
一个 User 对应多个 User,用一个 List 存储
  1. public class UserGroup {    private User user;    private Group group;
复制代码
中间表包罗两个对象
实现需求:通过用户 id 查找其所有的小组信息
UserMapper 接口:
  1. public interface UserMapper {    List getGroupByUId(int uId);}
复制代码
UserMapper.xml:
  1.             select u.uId, u.uName, g.gId, g.gName        from `user` u,`group` g, uesr_group ug        where g.gId = ug.gId and ug.uId = #{uId} and u.uId = #{uId};                                                                    
复制代码
由于需查询所有 Group 的信息,该方法返回 Group 聚集
这里的 resutMap 范例为中间表实体对象 UserGroup ,它将两个表接洽在一起
实在通过 collection 来处置处罚聚集对象的属性映射
数据库表测试数据:

查询效果(查找用户 id 为1的所有小组信息):

可以看到,小组信息以及用户信息都已经被正确地查询出来
2、 一对多查询

增加 Account 表,一个用户对应多个 Account
需求:查询指定用户所有的账户
数据库测试数据:

写法 1

实体类:
  1. public class User {    private int uId;    private String uName;    private List groupList;    private List accountList;
复制代码
一个 User 对应多个 Account,用一个 List 存储
  1. public class Account {    private int aId;    private String aName;    private User user;
复制代码
一个 Account 对应一个 User 对象
UserMapper 接口:
  1. public interface UserMapper {    List getGroupByUId(int uId);    List getAccountByUId(int uId);}
复制代码
UserMapper 实现:
  1.             select a.aId, a.aName, u.uId, u.uName        from user u, account a        where u.uId = a.uId and u.uId = #{uId};                                                                    
复制代码
查询效果:

写法1 以 Account(多的一方) 作为主表,即 resultMap 的范例为 Account,由于一个 Account 只对应一个 User,
所以在 resultMap 中 接纳 assocation 引入 User,从而实现多表查询。
这种写法的特点在于效果有多行记载,将 Account 的属性直接列出,而聚集中则为重复的 user 信息
写法 2

实体类:
  1. public class User {    private int uId;    private String uName;    private List groupList;    private List accountList;
复制代码
  1. public class Account {    private int aId;    private String aName;    private int uId;
复制代码
UserMapper 接口:
  1. public interface UserMapper {    List getGroupByUId(int uId);    List getAccountByUId(int uId);    User getUserByUId(int uId);}
复制代码
该方法是通过返回 User(一对多中一的一方) ,在 User 中通过 collection 引入 Account 关联
UserMapper.xml 实现:
  1.             select a.aId, a.aName, u.uId, u.uName        from user u, account a        where u.uId = a.uId and u.uId = #{uId};                                                                    
复制代码
测试效果:

写法2 以 User 作为主表,即 resultMap 的范例为 User,
由于一个 User 对应多个 Account,所以在 resultMap 中 接纳 collectiion 引入 Account ,从而实现多表查询。
这种写法的特点在于效果只有一行记载,将 user 的属性直接列出,而聚集中则为的 Account 信息。
3、多对一查询

需求:查询给定账户对应的用户
方式 1

实体类:
  1. public class User {    private int uId;    private String uName;    private List groupList;    private List accountList;
复制代码
  1. public class Account {    private int aId;    private String aName;    private int uId;
复制代码
AccountMapper 接口:
  1. public interface AccountMapper {    User getUserByAId(int aId);}
复制代码
这里返回 User(多对一中一的一方),在 User 中通过 collection 引入 Account
AccountMapper.xml 实现:
  1.             select u.uId, u.uName, a.aId, a.aName        from user u, account a        where u.uId = a.uId and a.aId = #{aId}                                                                    
复制代码
查询效果:

方式 2

实体类:
  1. public class User {    private int uId;    private String uName;    private List groupList;    private List accountList;
复制代码
  1. public class Account {    private int aId;    private String aName;    private User user;
复制代码
AccountMapper 接口:
  1. public interface AccountMapper {    Account getAccountAndUser(int aId);}
复制代码
该方法返回 Account(多的一方),在 resultMap 中通过 association 引入 User 关联
AccountMapper.xml 实现:
  1.             select u.uId, u.uName, a.aId, a.aName        from user u, account a        where u.uId = a.uId and a.aId = #{aId}                                                                    
复制代码
测试效果:

4、总结

首先,我们要需界说好实体类的属性以及 dao 的接口
如果映射的对象只有1个,接纳 assocation + javaType,如果映射的对象为一个聚集 List,则接纳 connection + ofType
result 标签为效果集映射关系, column 对应数据库中的列名,property 对应实体类的属性名
resultMap 的范例可以选择一对多中多的一方或一的一方,,指定好其范例后,接纳 assocation + javaType 或 connection + ofType 界说好对象关联映射即可。

来源:https://blog.csdn.net/qq_45716120/article/details/111942290
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


专注素材教程免费分享
全国免费热线电话

18768367769

周一至周日9:00-23:00

反馈建议

27428564@qq.com 在线QQ咨询

扫描二维码关注我们

Powered by Discuz! X3.4© 2001-2013 Comsenz Inc.( 蜀ICP备2021001884号-1 )