MyBatis基础应用(三)——使用MyBatis关联映射实现多表查询
现实生活中实体和实体之间的关系: 一对多、多对多 、一对一
1. 关联映射作用
在现实的项目中进行数据库建模时,我们要遵循数据库设计范式的要求,会对现实中的业务模型进行拆分,封装在不同的数据表中,表与表之间存在着一对一、一对多或是多对多的对应关系。进而,我们对数据库的增删改查操作的主体,也就从单表变成了多表。那么Mybatis中是如何实现这种多表关系的映射呢?答案是使用查询结果集ResultMap (结果集映射)!
resultMap元素中,允许有以下直接子元素:
id :作用与result相同,同时可以标识出用这个字段值可以区分其他对象实例。可以理解为数据表中的主键,可以定位数据表中唯一的一笔记录
result : 将数据表中的字段注入到Java对象属性中
column :数据库中的字段名
property:实体类中的属性名
association :关联,简单的讲,就是“有一个”关系,如“用户”有一个“帐号” (一对一)
collection :集合,顾名思议,就是“有很多”关系,如“客户”有很多“订单” (一对多或者多对多)
2. 一对多关联(重点)
一对多的关联主要体现在我们查询的时候需要关联查询多个数据表,在这里我举例查询电影类型,返回该电影类型下的所有电影的和电影信息,需要用到的两个表的信息如下:
创建对应的数据表、实体和mapper(可以根据表的信息自行添加、所有的数据库的sql在文末)
接口查询方法的返回类型是什么?查询结果包含了两张数据表的所有信息,显然一个对象无法封装这些信息。
解决办法就是在moveType实体类里面添加扩展字段,这样我们就能用一个moveType的对象去接受返回的查询结果。同时在mapper里面使用结果集映射来区分接受的数据字段,每个字段都不要省略。
public class MovieType {
private Integer id;
private String typeName;
//表示在电影类型下有多个电影对象--扩展字段
private List<Movie> movieList;
}
同时需要给movieType的id字段名取一个别名tid,防止两张表的数据字段id重名,id重名可能会造成返回接轨时无法区分id。
<mapper namespace="com.it.mapper.MovieTypeMapper">
<!--结果集映射-->
<resultMap id="typeMap" type="MovieType">
<id column="TID" property="id"/>
<result column="TYPENAME" property="typeName"/>
<!--关联字段:集合 has many-->
<collection property="movieList" ofType="Movie">
<id column="ID" property="id"/>
<result column="TITLE" property="title"/>
<result column="PRICE" property="price"/>
<result column="ACTOR" property="actor"/>
<result column="TYPE_ID" property="typeId"/>
</collection>
</resultMap>
<select id="queryMovieTypeInfo" resultMap="typeMap">
SELECT
tb_movietype.id AS 'tid',
tb_movietype.typeName,
tb_movie.*
FROM
tb_movietype
INNER JOIN tb_movie ON tb_movietype.id = tb_movie.type_id
WHERE
tb_movietype.typename =#{typeName}
</select>
</mapper>
MyBatis中使用collection标签来解决一对多的关联查询;
ofType属性指定集合中元素的对象类型。
3. 一对一关联(了解)
同样使用上面的两张数据表,查询一个电影,返回电影的信息和电影的类别。一个电影对应一个电影类别(一对一关联)
与一对多的主要区别就是添加的扩展字段和在mapper里面的配置结果集映射时候有所不同,主要区别如下图与所示:
MyBatis中使用association(有一个)标签来解决一对一的关联查询
4. 多对多关联(重点)
创建下面三张数据表,来测试实现多对多关联(人物与角色之间属于多对多的关系)
人物角色是中间表,可以不创建实体类;然后照常添加扩展字段后,配置mapper来实现多对多的关联查询。
mapper里面需要结果集映射,以及通过给数据字段取别名的解决多个表中字段名冲突问题。
<mapper namespace="com.it.mapper.PeopleMapper">
<resultMap id="peopleMap" type="People">
<id column="ID" property="id"/>
<result column="NAME" property="name"/>
<result column="SEX" property="sex"/>
<result column="AGE" property="age"/>
<!--有多个集合-->
<collection property="roleList" ofType="Roles">
<id column="RID" property="id"/>
<result column="RNAME" property="name"/>
<result column="REMARK" property="remark"/>
</collection>
</resultMap>
<select id="findByPeopleByName" resultMap="peopleMap">
SELECT
tb_people.*,
tb_role.id as 'rid',
tb_role.name as 'rname',
tb_role.remark
FROM
tb_people
INNER JOIN tb_people_role ON tb_people.id = tb_people_role.people_id
INNER JOIN tb_role ON tb_people_role.role_id = tb_role.id
WHERE
tb_people.`name` = #{name}
</select>
</mapper>
5.数据库sql文件
/*
Navicat Premium Data Transfer
Source Server : mysql
Source Server Type : MySQL
Source Server Version : 80029
Source Host : localhost:3306
Source Schema : mybatis-db-1
Target Server Type : MySQL
Target Server Version : 80029
File Encoding : 65001
Date: 28/04/2023 14:51:15
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for tb_car
-- ----------------------------
DROP TABLE IF EXISTS `tb_car`;
CREATE TABLE `tb_car` (
`id` int(0) NOT NULL,
`brand` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
`color` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
`price` decimal(10, 2) NULL DEFAULT NULL,
`size` double NULL DEFAULT NULL,
`card_id` int(0) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `uq_card_id`(`card_id`) USING BTREE,
CONSTRAINT `fk_card_id` FOREIGN KEY (`card_id`) REFERENCES `tb_card` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of tb_car
-- ----------------------------
INSERT INTO `tb_car` VALUES (1, '玛莎拉蒂', '白色', 90.00, 2, 2);
INSERT INTO `tb_car` VALUES (2, '迈巴赫', '黑色', 120.00, 2.5, 1);
-- ----------------------------
-- Table structure for tb_card
-- ----------------------------
DROP TABLE IF EXISTS `tb_card`;
CREATE TABLE `tb_card` (
`id` int(0) NOT NULL AUTO_INCREMENT,
`num` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
`color` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of tb_card
-- ----------------------------
INSERT INTO `tb_card` VALUES (1, '川A5678J', '蓝牌');
INSERT INTO `tb_card` VALUES (2, '川A4545X', '蓝牌');
-- ----------------------------
-- Table structure for tb_movie
-- ----------------------------
DROP TABLE IF EXISTS `tb_movie`;
CREATE TABLE `tb_movie` (
`id` int(0) NOT NULL AUTO_INCREMENT,
`title` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
`price` double(10, 2) NULL DEFAULT NULL,
`actor` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
`type_id` int(0) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `fk_type_id`(`type_id`) USING BTREE,
CONSTRAINT `fk_type_id` FOREIGN KEY (`type_id`) REFERENCES `tb_movietype` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of tb_movie
-- ----------------------------
INSERT INTO `tb_movie` VALUES (1, '山村老尸', 50.00, '吴镇宇', 3);
INSERT INTO `tb_movie` VALUES (2, '一眉道长', 60.00, '林正英', 3);
INSERT INTO `tb_movie` VALUES (3, '午夜凶铃', 60.00, '贞子', 3);
-- ----------------------------
-- Table structure for tb_movietype
-- ----------------------------
DROP TABLE IF EXISTS `tb_movietype`;
CREATE TABLE `tb_movietype` (
`id` int(0) NOT NULL AUTO_INCREMENT,
`typename` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of tb_movietype
-- ----------------------------
INSERT INTO `tb_movietype` VALUES (1, '动作片');
INSERT INTO `tb_movietype` VALUES (2, '爱情片');
INSERT INTO `tb_movietype` VALUES (3, '恐怖片');
INSERT INTO `tb_movietype` VALUES (4, '科幻片');
-- ----------------------------
-- Table structure for tb_people
-- ----------------------------
DROP TABLE IF EXISTS `tb_people`;
CREATE TABLE `tb_people` (
`id` int(0) NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
`sex` char(1) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
`age` int(0) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of tb_people
-- ----------------------------
INSERT INTO `tb_people` VALUES (1, '苍老师', '女', 18);
INSERT INTO `tb_people` VALUES (2, '波多老师', '女', 28);
INSERT INTO `tb_people` VALUES (3, '小泽老师', '女', 23);
-- ----------------------------
-- Table structure for tb_people_role
-- ----------------------------
DROP TABLE IF EXISTS `tb_people_role`;
CREATE TABLE `tb_people_role` (
`id` int(0) NOT NULL AUTO_INCREMENT,
`people_id` int(0) NULL DEFAULT NULL,
`role_id` int(0) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `fk_people_id`(`people_id`) USING BTREE,
INDEX `fk_role_id`(`role_id`) USING BTREE,
CONSTRAINT `fk_people_id` FOREIGN KEY (`people_id`) REFERENCES `tb_people` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT `fk_role_id` FOREIGN KEY (`role_id`) REFERENCES `tb_role` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of tb_people_role
-- ----------------------------
INSERT INTO `tb_people_role` VALUES (1, 1, 1);
INSERT INTO `tb_people_role` VALUES (2, 1, 2);
INSERT INTO `tb_people_role` VALUES (3, 1, 3);
INSERT INTO `tb_people_role` VALUES (4, 2, 1);
INSERT INTO `tb_people_role` VALUES (5, 3, 1);
-- ----------------------------
-- Table structure for tb_role
-- ----------------------------
DROP TABLE IF EXISTS `tb_role`;
CREATE TABLE `tb_role` (
`id` int(0) NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
`remark` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of tb_role
-- ----------------------------
INSERT INTO `tb_role` VALUES (1, '秘书', '老板秘书');
INSERT INTO `tb_role` VALUES (2, '护士', '医院护士');
INSERT INTO `tb_role` VALUES (3, '售票员', '公交车售票员');
INSERT INTO `tb_role` VALUES (4, '家教', '家庭教育');
SET FOREIGN_KEY_CHECKS = 1;
更多推荐
所有评论(0)