IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Mybatis中的关系映射 一对多 和多对多 -> 正文阅读

[游戏开发]Mybatis中的关系映射 一对多 和多对多

创建两张表格? ?player 和team??

?player表

CREATE TABLE `player` (
  `playerId` int NOT NULL,
  `playerName` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
  `playerNum` int DEFAULT NULL,
  `teamId` int DEFAULT NULL,
  PRIMARY KEY (`playerId`),
  KEY `teamId` (`teamId`),
  CONSTRAINT `player_ibfk_1` FOREIGN KEY (`teamId`) REFERENCES `team` (`teamId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

team表

CREATE TABLE `team` (
  `teamId` int NOT NULL AUTO_INCREMENT COMMENT '球队ID',
  `teamName` varchar(50) DEFAULT NULL COMMENT '球队名称',
  `location` varchar(50) DEFAULT NULL COMMENT '球队位置',
  `createTime` date DEFAULT NULL COMMENT '球队建立时间',
  PRIMARY KEY (`teamId`)
) ENGINE=InnoDB AUTO_INCREMENT=1013 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

插入数据如下

引出问题,mybatis如何进行多表连接查询

比如根据player表的teamId查询出所有球员的信息,在此情况下如何获取球员对于的球队信息?

1 对一关系的映射

实体类

public class Player {
private Integer playerId;
private String playerName;
private Integer playerNum;
private Integer teamId;
//多对一的体现:多方持有一方的对象 要有get方法
private Team team1;//关联对象--多个球员可以属于同一个球队;
private Team team2;//关联对象--多个球员可以属于同一个球队;
private Team team3;//关联对象--多个球员可以属于同一个球队;
//省略set get 和toString方法

}

mapper接口

public interface PlayerMapper {
      List<Player>  queryById1(int playerId);
    List<Player> queryById2(int playerId);
    List<Player> queryById3(int playerId);
}

对一映射方式1:通过关联对象打点调用属性的方式

??要求:两表的连接查询

 <select id="queryById1" resultMap="JoinTeamResult1">
        select * from player p inner join team t on p.teamId=t.teamId
        where t.teamId=#{id}
    </select>
    <resultMap id="baseResultMap" type="com.kkb.pojo.Player">
        <id column="playerId" property="playerId"></id>
        <result column="playerName" property="playerName"></result>
        <result column="playerNum" property="playerNum"></result>
        <result column="teamId" property="teamId"></result>
    </resultMap>
    <!-- 方式1:通过关联对象打点调用属性的方式
 要求:连接查询
 如果连接查询,一般单独定义resultMap
 extends="表示继承的其他的resultMap的id"
 -->
    <resultMap id="JoinTeamResult1" type="com.kkb.pojo.Player" extends="baseResultMap">
        <id column="teamId" property="team1.teamId"></id>
        <result column="teamName" property="team1.teamName"></result>
        <result column="location" property="team1.location"></result>
        <result column="teamName" property="team1.teamName"></result>
        <result column="createTime" property="team1.createTime"></result>
    </resultMap>

测试类

package com.kkb.test;

import com.kkb.mapper.PlayerMapper;
import com.kkb.pojo.Player;
import com.kkb.utils.MybatisUtil;
import org.junit.Test;

import java.util.List;

public class PlayerTest {
     private PlayerMapper playerMapper = MybatisUtil.getSqlSession().getMapper(PlayerMapper.class);

  
     @Test
    public  void test01(){
         List<Player> players = playerMapper.queryById1(1005);
         for (Player player : players) {
             System.out.println(player);
         }
     }

    @Test
    public void test02(){
        Player player = playerMapper.queryById2(1005);
         for (Player player : players) {
             System.out.println(player);
         }
}
    @Test
    public void test03(){
    Player player = playerMapper.queryById3(1005);
     for (Player player : players) {
             System.out.println(player);
         }
    }


}

?对一映射方式2:直接引用关联对象的Mapper映射

要求:

1、两表的连接查询
2、关联对象中已经存在被引用的resultMap

<select id="queryById2" resultMap="JoinTeamResult2">
        select * from player p inner join team t on p.teamId=t.teamId
        where t.teamId=#{id}
    </select>
<!--方式2:直接引用关联对象的Mapper映射:要求连接查询
property="关联对象的属性名"
javaType="关联对象的类型"
resultMap="关联对象的命名空间中的resultMap"
-->
<resultMap id="JoinTeamResult2" type="com.kkb.pojo.Player" extends="baseResultMap">
<association property="team2" javaType="com.kkb.pojo.Team"
resultMap="com.kkb.mapper.TeamMapper.baseResultMap"></association>
</resultMap>

?teamMapper.xml中的baseResultMap??

 <resultMap id="baseResultMap" type="com.kkb.pojo.Team">
        <id column="teamId" property="teamId"  javaType="int"></id>
        <result column="teamName" property="teamName"  javaType="string"></result>
        <result column="location" property="location"  javaType="string"></result>
        <result column="createTime" property="createTime"  javaType="date"></result>
    </resultMap>

测试结果:

?

对一映射方式3:直接引用关联对象的单独查询的方法

要求:

1、不需要两表的连接查询
2、关联对象中已经存在被引用的查询方法(接口类中的方法)

就是分两步查先根据playerId查询出来的信息,再根据association标签中column属性指定第二次查询的列作为条件进行二次查询。

<select id="queryById3" resultMap="JoinTeamResult3">
    select * from player where teamId=#{id}
</select>

 <resultMap id="baseResultMap" type="com.kkb.pojo.Player">
        <id column="playerId" property="playerId"></id>
        <result column="playerName" property="playerName"></result>
        <result column="playerNum" property="playerNum"></result>
        <result column="teamId" property="teamId"></result>
    </resultMap>

<!--方式3:直接引用关联对象的单独查询的方法:要求:关联对象的Maper中必须要求有单独的查询方法
property="关联对象的属性名"
javaType="关联对象的类型"
select="关联对象的单独查询的语句"
column="外键列"
-->
<resultMap id="JoinTeamResult3" type="Player" extends="baseResultMap">
    <association property="team3" javaType="Team"
    select="com.kkb.mapper.TeamMapper.queryById" column="teamId"></association>
  </resultMap>

teamMapper接口中对应的方法。?

  Team queryById(Integer teamId);

teamMapper.xml中的方法查询语句?

  <select id="queryById" parameterType="int" resultType="com.kkb.pojo.Team">

    select * from team where teamId=#{id}
</select>

测试结果:

?可以看到进行了两次查询

总结

开发中常用到第二种和第三种方式,其实第三种方式就是分两次查询,这一点也可以在service层次做到。

?对多关系的映射

修改实体类Team.java:

public class Team {
    private Integer teamId;
    private String teamName;
    private String location;
    private Date createTime;
    //一对多的体现:一方持有多方的对象  分两种方法介绍
    private List<Player> playerList1;//关联对象--一个球队可以拥有多个球员
    private List<Player> playerList2;//关联对象--一个球队可以拥有多个球员

    //get  和set  方法  toString方法自行补充
}

TeamMapper.java接口中添加方法:

public interface TeamMapper {
    Team queryById1(int teamId);
    Team queryById2(int teamId);
}

PlayerMapper.java接口中添加方法:? 第二种方法要用到

public interface PlayerMapper {    
    List<Player> queryByTeamId(int teamId);
}

PlayerMapper.xml添加如下内容:

<select id="queryByTeamId" resultType="Player">
    select * from player where teamId=#{id}
</select>

方式1:连接查询+引用关联对象的结果映射

一步查询? 需要inner join进行连接查询

?方式2:引用关联对象的单独查询的方法

分两部查询? ?需要引用的其他类的方法进行二次查询

TeamMapper.xml添加

<select id="queryById1" resultMap="joinResult1">
    select * from team t join player p
    on t.teamId=p.teamId where t.teamId=#{id};
</select>
<select id="queryById2" resultMap="joinResult2">
    select * from team where teamId=#{id};
</select>
<!--方式1:
对多的连接查询:对多使用collection
property="关联对象的集合名称"
javaType="关联对象的集合类型"
ofType="关联对象的集合的泛型"
resultMap="引用关联对象的结果映射"
-->
<resultMap id="joinResult1" type="Team" extends="baseResultMap">
    <collection property="playerList1" javaType="java.util.ArrayList" ofType="Player"
    resultMap="com.kkb.mapper.PlayerMapper.baseResultMap"></collection>
</resultMap>
<!--方式2:
对多的连接查询:对多使用collection
property="关联对象的集合名称"
javaType="关联对象的集合类型"
ofType="关联对象的集合的泛型"
select="引用关联对象的单独查询的方法":使用的前提是关联对象中该方法可用
column="引用关联对象的单独查询的方法的参数,一般是外键"
-->
<resultMap id="joinResult2" type="Team" extends="baseResultMap">
    <collection property="playerList2" javaType="java.util.ArrayList"
    select="com.kkb.mapper.PlayerMapper.queryByTeamId" column="teamId"></collection>
</resultMap>

测试:

public class TestPlayerMapper {
TeamMapper teamMapper=MybatisUtil.getSqlSession().getMapper(TeamMapper.class);
     /**
     * 多关系查询   连接查询
     */
    @Test
    public void test04() {
        Team team = teamMapper.queryById1(1005);
        System.out.println(team);
        List<Player> playerList1 = team.getPlayerList1();
        for (Player player : playerList1) {
            System.out.println(player);
        }
    }

    /**
     * 多关系查询    两次查询
     */
    @Test
    public void test05() {
        Team team = teamMapper.queryById2(1003);
        System.out.println(team);
        List<Player> playerList2 = team.getPlayerList2();
        for (int i = 0; i < playerList2.size(); i++) {
            System.out.println(playerList2.get(i));
        }
    }
   
}

测试结果:

tset04

?tset05

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-03-24 00:54:10  更:2022-03-24 00:56:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 20:38:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码