• 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}]}
    

    可以思考一下,如果这里需要打印账号信息,你可以尝试一下能否自己独立搞定。

    作者:Binge
    本文版权归作者和博客园共有,转载必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
  • 相关阅读:
    2020.10.6 提高组模拟
    GMOJ 6815. 【2020.10.06提高组模拟】树的重心
    Codeforces Round #542 [Alex Lopashev Thanks-Round] (Div. 1) D. Isolation
    Forethought Future Cup
    Codeforces Round #543 (Div. 2, based on Technocup 2019 Final Round) D. Diana and Liana
    2020.10.07提高组模拟
    2020.10.05提高组模拟
    9.29 联赛组作业
    JZOJ 3978. 寝室管理
    Centos7下安装netstat的方法
  • 原文地址:https://www.cnblogs.com/binbingg/p/13786801.html
Copyright © 2020-2023  润新知