MybatisPlus实现多表的关联查询,实现分页,多条件查询全过程

 更新时间:2026年03月16日 17:11:51   作者:捡黄金的少年  
文章介绍了如何通过商品表与供应商表的关联查询,实现商品信息的模糊查询,具体包括建立DAO层接口、实体类和请求参数类,编写SQL查询语句,以及在控制层处理查询请求

缘由

实现商品表,通过表内的id关联查询到供应商表的name属性 

商品表

  • 如下所示:

供应商表

  • 如下所示:

新建查询测试sql

注意:

1、查询tb_goods表的全部,所以用t1.*,查询t2表的name,并用supplierName替换名称

2、使用LEFT JOIN链入tb_supplier表,tb_goods为主表

3、使用on来判断连接条件

4、where下面是查询条件,用like模糊查询,个条件间使用 And连接而不是Add

SELECT
	t1.*, t2. NAME supplierName
FROM
	tb_goods t1
LEFT JOIN tb_supplier t2 
ON t1.supplier_id = t2.id
WHERE
t1.name like '%S%'
AND t1.code like '%Spring%'
AND t1.supplier_id=1

建立dao层接口,实体类,以及接受请求参数类

请求参数类

建立请求参数类,用于接收前端模糊查询的结果

前端查询:商品名称,商品编码,商品供应商名称

package com.jhj.member.req;

import lombok.Data;

/**
 * @program: jhjmember
 * @ClassName GoodsREQ
 * @description:
 * @author:蒋皓洁
 * @create: 2020-08-19 15:21
 * @Version 1.0
 * 商品的请求类,接收请求参数
 **/
@Data
public class GoodsREQ {
    /**
     * 商品名称
     */
    private String name;

    /**
     * 商品编码
     */
    private String code;
    /**
     * 供应商id
     */
    private Integer supplierId;
}

entity实体类

实体类是代码生成器自动生成的,字段映射的是数据库tb_goods表的字段

但是注意的是,因为没有tb_supplier表供应商名字的字段,但是又要添加,所以采用 @TableField(exist = false)标识,不然启动时候在tb_goods中找不到supplierName就会报错

 /**
     * goods表中没有这个字段,所以这里要用,TableFiled标识字段,不然要报错
     */
    @TableField(exist = false)
    private  String supplierName;

package com.jhj.member.entity;

import java.math.BigDecimal;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

/**
 * <p>
 * 商品信息表
 * </p>
 *
 * @author 蒋皓洁
 * @since 2020-08-18
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("tb_goods")
public class Goods implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 主键ID
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    /**
     * 商品名称
     */
    private String name;

    /**
     * 商品编码
     */
    private String code;

    /**
     * 商品规格
     */
    private String spec;

    /**
     * 零售价
     */
    private BigDecimal retailPrice;

    /**
     * 进货价
     */
    private BigDecimal purchasePrice;

    /**
     * 库存数量
     */
    private Integer storageNum;

    /**
     * 供应商id
     */
    private Integer supplierId;


    /**
     * goods表中没有这个字段,所以这里要用,TableFiled标识字段,不然要报错
     */
    @TableField(exist = false)
    private  String supplierName;


}

mapper层接口

1、第一个参数传递分页的对象page (此对象封装当前页码,还有显示查询多少)

2、第二个参数,查询条件,@Param取别名, @Param(“req”)这个取的别名,方便xml里面使用

public interface GoodsMapper extends BaseMapper<Goods> {
    /**
     *
     * @param page
     * @param req
     * @return
     *
     *
     * 分页查询商品的列表
     * 1、第一个参数传递分页的对象page (此对象封装当前页码,还有显示查询多少)
     *
     * 2、第二个参数,查询条件,@Param取别名,
     *  @Param("req")这个取的别名,方便xml里面使用
     */

      IPage<Goods>searchPage(IPage<Goods> page, @Param("req")GoodsREQ req);
}

xml中写入sql

拼接如下所示,但是,注意的是

1、 < select id=“searchPage” resultType=“Goods”>

searchPage表mapper中的方法名称,Goods表示实体类的名称

在application.yml中配置了实体类的包,所以不用加全路径

mybatis-plus:
  # 扫描实体类所在的包,这样在mapper.xml文件中就不用配置实体类全路径,直接写类名就行
  type-aliases-package: com.jhj.member.entity
  #  扫描xml包下面的xml文件
  mapper-locations: classpath:com/jhj/member/mapper/xml/**.xml
  #  配置日志级别

2、where下面的拼接

WHERE 1=1

判断传入的值是否为空 req.name,这就用到了别名@Param(“req”),映射GoodsREQ req,

t1.name的name是数据库的字段,两个之间用and连接,不是add

每个查询条件之间也是用and连接

  < if test="req.name !=null and req.name!=''">
            and t1.name like CONCAT('%',#{req.name},'%')
  </ if >
<?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.jhj.member.mapper.GoodsMapper">

    <select id="searchPage" resultType="Goods">
        SELECT
        t1.*, t2.name supplierName
        FROM
        tb_goods t1
        LEFT JOIN tb_supplier t2 ON t1.supplier_id = t2.id
        WHERE 1=1
        <if test="req.name !=null and req.name!=''">
            and t1.name like CONCAT('%',#{req.name},'%')
        </if>
        <if test="req.code!=null and req.code!=''">
            and  t1.code like CONCAT('%',#{req.code},'%')
        </if>
        <if test="req.supplierId!=null">
            and t1.supplier_id=#{req.supplierId}
        </if>
    </select>
</mapper>

service层的编写

接口还是传入,页数page,每页显示多少size,和查询条件参数封装的req

public interface IGoodsService extends IService<Goods> {
    List<Goods>SlectBySupplierId(int id);

    Result search (Long page, Long size, GoodsREQ req);
}

serviceImpl

因为mapper.xml已经对查询条件进行筛选和拼接了,所以这里不做条件的拼接,

传入分页对象和查询条件进行查询。

  @Override
    public Result search(Long page, Long size, GoodsREQ req) {
        /**
         *因为mapper.xml已经对查询条件进行筛选和拼接了
         */
        if (req==null){
            req=new GoodsREQ();
        }
        IPage data = baseMapper.searchPage(new Page<Goods>(page, size), req);
        return Result.ok(data);
    }

control层

@RequestBody (required = false) 表示可以不传查询条件

  @Autowired
    private IGoodsService goodsService;


    /**
     *
     * @param page
     * @param size
     * @param req
     * @return
     *
     */
    @PostMapping("/list/search/{page}/{size}")
    public Result search(
            @PathVariable("page") long page,
            @PathVariable("size") long size,
            @RequestBody (required = false)    GoodsREQ req
            ){

       return goodsService.search(page,size,req);
    }

总结

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

相关文章

  • 深入了解MyBatis二级缓存

    深入了解MyBatis二级缓存

    今天小编就为大家分享一篇关于深入了解MyBatis二级缓存,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12
  • Spring Boot中使用Redis实战案例

    Spring Boot中使用Redis实战案例

    redis作为一个高性能的内存数据库,如果不会用就太落伍了,之前在 node.js中用过 redis,本篇记录如何将 redis 集成到 spring boot 中,下面这篇文章主要给大家介绍了关于Spring Boot中使用Redis的相关资料,需要的朋友可以参考下
    2023-04-04
  • SpringBoot全局异常处理与定制404页面的方法

    SpringBoot全局异常处理与定制404页面的方法

    这篇文章主要介绍了SpringBoot全局异常处理与定制404页面的相关资料,本文通过实例代码图文相结合给大家介绍的非常详细,需要的朋友可以参考下
    2007-09-09
  • 使用SpringBoot项目导入openfeign版本的问题

    使用SpringBoot项目导入openfeign版本的问题

    这篇文章主要介绍了使用SpringBoot项目导入openfeign版本的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • Java程序员新手老手常用的八大开发工具

    Java程序员新手老手常用的八大开发工具

    这篇文章主要介绍了Java程序员新手老手常用的八大开发工具,需要的朋友可以参考下
    2017-05-05
  • java使用ArrayList遍历及效率比较实例分析

    java使用ArrayList遍历及效率比较实例分析

    这篇文章主要介绍了java使用ArrayList遍历及效率比较,实例分析了ArrayList遍历的方法与使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-07-07
  • Java StringBuilder类相关知识总结

    Java StringBuilder类相关知识总结

    这篇文章主要介绍了Java StringBuilder类相关知识总结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • Eclipse 使用Maven构建SpringMVC项目

    Eclipse 使用Maven构建SpringMVC项目

    本文主要介绍在Eclipse下创建Maven项目构建SpringMVC框架的过程,讲解的比较详细,需要的朋友可以参考下。
    2016-06-06
  • Java 中责任链模式实现的三种方式

    Java 中责任链模式实现的三种方式

    本文重点给大家介绍java中如何编写责任链模式。主要从下面3个框架中的代码中介绍。非常不错,需要的朋友参考下吧
    2017-09-09
  • java分治思想之ForkJoin详解

    java分治思想之ForkJoin详解

    这篇文章主要为大家介绍了java分治思想之ForkJoin使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04

最新评论