本文介绍: Mybatis Plus 多表联查(包含分页关联查询,图文讲解)更新时间 2023-01-03 21:41:38大家好,我是小哈。本小节中,我们学习如何通过 Mybatis Plus 实现多表关联查询,以及分页关联查询。表结构本文查询用户所下订单,来演示 Mybatis Plus 的关联查询数据库表除了前面小节中已经定义好的用户表外,再额外创建一张单表然后插入一些测试数据

Mybatis Plus 多表联查(包含分页关联查询,图文讲解)

 更新时间 2023-01-03 21:41:38

大家好,我是小哈。

本小节中,我们学习如何通过 Mybatis Plus 实现多表关联查询,以及分页关联查询

表结构

本文查询用户所下订单,来演示 Mybatis Plus 的关联查询,数据库表除了前面小节中已经定义好的用户表外,再额外创建一张单表然后插入一些测试数据,执行脚本如下:

DROP TABLE IF EXISTS user; CREATE TABLE `t_user` ( `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID', `name` varchar(30) NOT NULL DEFAULT '' COMMENT '姓名', `age` int(11) NULL DEFAULT NULL COMMENT '年龄', `gender` tinyint(2) NOT NULL DEFAULT 0 COMMENT '性别,0:女 1:男', PRIMARY KEY (`id`) ) COMMENT = '用户表'; INSERT INTO `t_user` (`id`, `name`, `age`, `gender`) VALUES (1, '犬小哈', 30, 1); INSERT INTO `t_user` (`id`, `name`, `age`, `gender`) VALUES (2, '关羽', 46, 1); INSERT INTO `t_user` (`id`, `name`, `age`, `gender`) VALUES (3, '诸葛亮', 26, 1); CREATE TABLE `t_order` ( `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID', `order_id` bigint(20) UNSIGNED NOT NULL COMMENT '订单ID', `user_id` bigint(20) UNSIGNED NOT NULL COMMENT '下单用户ID', `goods_name` varchar(30) NOT NULL COMMENT '商品名称', `goods_price` decimal(10,2) NOT NULL COMMENT '商品价格', PRIMARY KEY (`id`), INDEX idx_order_id(`order_id`) ) COMMENT = '订单表'; INSERT INTO `t_order` (`id`, `order_id`, `user_id`, `goods_name`, `goods_price`) VALUES (1, 805646264648356, 1, 'Switch 游戏机', 1400.00); INSERT INTO `t_order` (`id`, `order_id`, `user_id`, `goods_name`, `goods_price`) VALUES (2, 551787441310504, 1, '小米手机', 2000.00); INSERT INTO `t_order` (`id`, `order_id`, `user_id`, `goods_name`, `goods_price`) VALUES (3, 938562101633493, 2, '《三国演义》', 66.00); INSERT INTO `t_order` (`id`, `order_id`, `user_id`, `goods_name`, `goods_price`) VALUES (4, 791129917310894, 3, '华为手机', 1200.00); INSERT INTO `t_order` (`id`, `order_id`, `user_id`, `goods_name`, `goods_price`) VALUES (5, 208722395587361, 3, '《西游记》', 56.00); 

需求分析

假设前端需要展示数据有如下几个字段:订单号、商品名称商品价格、下单用户姓名、下单用户年龄、下单用户性别:

对应的关联 SQL 语句如下:

select o.order_id, o.goods_name, o.goods_price, u.name, u.age, u.gender
        from t_order as o left join t_user as u on o.user_id = u.id 

项目结构

先贴一张项目结构,下面所创建的类与文件可参考这里

实体类

接下来我们定义实体类。创建一个 OrderVO 视图类,用于传输前端展示

/**
 * @author: 犬小哈
 * @from: 公众号:小哈学Java, 网站www.quanxiaoha.com
 * @date: 2022-12-13 14:13
 * @version: v1.0.0 * @description: TODO **/ @Data public class OrderVO { /** * 订单ID */ private Long orderId; /** * 下单用户ID */ private Long userId; /** * 商品名称 */ private String goodsName; /** * 商品价格 */ private BigDecimal goodsPrice; /** * 用户名 */ private String userName; /** * 年龄 */ private Integer userAge; /** * 性别 */ private Integer userGender; } 

TIP: @Data 是 Lombok 注解,偷懒用的,加上它即可免写繁杂的 getXXX/setXXX 相关方法,不了解的小伙伴可自行搜索一下如何使用

开始关联查询

简单的关联查询

创建 UserMapper , 让其继承自 BaseMapper , 并自定义一个查询订单列表方法:

public interface UserMapper extends BaseMapper<User> { // 查询订单列表 List<OrderVO> selectOrders(); } 

在项目的 resource 目录新建 mapper 文件夹,并在 mapper 文件夹中创建 UserMapper.xml 文件

UserMapper.xml 中编写关联语句,以及需要映射对象内容如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.quanxiaoha.mybatisplusdemo.mapper.UserMapper"> <resultMap id="orderMap" type="com.quanxiaoha.mybatisplusdemo.model.OrderVO"> <result property="userName" column="name"/> <result property="userAge" column="age"/> <result property="userGender" column="gender"/> <result property="orderId" column="order_id"/> <result property="userId" column="user_id"/> <result property="goodsName" column="goods_name"/> <result property="goodsPrice" column="goods_price"/> </resultMap> <select id="selectOrders" resultMap="orderMap"> select o.order_id, o.user_id, o.goods_name, o.goods_price, u.name, u.age, u.gender from t_order as o left join t_user as u on o.user_id = u.id </select> </mapper> 

创建完了 UserMapper.xml 文件后,还需要在 applicatoin.yml 中添加如下配置,告诉 Mybatis Plus 框架扫描这些 xml 文件

mybatis-plus:
  mapper-locations: classpath:/mapper/*Mapper.xml

然后,创建一个单元测试看看好不好使:

@Autowired
private UserMapper userMapper;

@Test
void testSelectOrders() { List<OrderVO> orderVOS = userMapper.selectOrders(); } 

执行上面的单元测试,实际执行 SQL 为:

select o.order_id, o.user_id, o.goods_name, o.goods_price, u.name, u.age, u.gender from t_order as o left join t_user as u on o.user_id = u.id 

返回数据如下:

这里一个简单的关联查询就搞定了。

带分页的关联查询

实际开发场景中,很多关联查询都需要结合分页一起使用假设上面展示的数据需要分页展示,且需要支持条件查询,要怎么做呢?

定义关联查询分页方法

在 UserMapper 接口中再定义支持分页的关联查询方法

public interface UserMapper extends BaseMapper<User> { //... IPage<OrderVO> selectOrderPage(IPage<OrderVO> page, @Param(Constants.WRAPPER) QueryWrapper<OrderVO> wrapper); //... } 

TIP : 可以看到我们定义的关联分页查询和 Myatis Plus 内部提供的分页方法相差不大,仔细看入参,我们复用了 Mybatis Plus 内部提供的分页类IPage,以及 QueryWrapper (用于组装 where 条件)。

然后在 UserMapper.xml 中创建该方法对应的关联查询:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.quanxiaoha.mybatisplusdemo.mapper.UserMapper"> <resultMap id="orderMap" type="com.quanxiaoha.mybatisplusdemo.model.OrderVO"> <result property="userName" column="name"/> <result property="userAge" column="age"/> <result property="userGender" column="gender"/> <result property="orderId" column="order_id"/> <result property="userId" column="user_id"/> <result property="goodsName" column="goods_name"/> <result property="goodsPrice" column="goods_price"/> </resultMap> //... <select id="selectOrderPage" resultMap="orderMap"> select u.name, u.age, u.gender, o.order_id, o.goods_name, o.goods_price from t_user as u left join t_order as o on u.id = o.user_id ${ew.customSqlSegment} </select> //... </mapper> 

再创建一个单元测试

@Autowiredprivate UserMapper userMapper;

@Test
void testSelectOrdersPage() { // 查询第一页,每页显示 10 条 Page<OrderVO> page = new Page<>(1, 10); // 注意:一定要手动关闭 SQL 优化,不然查询总数的时候只会查询主表 page.setOptimizeCountSql(false); // 组装查询条件 where age = 20 QueryWrapper<OrderVO> queryWrapper = new QueryWrapper<>(); queryWrapper.ge("age", 20); IPage<OrderVO> page1 = userMapper.selectOrderPage(page, queryWrapper); System.out.println("总记录数:" + page1.getTotal()); System.out.println("总共多少页:" + page1.getPages()); System.out.println("当前页码:" + page1.getCurrent()); System.out.println("查询数据:" + page1.getRecords()); } 

执行单元测试控制打印实际执行 SQL 如下,可见分页功能也是 OK 的,先执行 select count(*) 查询记录总数,然后再执行关联分页查询:

原文地址:https://blog.csdn.net/m0_61442607/article/details/128887908

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

如若转载,请注明出处:http://www.7code.cn/show_13185.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

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