首页 > 其他分享 >Mybatis Plus 多表联查(包含分页关联查询,图文讲解)

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

时间:2024-04-30 12:00:11浏览次数:28  
标签:goods 多表 name order Plus user Mybatis 查询 id

本章将学习如何通过 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>

 

再创建一个单元测试:

@Autowired
private 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://www.quanxiaoha.com/mybatis-plus/mybaitsplus-join-query.html

标签:goods,多表,name,order,Plus,user,Mybatis,查询,id
From: https://www.cnblogs.com/haoyul/p/18167786

相关文章

  • Mybatis二级缓存使用
     一、应用场景例如首页数据加载很慢,但是首页相关数据变动很小。即可以使用二级缓存 二、此处以springboot项目为例在yml配置文件新增 三、查询数据的类对象需要序列化不然会报错 四、在对应的xml文件中加入</cache>开启二级缓存 ......
  • Mybatis Plus快速入门(一)
    1.环境准备MySQL环境配置:5.7,可以参考我之前的文章使用docker或者直接安装在服务器上面。新建一张表user,使用MybatisPlus官网提供表结构和数据。DROPTABLEIFEXISTS`user`;CREATETABLE`user`(idBIGINTNOTNULLCOMMENT'主键ID',nameVARCHAR(30)NULLD......
  • mybatis 常用标签
    xml模板<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEmapperPUBLIC"-//mybatis.org//DTDMapper3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mappernamespace="mapper接口全限定名">......
  • mybatis乐观锁批量更新和单个更新
    拦截器packagecom.esolution.xreport.config;importcom.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;importcom.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;importorg.springframework.context.annotation.......
  • SpringBoot中几种好用的代码生成器(基于Mybatis-plus生成entity、mapper、xml等)
    前言熟悉Spring框架的同学一定都知道MVC开发模式吧,控制器(Controller)、业务类(Service)、持久层(Repository)、数据库映射(Mapper)、各种DO类构成了我们服务端的代码。初学的时候,觉得新鲜手写这些东西不觉得有啥,但是写久了就会觉得很烦。好不容易在数据库中写完了一遍字段,在Java代码又要......
  • openGauss 如何解决-g++-fatal-error-Killed-signal-terminated-program-cclplus-报错
    如何解决"g++:fatalerror:Killedsignalterminatedprogramcclplus"报错问题如何解决编译过程中出现的"g++:fatalerror:Killedsignalterminatedprogramcclplus"报错。回答报错原因:脚本中的编译过程都添加了-sj参数,并发数太大导致错误。解决办法:编译过程中降......
  • Mybatis入门——基础操作
    介绍什么是Mybatis?Mybatis是一款优秀的持久层框架,用于简化JDBC的开发。Mybatis本是Apache的一个开源项目iBatis,2010年这个项目由apache迁移到了goolecode,并且改名为Mybatis,2013年11月迁移到GitHub。官网:https://mybatis.org/mybatis-3/zh_CN/index.html快速入门使用......
  • MyBatis-Plus QueryWrapper常用方法
    1queryWrapper.lt();//小于2queryWrapper.le();//小于等于3queryWrapper.gt();//大于4queryWrapper.ge();//大于等于5queryWrapper.eq();......
  • mybatisplus乐观锁拦截器批量更新
    在MyBatis-Plus中使用乐观锁拦截器进行批量更新时,需要注意乐观锁的使用方式。乐观锁通常通过版本号机制实现,即在数据库表中增加一个版本号字段,每次更新时都会将版本号加一。下面是一个使用MyBatis-Plus的乐观锁拦截器处理批量更新的示例:首先,你需要自定义一个拦截器,实现Intercept......
  • mybatisplus乐观锁实现批量更新(在sql中实现)
    mybatisplus乐观锁实现批量更新在MyBatis-Plus中,乐观锁通常用于处理并发更新数据的问题。乐观锁实现批量更新时,可以使用版本号或者时间戳来保证数据的一致性。以下是使用乐观锁实现批量更新的示例代码:首先,在你的实体类中添加版本号字段:importcom.baomidou.mybatis......