通常我们会使用PageHelper进行分页查询,但是当分页查询被用到多个表的关联查询中时,就有可能导致查询出来的数据总数比我们想要的多得多。
首先在数据库中创建三个demo表:role、path、role_path
role角色表
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for role
-- ----------------------------
DROP TABLE IF EXISTS `role`;
CREATE TABLE `role` (
`id` int(20) NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of role
-- ----------------------------
INSERT INTO `role` VALUES (1, '管理员');
INSERT INTO `role` VALUES (2, '竞赛负责人');
INSERT INTO `role` VALUES (3, '教师');
INSERT INTO `role` VALUES (4, '学生');
SET FOREIGN_KEY_CHECKS = 1;
path路径表
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for path
-- ----------------------------
DROP TABLE IF EXISTS `path`;
CREATE TABLE `path` (
`id` int(20) NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`address` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of path
-- ----------------------------
INSERT INTO `path` VALUES (1, '学生管理', '/stuMa');
INSERT INTO `path` VALUES (2, '教师管理', '/teaMa');
INSERT INTO `path` VALUES (3, '队伍管理', '/teamMa');
INSERT INTO `path` VALUES (4, '项目管理', '/proMa');
SET FOREIGN_KEY_CHECKS = 1;
role_path角色路径关系表
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for role_path
-- ----------------------------
DROP TABLE IF EXISTS `role_path`;
CREATE TABLE `role_path` (
`role_id` int(20) NULL DEFAULT NULL,
`path_id` int(20) NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of role_path
-- ----------------------------
INSERT INTO `role_path` VALUES (1, 1);
INSERT INTO `role_path` VALUES (1, 2);
INSERT INTO `role_path` VALUES (1, 3);
INSERT INTO `role_path` VALUES (1, 4);
INSERT INTO `role_path` VALUES (2, 4);
INSERT INTO `role_path` VALUES (3, 3);
INSERT INTO `role_path` VALUES (3, 4);
INSERT INTO `role_path` VALUES (4, 3);
SET FOREIGN_KEY_CHECKS = 1;
假设我们想要查询角色所对应的路径的名称有哪些,此时就会进行多表关联查询
SELECT
role.NAME,
res.NAME pathName
FROM
role
INNER JOIN ( SELECT role_path.role_id, path.NAME FROM role_path INNER JOIN path ON role_path.path_id = path.id ) res ON res.role_id = role.id
查询结果
正常情况下我们通过mybatis的封装,就可以将查询到的数据封装在4个角色对象当中,但是如果我们还想使用PageHelper进行分页查询,那么PageHelper给我们返回的数据总数total就会是8条,这样很显然不是我们想要的数据。
解决方法
我们可以在数据库中将角色名称相同的数据进行合并,并使用GROUP_CONCAT(属性名),将指定的属性进行拼接(如果分组后的属性存在多个)
SELECT
role.NAME,
GROUP_CONCAT( res.NAME ) pathName
FROM
role
INNER JOIN ( SELECT role_path.role_id, path.NAME FROM role_path INNER JOIN path ON role_path.path_id = path.id ) res ON res.role_id = role.id
GROUP BY
role.NAME
查询结果
这样再使用PageHelper时返回的total仍然是4个,并且在数据库中直接将我们想要的数据进行了整合。
如果我们想要获取有队伍管理权限的角色拥有的权限信息,此时也是需要进行多表查询