MybatisPlus使用注解的多对多级联查询方式

 更新时间:2023年07月31日 10:44:11   作者:墨末..  
这篇文章主要介绍了MybatisPlus使用注解的多对多级联查询方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

假设我们需要将用户信息(包括了用户对应的角色信息)查询出来

数据表结构

先贴出数据表结构,user和role,还有一张中间表user_role

user表和role表的关系为多对多,即一个user可以分配多个role,一个role可以属于多个user。

1.user表

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `nickname` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '昵称',
  `birthday` date NOT NULL COMMENT '生日',
  `username` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户名',
  `password` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '密码',
  `status` varchar(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '状态 ',
  `create_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
  `update_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

插入数据

INSERT INTO `user` VALUES (1, 'lh', '2022-06-29', '李大', '123456', '0', '2022-06-29 09:02:07', '2022-06-29 09:02:07');
INSERT INTO `user` VALUES (2, 'ww', '2022-06-29', '陈大', '123456', '0', '2022-06-29 13:06:24', '2022-06-29 13:06:24');
INSERT INTO `user` VALUES (3, 'aa', '2022-06-29', '刘达', '123456', '0', '2022-06-29 13:06:48', '2022-06-29 13:06:48');

2.role表

DROP TABLE IF EXISTS `role`;
CREATE TABLE `role`  (
  `id` int(0) NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '角色名称',
  `remark` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '角色描述',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

插入数据

INSERT INTO `role` VALUES (1, '系统管理员', '系统管理员');
INSERT INTO `role` VALUES (2, '数据管理员', '数据管理员');

3.user_role中间表

DROP TABLE IF EXISTS `user_role`;
CREATE TABLE `user_role`  (
  `user_id` int(0) NOT NULL COMMENT '用户id',
  `role_id` int(0) NULL DEFAULT NULL COMMENT '角色id'
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

插入数据

INSERT INTO `user_role` VALUES (1, 1);
INSERT INTO `user_role` VALUES (1, 2);
INSERT INTO `user_role` VALUES (2, 1);
INSERT INTO `user_role` VALUES (2, 2);
INSERT INTO `user_role` VALUES (3, 1);

具体做法

先定义UserVo类,List roles表示user所属role

@Data
@ApiModel("用户视图模型")
public class UserVo {
    /**
     * 用户编号
     */
    @ApiModelProperty("用户编号")
    private Integer id;
    /**
     * 昵称
     */
    @ApiModelProperty("昵称")
    private String nickname;
    /**
     * 用户名
     */
    @ApiModelProperty("用户名")
    private String username;
    /**
     * 生日
     */
    @ApiModelProperty("生日")
    private LocalDateTime birthday;
    private List<Role> roles;
}

先在userMapper中定义getList()方法用户获取用户基本信息(包括了用户对应的角色信息)

 @Select("select * from user where ${ew.SqlSegment}")
 List<UserVo> getList(@Param("ew") QueryWrapper wrapper);

然后再roleMapper中定义getListByUserId()方法来获取用户所属角色列表

 /**
     * 根据指定的userId去user和user_role关联表查出该user所属role列表
     * @param userId
     * @return
 */
@Select("select * from role left join user_role on role.id=user_role.role_id  where user_role.user_id=#{userId}")
List<Role> getListByUserId(Integer userId);

添加关联关系,修改userMapper中的getList()方法

 @Select("select * from user where ${ew.SqlSegment}")
    @Results({@Result(column = "id",property = "id"),
    @Result(column = "id",property = "roles",many=@Many(
            select = "com.hxh.basic.project.mapper.RoleMapper.getListByUserId"
    ))
    })
List<UserVo> getList(@Param("ew") QueryWrapper wrapper);

在上面这个@Result中column代表子查询关联的主表中的列名,即子查询和主查询之间的关联关系。property,代表子查询的查询结果关联的实体属性,就是UserVo中的roles。

select="com.hxh.basic.project.mapper.RoleMapper.getListByUserId"代表使用的子查询方法,就是我们的RoleMapper 的 getListByUserId()方法。

意思就是查询主表,并将主表的id这个列和子查询关联起来,将id的值作为查询条件传入子查询中,子查询返回的结果存入到属性roles中其中 @Result(column=“id”,property=“Id”),这个可以不写,也不会报错,但是会导致我们查询结果列表里每个UVO 实体的Id等属性没有值。

执行效果

测试类UserServiceImplTest

@RunWith(SpringRunner.class)
@SpringBootTest(classes = BasicProjectApplication.class)
public class UserServiceImplTest {
    @Resource
    private UserMapper userMapper;
    @Resource
    private RoleMapper roleMapper;
    @Test
    public void getUserInfo(){
        QueryWrapper<User> wrapper=new QueryWrapper();
        wrapper.eq("id",1);
        List<UserVo> list = userMapper.getList(wrapper);
        System.out.println(list);
    }
}

将user的id=1传入,得到结果如下:

[UserVo(id=1, nickname=lh, username=李哈, birthday=2022-06-29T00:00, roles=[Role(id=1, name=系统管理员, remark=系统管理员), Role(id=2, name=数据管理员, remark=数据管理员)])]

可以看出表中id为1的user信息和其对应的角色信息信息已经查询出来了。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 深入理解Java的接口与抽象类

    深入理解Java的接口与抽象类

    本文主要介绍java 的接口和抽象类,对接口和抽象类进行介绍对比,深入理解,有需要的小伙伴可以参考下
    2016-07-07
  • 史上最全的java随机数生成算法分享

    史上最全的java随机数生成算法分享

    这篇文章主要介绍了史上最全的java随机数生成算法,我分享一个最全的随机数的生成算法,最代码的找回密码的随机数就是用的这个方法
    2014-01-01
  • Spring Boot中Redis数据库的使用实例

    Spring Boot中Redis数据库的使用实例

    Spring Boot中除了对常用的关系型数据库提供了优秀的自动化支持之外,对于很多NoSQL数据库一样提供了自动化配置的支持。本篇文章主要介绍了Spring Boot中Redis的使用实例代码,有兴趣的开业了解一下。
    2017-04-04
  • Java中获取类路径classpath的简单方法(推荐)

    Java中获取类路径classpath的简单方法(推荐)

    下面小编就为大家带来一篇Java中获取类路径classpath的简单方法(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-09-09
  • Java后端限制频繁请求和重复提交的实现

    Java后端限制频繁请求和重复提交的实现

    很多用户会请求过于频繁或者是多次重复提交数据,本文主要介绍了Java后端限制频繁请求和重复提交的实现,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • Springboot源码 AbstractAdvisorAutoProxyCreator解析

    Springboot源码 AbstractAdvisorAutoProxyCreator解析

    这篇文章主要介绍了Springboot源码 AbstractAdvisorAutoProxyCreator解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-08-08
  • SpringBoot3整合EasyExcel动态实现表头重命名

    SpringBoot3整合EasyExcel动态实现表头重命名

    这篇文章主要为大家详细介绍了SpringBoot3整合EasyExcel如何通过WriteHandler动态实现表头重命名,文中的示例代码讲解详细,有需要的可以了解下
    2025-03-03
  • 使用springboot通过spi机制加载mysql驱动的过程

    使用springboot通过spi机制加载mysql驱动的过程

    这篇文章主要介绍了使用springboot通过spi机制加载mysql驱动的过程,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • Java设计模式之工厂方法模式详解

    Java设计模式之工厂方法模式详解

    工厂方法模式(FACTORY METHOD)是一种常用的类创建型设计模式,此模式的核心精神是封装类中变化的部分,提取其中个性化善变的部分为独立类,通过依赖注入以达到解耦、复用和方便后期维护拓展的目的。它的核心结构有四个角色,分别是抽象工厂、具体工厂、抽象产品、具体产品
    2022-08-08
  • SpringBoot顶层接口实现类注入项目的方法示例

    SpringBoot顶层接口实现类注入项目的方法示例

    本文主要介绍了SpringBoot顶层接口实现类注入项目的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-06-06

最新评论