基于Java的仓库管理系统设计与实现(四)

仍在编写后端功能,目前在写出入库管理明细,这里记录一下遇到的问题。

1. 多表联查,联查字段不存在,使用@TableField(exist = false)

查询Product 商品表,与商品类别关联,查询出商品名称,于是在Product实体类中,添加categoryName字段,并添加@TableField(exist = false) 实现查询。
@TableField(exist = false)这个注解表示该字段在数据库表中不存在。当使用 MyBatis-Plus 的自动注入 SQL 语句功能时,会忽略这个字段,不会将其包含在 SQL 查询语句中。通常用于实体类中需要额外计算或处理的字段,而不需要与数据库表中的字段进行映射。

Product.java

package cn.xy21lin.wms_lin.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;

/**
 * <p>
 * 
 * </p>
 *
 * @author 十一月的早晨
 * @since 2025-02-26
 */
@Data
@Accessors(chain = true)
@TableName("biz_product")
@Schema(name = "Product", description = "")
public class Product implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;

    @Schema(description = "商品ID",hidden = true)
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    @Schema(description = "商品名称",example = "可口可乐")
    private String name;

    @Schema(description = "类别ID(关联biz_category)",hidden = true)
    private Long categoryId;

    // ... 其他相关字段

    @Schema(description = "类别名称",example = "饮料")
    @TableField(exist = false)
    private String categoryName;
}

2.多表联查,联查字段不存在,使用Vo类

不操作原提示类,在实体类的基础上,创建一个Vo类,比如入库明细表,多表联查后详细字段很多,就使用了Vo来进行查询结果映射和数据封装返回。再在mapper层、service层、controller层等都用Vo去接收和返回数据,并且在mapper.xml文件指定Vo类名,确定好映射接收类。

StockInItemDetailVo.java

package cn.xy21lin.wms_lin.vo;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.experimental.Accessors;

import java.math.BigDecimal;
import java.time.LocalDateTime;

@Data
@Schema(description = "入库明细")
@Accessors(chain = true)
public class StockInItemDetailVo {

    @Schema(description = "明细ID",hidden = true)
    private Long id;

    @Schema(description = "数量",hidden = true)
    private Integer quantity;

    @Schema(description = "进货单价", hidden = true)
    private BigDecimal price;

    @Schema(description = "进货总价",hidden = true)
    private BigDecimal totalAmount;

    @Schema(description = "创建时间",hidden = true)
    private LocalDateTime gmtCreate;

    @Schema(description = "入库备注",hidden = true)
    private String remark;

    @Schema(description = "商品名称",hidden = true)
    private String productName;

    @Schema(description = "商品类别",hidden = true)
    private String categoryName;

    @Schema(description = "供应商名称",hidden = true)
    private String supName;

    @Schema(description = "操作员账号",hidden = true)
    private String userName;

    @Schema(description = "操作员姓名",hidden = true)
    private String realName;
}

StockInItemMapper.xml

<!-- 指定映射类为Vo-->
<select id="selectStockInInfo" resultType="cn.xy21lin.wms_lin.vo.StockInItemDetailVo">
  <!-- sql查询语句 -->
</select>

3. 使用日期进行条件查询

3.1 格式问题

我想在SQL中使用DAY()函数来获取传入日期的具体天数,与表中gmt_create字段进行比较查询,实现查询指定日期的明细数据,在数据库中查询没有问题,拿到idea中,运行报错,
JSON parse error: Cannot deserialize value of type java.time.LocalDateTime from String "2025-02-28 14:49:09": Failed to deserialize java.time.LocalDateTime: (java.time.format.DateTimeParseException) Text '2025-02-28 14:49:09' could not be parsed at index 10
简单来说,就是日期格式有问题,我传入的"gmtCreate": "2025-03-10 14:49:09"不能转换到LocalDateTime类型,JSON中的日期时间格式与LocalDateTime不匹配
解决办法也很简单,解析不了我传入的字符串的日期,那我就指定一个日期格式。使用@JsonFormat注解指定日期时间格式。

StockInItemDetailVo.java

package cn.xy21lin.wms_lin.vo;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.experimental.Accessors;

import java.math.BigDecimal;
import java.time.LocalDateTime;

@Data
@Schema(description = "入库明细")
@Accessors(chain = true)
public class StockInItemDetailVo {

    @Schema(description = "明细ID",hidden = true)
    private Long id;

    @Schema(description = "数量",hidden = true)
    private Integer quantity;

    @Schema(description = "进货单价", hidden = true)
    private BigDecimal price;

    @Schema(description = "创建时间",hidden = true)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime gmtCreate;
    // 省略其他字段
}

3.2 不合法的比较操作

解决了日期格式的问题,新问题随之而来,java.lang.IllegalArgumentException: invalid comparison: java.time.LocalDateTime and java.lang.String,简单看一下,就是日期和字符串的比较问题,拿日期与字符串进行了比较,仔细查看一遍,原来是对应的mapper.xml中出现的问题。

修改前:StockInItemMapper.xml

  <!-- 省略其余sql语句-->
  <where>
      <if test="stock.supName !='' and stock.supName != null">
          and sup.`name` like concat('%',#{stock.supName},'%')
      </if>
      <if test="stock.gmtCreate != '' and stock.gmtCreate != null">
          and DAY(sin.gmt_create)  = DAY(#{stock.gmtCreate})
      </if>
  </where>

原来是因为这里,拿gmtCreate与空字符串进行了比较,导致发生错误,鉴定完毕,原因为复制顺手了,直接一划拉全粘贴,删掉即可。

修改后:StockInItemMapper.xml

  <!-- 省略其余sql语句-->
  <where>
      <if test="stock.supName !='' and stock.supName != null">
          and sup.`name` like concat('%',#{stock.supName},'%')
      </if>
      <if test="stock.gmtCreate != null">
          and DAY(sin.gmt_create)  = DAY(#{stock.gmtCreate})
      </if>
  </where>

4. 结果测试

再次发起请求,看看能否拿下

curl -X 'POST' \
  'http://localhost:8080/warehouse/stockInItem/list' \
  -H 'accept: */*' \
  -H 'token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYmYiOjE3NDE1OTQ5NzcsImV4cCI6MTc0MTY4MTM3NywidXNlcklkIjo1LCJpYXQiOjE3NDE1OTQ5NzcsInVzZXJuYW1lIjoiZGFoYWkifQ.TLwe3stmZQlit1sTp1jgbetqBdjB6Vf_E6Jm-QfUdek' \
  -H 'Content-Type: application/json' \
  -d '{
  "pageNum": "1",
  "pageSize": "3",
  "data": {
    "gmtCreate": "2025-03-10 14:49:09"
  }
}'

请求结果:

{
  "code": 200,
  "message": "获取成功",
  "data": {
    "records": [
      {
        "id": 1,
        "quantity": 100,
        "price": 40,
        "totalAmount": 4000,
        "gmtCreate": "2025-03-10 16:59:13",
        "remark": "请批准",
        "productName": "可口可乐 330ml",
        "categoryName": "饮料",
        "supName": "可口可乐公司",
        "userName": "operator1",
        "realName": "李四"
      }
    ],
    "total": 1,
    "size": 3,
    "current": 1,
    "pages": 1
  },
  "success": true
}

大功告成,今天休息

5. Git 推送

还是老操作
git add .
git commit -m "出入库管理功能完成"
git push origin master