基于MybatisPlus实现多表的关联查询,实现分页,多条件查询

1、缘由

实现商品表,通过表内的id关联查询到供应商表的name属性
商品表
如下所示
基于MybatisPlus实现多表的关联查询,实现分页,多条件查询_第1张图片
供应商表
如下所示
基于MybatisPlus实现多表的关联查询,实现分页,多条件查询_第2张图片

新建查询测试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;

/**
 * 

* 商品信息表 *

* * @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
  #  配置日志级别

基于MybatisPlus实现多表的关联查询,实现分页,多条件查询_第3张图片

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);
    }

你可能感兴趣的:(java)