MyBatis 高级查询环境准备(八)
MyBatis 高级查询
之前在学习 Mapper XML 映射文件时,说到 resultMap 标记是 MyBatis 中最重要最强大也是最复杂的标记,而且还提到后面会详细介绍它的高级用法。
听到高级用法不要觉得有多高级,说白了就是联表查询。
MyBatis 支持四种联表查询方式:
-
一对一联表查询
-
一对多联表查询
-
多对一联表查询
-
多对多联表查询
联表查询需要用到 resultMap 标记两个子标记:
- association 标记:用于映射关联查询单个对象的信息
- collection 标记:用于映射关联查询多个对象的信息
环境准备
创建数据库表
为了演示高级查询,我准备了四张表,想必大家都喜欢玩游戏,那么这四张表和游戏有关,分别是:
- 玩家表(tb_player)
- 游戏表(tb_game)
- 账号表(tb_account)
- 角色表(tb_role)
简单分析一下这四张表的关系如下:
- 玩家表->游戏表:多对多(一个玩家有多个游戏,一个游戏有多个玩家)
- 游戏表->账号表:一对多(一个游戏有多个账号,一个账号有一个游戏)
- 账号表->游戏表:多对一(一个游戏有多个账号,一个账号有一个游戏)
- 账号表->角色表:一对一(一个账号有一个角色,一个角色有一个账号)
编写 SQL 语句分别创建四张表,如下:
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `tb_account`
-- ----------------------------
DROP TABLE IF EXISTS `tb_account`;
CREATE TABLE `tb_account` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_name` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
`game_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `game_id` (`game_id`) USING BTREE,
CONSTRAINT `tb_account_ibfk_1` FOREIGN KEY (`game_id`) REFERENCES `tb_game` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of tb_account
-- ----------------------------
INSERT INTO `tb_account` VALUES ('1', '潇洒哥', '12345', '1');
INSERT INTO `tb_account` VALUES ('4', '进击巨人', '11111', '1');
INSERT INTO `tb_account` VALUES ('5', '征服者', '12315', '2');
-- ----------------------------
-- Table structure for `tb_game`
-- ----------------------------
DROP TABLE IF EXISTS `tb_game`;
CREATE TABLE `tb_game` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`type` varchar(255) DEFAULT NULL,
`operator` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of tb_game
-- ----------------------------
INSERT INTO `tb_game` VALUES ('1', '英雄联盟', 'MOBA', '腾讯游戏');
INSERT INTO `tb_game` VALUES ('2', '绝地求生', 'TPS', '蓝洞游戏');
-- ----------------------------
-- Table structure for `tb_player`
-- ----------------------------
DROP TABLE IF EXISTS `tb_player`;
CREATE TABLE `tb_player` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`sex` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of tb_player
-- ----------------------------
INSERT INTO `tb_player` VALUES ('1', '张三', '23', '1');
INSERT INTO `tb_player` VALUES ('2', '李四', '24', '1');
-- ----------------------------
-- Table structure for `tb_player_game`
-- ----------------------------
DROP TABLE IF EXISTS `tb_player_game`;
CREATE TABLE `tb_player_game` (
`player_id` int(11) NOT NULL DEFAULT '0',
`game_id` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`player_id`,`game_id`),
KEY `game_id` (`game_id`),
CONSTRAINT `tb_player_game_ibfk_2` FOREIGN KEY (`game_id`) REFERENCES `tb_game` (`id`),
CONSTRAINT `tb_player_game_ibfk_1` FOREIGN KEY (`player_id`) REFERENCES `tb_player` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of tb_player_game
-- ----------------------------
INSERT INTO `tb_player_game` VALUES ('1', '1');
INSERT INTO `tb_player_game` VALUES ('1', '2');
INSERT INTO `tb_player_game` VALUES ('2', '2');
-- ----------------------------
-- Table structure for `tb_role`
-- ----------------------------
DROP TABLE IF EXISTS `tb_role`;
CREATE TABLE `tb_role` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`profession` varchar(255) DEFAULT NULL,
`rank` int(11) DEFAULT NULL,
`money` int(11) DEFAULT NULL,
`account_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `account_id` (`account_id`) USING BTREE,
CONSTRAINT `tb_role_ibfk_1` FOREIGN KEY (`account_id`) REFERENCES `tb_account` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of tb_role
-- ----------------------------
INSERT INTO `tb_role` VALUES ('1', '战士', '10', '2000', '1');
INSERT INTO `tb_role` VALUES ('2', '法师', '30', '100000', '4');
INSERT INTO `tb_role` VALUES ('4', '刺客', '1', '100', '5');
数据库显示如下:
这张图是通过 Navicat 工具的逆向表模型功能得到的,可以直观方便查看表与表之间的关系,操作步骤如下:
你可能会问,不是说四张表,怎么数据库里有五张表呀,原因是多对多的关联关系在数据库中无法直接实现,只能间接实现;具体而言,就是通过添加一张中间表,将多对多的关联关系转化为两个一对多的关联关系。
如果还没搞明白,建议你去复习一下数据库的相关知识。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)