最简单的 MyBatis Plus 的多表联接、分页查询实现方法

最简单的 MyBatis Plus 的多表联接、分页查询实现方法一、前言最近在加强ITAEM团队的一个app项目,人员配备:安卓+前端+后台后台DAO层借鉴了华工其他软件开发团队,使用了新颖强大的MyBatisPlus框架,里边有一个类似百度贴吧的发帖子的功能:而如果设计表,应为帖子表t_postidtitle标题content内容xxuser_id用户外键用户表t_userid…

大家好,又见面了,我是你们的朋友全栈君。

一、前言

最近在加强 ITAEM 团队的一个 app 项目——学生教师学习交流平台
人员组成:安卓 + 前端 + 后台
后台 DAO 层借鉴了华工其他软件开发团队,使用了新颖强大的 MyBatisPlus 框架,里边有一个类似百度贴吧的发帖子的功能:
这里写图片描述
而如果设计表,应为

  • 帖子表 t_post
    – id
    – title 标题
    – content 内容
    – xx
    user_id 用户外键
  • 用户表 t_user
    + id
    + name 帖子发起者名字
    + xx

示例图中红色框中的内容为 t_user 表的字段 name
而要实现上面显示帖子,就要用到关联查询了,而且帖子很多,必须用分页查询,

那么,怎么通过 MyBatisPlus 来实现关联、分页查询呢 ?很简单,往下看。

二、需求、数据库表设计

这是个人 app 项目中 v1.0 版本的部分表。
这里写图片描述
需求:显示帖子

  • 要帖子基本内容如时间、帖子内容等,即 t_question 表的内容全部要,
  • 同时还要发帖子的人名字,即 t_student 的字段 name

三、代码结构

为了写这篇文章,抽取了该 app 项目中的部分代码,彼此相互关系如下图
这里写图片描述

四、代码实现

1、代码已经放到 github 上了,若对本文的代码有疑问可以去 github 上查看详情:
https://github.com/larger5/MyBatisPlus_page_tables.git

2、entity、mapper、service、controller 使用了 MyBatisPlus 的代码生成器,自动生成大部分基础的代码,操作方法见之前的文章:
在 SpringBoot 中引入 MyBatisPlus 之 常规操作

1.实体

① Question

// import 省略

@TableName("t_question")
public class Question implements Serializable { 
   

    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "问答主键id")
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    @ApiModelProperty(value = "学生外键id")
    @TableField("student_id")
    private Integer studentId;

    @ApiModelProperty(value = "问题内容")
    private String content;

    @ApiModelProperty(value = "问题发布时间,发布的时候后台自动生成")
    private Date date;

    @ApiModelProperty(value = "问题悬赏的积分")
    private Integer value;

	// getter、setter 省略
}

② Student

// import 省略

@TableName("t_student")
public class Student implements Serializable { 
   

    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "学生主键id")
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    @ApiModelProperty(value = "学生名称")
    private String name;

    @ApiModelProperty(value = "学生密码")
    private String password;

    @ApiModelProperty(value = "学生积分数")
    private Integer points;

    @ApiModelProperty(value = "学生邮件地址")
    private String email;

    @ApiModelProperty(value = "学生手机号码")
    private String phone;

    @ApiModelProperty(value = "学生学号")
    private String num;

    @ApiModelProperty(value = "学生真实姓名")
    @TableField("true_name")
    private String trueName;

	// getter、setter 省略
}

2.mapper

① StudentMapper

// import 省略
public interface StudentMapper extends BaseMapper<Student> { 
   
}

② QuestionMapper

// import 省略
public interface QuestionMapper extends BaseMapper<Question> { 
   
    /** * * @param page 翻页对象,可以作为 xml 参数直接使用,传递参数 Page 即自动分页 * @return */
    @Select("SELECT t_question.*,t_student.`name` FROM t_question,t_student WHERE t_question.student_id=t_student.id")
    List<QuestionStudentVO> getQuestionStudent(Pagination page);

}

3、service

① StudentService

// import 省略
public interface StudentService extends IService<Student> { 
   
}

② QuestionService

// import 省略
public interface QuestionService extends IService<Question> { 
   

    Page<QuestionStudentVO> getQuestionStudent(Page<QuestionStudentVO> page);

}

4、serviceImpl

① StudentServiceImpl

// import 省略
@Service
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService { 
   

}

② QuestionServiceImpl

// 省略 import

@Service
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> implements QuestionService { 
   

    @Override
    public Page<QuestionStudentVO> getQuestionStudent(Page<QuestionStudentVO> page) { 
   
        return page.setRecords(this.baseMapper.getQuestionStudent(page));
    }

}

5、controller

// 省略 import

@RestController
@RequestMapping("/common")
@EnableSwagger2
public class CommonController { 
   

    @Autowired
    QuestionService questionService;

    @Autowired
    StudentService studentService;

    @GetMapping("/getAllQuestionByPage/{page}/{size}")
    public Map<String, Object> getAllQuestionByPage(@PathVariable Integer page, @PathVariable Integer size) { 
   
        Map<String, Object> map = new HashMap<>();
        Page<Question> questionPage = questionService.selectPage(new Page<>(page, size));
        if (questionPage.getRecords().size() == 0) { 
   
            map.put("code", 400);
        } else { 
   
            map.put("code", 200);
            map.put("data", questionPage);
        }
        return map;
    }

    @GetMapping("/getAllQuestionWithStudentByPage/{page}/{size}")
    public Map<String, Object> getAllQuestionWithStudentByPage(@PathVariable Integer page, @PathVariable Integer size) { 
   
        Map<String, Object> map = new HashMap<>();
        Page<QuestionStudentVO> questionStudent = questionService.getQuestionStudent(new Page<>(page, size));
        if (questionStudent.getRecords().size() == 0) { 
   
            map.put("code", 400);
        } else { 
   
            map.put("code", 200);
            map.put("data", questionStudent);
        }
        return map;
    }

}

6、MyBatisPlus 配置

// 省略 import

@EnableTransactionManagement
@Configuration
@MapperScan("com.cun.app.mapper")
public class MybatisPlusConfig { 
   

    /** * 分页插件 */
    @Bean
    public PaginationInterceptor paginationInterceptor() { 
   
        return new PaginationInterceptor();
    }

    /** * 打印 sql */
    @Bean
    public PerformanceInterceptor performanceInterceptor() { 
   
        PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
        //格式化sql语句
        Properties properties = new Properties();
        properties.setProperty("format", "true");
        performanceInterceptor.setProperties(properties);
        return performanceInterceptor;
    }
}

7、关联查询 VO 对象

// import 省略

public class QuestionStudentVO implements Serializable { 
   

    @ApiModelProperty(value = "问答主键id")
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    @ApiModelProperty(value = "学生外键id")
    @TableField("student_id")
    private Integer studentId;

    private String name;

    @ApiModelProperty(value = "问题内容")
    private String content;

    @ApiModelProperty(value = "问题发布时间,发布的时候后台自动生成")
    private Date date;

    @ApiModelProperty(value = "问题悬赏的积分")
    private Integer value;

	// getter、setter 省略

五、测试接口

这里写图片描述

1、没有关联的分页查询接口

http://localhost/common/getAllQuestionByPage/1/2

① json 输出

{ 
   
  "code": 200,
  "data": { 
   
    "total": 10,
    "size": 2,
    "current": 1,
    "records": [
      { 
   
        "id": 1,
        "studentId": 3,
        "content": "唐代,渝州城里,有一个性格开朗、乐观的小伙子,名叫景天。",
        "date": 1534497561000,
        "value": 5
      },
      { 
   
        "id": 2,
        "studentId": 1,
        "content": "雪见从小父母双亡,由爷爷唐坤抚养成人。",
        "date": 1533201716000,
        "value": 20
      }
    ],
    "pages": 5
  }
}

② sql 执行

这里写图片描述

2、多表关联、分页查询接口

http://localhost/common/getAllQuestionWithStudentByPage/1/2

① json 输出

{ 
   
  "code": 200,
  "data": { 
   
    "total": 10,
    "size": 2,
    "current": 1,
    "records": [
      { 
   
        "id": 1,
        "studentId": 3,
        "name": "vv",
        "content": "唐代,渝州城里,有一个性格开朗、乐观的小伙子,名叫景天。",
        "date": 1534497561000,
        "value": 5
      },
      { 
   
        "id": 2,
        "studentId": 1,
        "name": "cun",
        "content": "雪见从小父母双亡,由爷爷唐坤抚养成人。",
        "date": 1533201716000,
        "value": 20
      }
    ],
    "pages": 5
  }
}

② sql 执行

这里写图片描述

六、小结

写本文的原因:

  • ①网上有做法不合时宜的文章(自定义page类、配置版)
  • ②官方文档使用的是配置版的,笔者采用注解版的
MyBatis 配置版 MyBatis 注解版
① 动态 sql 灵活、② xml 格式的 sql,可拓展性好 ① 少一个设置,少一个错误爆发点、② 代码清晰优雅

当然,智者见智仁者见仁

参考资料:
MyBatisPlus 官方文档:分页插件:方式一 、传参区分模式【推荐】

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/138328.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • visifire 控件

    visifire 控件引言Silverlight对于图形图像处理方面,从1.0时代起就给予了很强大的支持,所以我们可以在Silverlight中实现非常棒的各种统计图表,然而现在有了一些开源的项目,使得这项工作更加的简单。本文我将介绍一个开源的项目visifire,使用它可以在Silverlight2中实现超酷的图表。简单图表首先我们需要下载Visifire项目Silverlight开发包,在建立完项…

    2022年7月21日
    15
  • pandas astype()错误[通俗易懂]

    pandas astype()错误[通俗易懂]由于数据出现错误DataError:Nonumerictypestoaggregate改正以后才认识到astype的重要性。Top15[‘populations’]=Top15[‘EnergySupply’].div(Top15[‘EnergySupplyperCapita’]).astype(float)df_mean=((df.set_ind…

    2022年5月15日
    51
  • 在线客服系统源码demo/PHP客服系统下载附php源码「建议收藏」

    在线客服系统源码demo/PHP客服系统下载附php源码「建议收藏」在线客服系统软件为每个客户提供个性化的一对一支持。在线客服系统源码安装实时聊天小部件在尽可能多的网站和博客上并可定制聊天小部件完全适合您的网站。从一系列颜色和选项混合搭配。在线客服系统附源码演示及下载地址:ym.ws58.net在线客服系统源码H5通过为常见答案和回复创建快捷方式来节省时间。基于thinkphp在网页线客服完整源码下载地址:ym.ws58.net在聊天室里点击一个按钮就可以看到这些,只需单击一次即可将聊天内容传送到其他代理。团队合作以取悦顾客。实时聊天小部件跟踪访问者浏览您.

    2022年7月19日
    21
  • 细说 里氏替换原则[通俗易懂]

    细说 里氏替换原则[通俗易懂]转载:细说LSP(里氏替换原则)|chengco的博客前言曾经在一次给新入职员工做Java开发的课程培训,讲到面向对象的SOLID设计原则时,大家普遍认为”里氏替换原则”是其中最难理解的一个。也许从头说起才能弄清来龙去脉。为什么叫里氏替换原则?里氏替换原则在SOLID这五个设计原则中是比较特殊的存在:如果违反了里氏替换原则,不只是降低软件设计的优雅性,很可能会导致Bug 只有里氏替换原则是以人名命令的里氏替换原则译自Liskovsubstitutionprinciple

    2025年7月30日
    4
  • kitti数据集介绍_cifar10数据集下载

    kitti数据集介绍_cifar10数据集下载KITTI数据集下载及解析版本更新时间更新内容作者1V1.0xxx完成主体内容W.Xiao2文章目录KITTIDataset1简介1.1数据采集平台1.2坐标系2数据解析2.1image文件2.2velodyne文件2.3calib文件2.4label文件3KITTI可视…

    2022年10月10日
    3
  • 想修改CSS

    想修改CSS

    2021年7月23日
    56

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号