MyBatis 高级查询之多对多查询(十一)
高级查询之多对多查询
查询条件:根据玩家名,查询游戏信息
我们在之前创建的映射器接口 GameMapper.java 中添加接口方法,如下:
/**
* 根据玩家名查询游戏
* @param name 玩家名
* @return 玩家实体类
*/
public PlayerEntity selectPlayerByName(String name);
接下来,我分别演示关联查询和子查询方式实现接口方法的映射。
关联查询方式
现在我们暂时先抛开 MyBatis 框架,直接从数据库出发写一写关联查询的 SQL 语句,如下:
select p.*,g.* from tb_player as p join tb_player_game as p_g on p.id = p_g.player_id join tb_game as g on g.id = p_g.game_id where p.name = '张三'
这条 SQL 语句有点长,涉及三表关联查询,因为多对多相比一对多而言,多了一张中间表哈。
我们在数据库中执行这条 SQL 语句,结果如下:

现在,我们回到 MyBatis 框架,看一下在 XML 映射文件中,如何实现关联查询映射。
首先,我们需要建立 PlayerEntity 实体类 与 GameEntity 实体类之间的关联关系,如下:
public class PlayerEntity {
private int id;
private String name;
private int age;
private int sex;
private List<GameEntity> games;
}
这样,通过玩家名查询的游戏信息就可以映射到 games 属性中。对了,set 和 get 方法以及 toString 方法自己补上哈。
现在,我们来编写映射文件中 SQL 语句映射,如下:
<?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="mapper.GameMapper">
<resultMap id="playerResultMap" type="entity.PlayerEntity">
<id property="id" column="id" />
<result property="name" column="name" />
<result property="age" column="age" />
<result property="sex" column="sex" />
<collection property="games" ofType="entity.GameEntity">
<id property="id" column="id" />
<result property="name" column="name" />
<result property="type" column="type" />
<result property="operator" column="operator" />
</collection>
</resultMap>
<select id="selectPlayerByName" resultMap="playerResultMap" >
select p.*,g.* from tb_player as p
join tb_player_game as p_g on p.id = p_g.player_id
join tb_game as g on g.id = p_g.game_id where p.name = #{name}
</select>
</mapper>
除了三表关联查询,其他和一对多关联映射差不多。
最后,我们在 MyBatisTest 中添加一个单元测试方法,如下:
@Test
public void selectPlayerByNameTest() {
PlayerEntity playerEntity = gameMapper.selectPlayerByName("张三");
System.out.println(playerEntity);
Assert.assertNotNull(playerEntity);
}
执行测试,结果如下:
2020-07-16 21:57:18,545 [main] [mapper.GameMapper.selectPlayerByName]-[DEBUG] ==> Preparing: select p.*,g.* from tb_player as p join tb_player_game as p_g on p.id = p_g.player_id join tb_game as g on g.id = p_g.game_id where p.name = ?
2020-07-16 21:57:18,623 [main] [mapper.GameMapper.selectPlayerByName]-[DEBUG] ==> Parameters: 张三(String)
2020-07-16 21:57:18,669 [main] [mapper.GameMapper.selectPlayerByName]-[DEBUG] <== Total: 2
PlayerEntity{id=1, name='张三', age=23, sex=1, games=[GameEntity{id=1, name='英雄联盟', type='MOBA', operator='腾讯游戏', accounts=null}, GameEntity{id=2, name='绝地求生', type='TPS', operator='蓝洞游戏', accounts=null}]}
可以思考一下,如果这里需要打印账号信息,你可以尝试一下能否自己独立搞定。
MyBatis 高级查询之多对多查询(十一)的更多相关文章
- Mybatis 多表实现多对多查询、添加操作
Mybatis 多表实现多对多查询.添加操作 学习内容: 1. 多对多之添加操作 1.1.需求 1.2.数据库表(多对多数据库设计需要设计中间表) 1.3.类设计 1.4.Mapper 接口和 Map ...
- Mybatis 多表实现多对一查询、添加操作
Mybatis 多表实现多对一查询.添加操作 学习内容: 1. 多对一之添加操作 1.1.需求 1.2.数据库表(多对一或一对多,数据库外键都是设置在多的一方) 1.3.类设计 1.4.Mapper ...
- mybatis由浅入深day02_4多对多查询_多对多查询总结
4 多对多查询 4.1 需求(查询用户及用户购买商品信息) 查询用户及用户购买商品信息. 4.2 sql语句 查询主表是:用户表 关联表:由于用户和商品没有直接关联,通过订单和订单明细进行关联,所以关 ...
- flask的orm框架(SQLAlchemy)-一对多查询以及多对多查询
一对多,多对多是什么? 一对多.例如,班级与学生,一个班级对应多个学生,或者多个学生对应一个班级. 多对多.例如,学生与课程,可以有多个学生修同一门课,同时,一门课也有很多学生. 一对多查询 如果一个 ...
- 基于对象的跨表查询,多对多查询,多对多操作,聚合查询和分组查询,F查询和Q 查询
基于对象的跨表查询 一对多查询(班级表和学生表) 表结构创建 class Class(models.Model): id = models.AutoField(primary_key=True) cn ...
- 【MyBatis学习10】高级映射之多对多查询
本文来总结一下mybatis中的多对多映射,从第8节的文章中可以看出,用户表和商品表示多对多关系,它们两的多对多是通过订单项和订单明细这两张表所关联起来的,那么这一节主要来总结一下用户表和商品表之间的 ...
- mybatis级联查询,多对一查询问题
在使用Mybatis进行多表级联查询时遇到了一个问题:查询结果只有一项,但正确结果是两项.经测试,SQL语句本身没有问题. 在SQL映射文件(XML)中: <!-- 级联查询数据 --> ...
- mybatis(一、原理,一对多,多对一查询)
MyBatis框架及原理分析 MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架,其主要就完成2件事情: 封装JDBC操作 利用反射打通Java类与SQL语句之间的相互转换 ...
- mybatis 一对多和多对一关联查询
首先 数据库量表之间字段关系(没有主外键) studentmajor表的id字段对应student表里major字段 两个实体类 package com.model; import java.uti ...
随机推荐
- 【笔记】《Redis设计与实现》chapter2 简单动态字符串
------------恢复内容开始------------ 2.1 SDS的定义 struct sdshdr{ // 记录buf数组中已使用字节的数量 // 等于SDS所保存字符串的长度(不含'\0 ...
- Day14_82_反射机制输出整个类
利用反射机制输出整个类 代码实例 import java.lang.reflect.Field; import java.lang.reflect.Modifier; public class Ref ...
- 数据结构(3):java使用数组模拟堆栈
堆栈原理: 数组模拟堆栈: //数组模拟栈 class ArrayStack{ //栈顶 private int top = -1; private int maxSize; private int[ ...
- 【Java】String、StringBuilder和StringBuffer
[String] 首先,从String类的定义入手,可以看到String类是由final修饰,即不可变的,一旦创建出来就不可修改,因此首先明确,字符串的拼接.截取等操作都会产生新的字符串对象. 观察以 ...
- 1.8.8- textarea控件(文本域)
如果需要大量的信息,就需要用到<textarea>标签,通过testarea控件可以轻松创建多行文本输入框,其基本语法如下: <textarea cols="每行的字数&q ...
- SQL优化-大数据量分页优化
百万数据量SQL,在进行分页查询时会出现性能问题,例如我们使用PageHelper时,由于分页查询时,PageHelper会拦截查询的语句会进行两个步骤 1.添加 select count(*)fro ...
- 基于防火墙的VRRP技术--华为防火墙双机热备--VGMP
目录 主备备份双机热备配置 负载分担双机热备配置 为了解决多个VRRP备份组状态不一致的问题,华为防火墙引入VGMP(VRRP Group Management Protocol)来实现对VRRP备份 ...
- Windows核心编程 第25章 未处理异常和C ++异常(下)
这一节东西比较少,本应该归并在上一节里,但是昨天太晚了.就先把那些东西分为上了.这节里面就一个问题,C++异常与结构性异常的对比(try和__try的区别): C++异常与结构性异常的对比 S E H ...
- 续订Jetbrain学生包
今天打开IDEA和Pycharm都不约而同的告诉我我的账号无法使用学生包了 此刻我的内心是: 冷静下来我算了算,嗷,原来是一年的订阅期到了,那就简单了,直接续订吧,唉.其实续订和重新认证是一样的. 首 ...
- layui处理表单/按钮进行多次提交
在一个项目中,我们最频繁的操作是CRUD,所以一定有涉及到按钮的操作.比如:确认保存,确认编辑,确认删除等等.所以,为了避免表单进行多次提交就显得特别地重要. 代码实现 知识点 $(':button' ...