You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用REST API开发Spring简易市场应用,现有实体后续该如何推进?

开发推进步骤

第一步:修正现有实体类的错误

你当前写的实体类有几处影响功能的映射问题,先修改:

  • User类的@OneToMany映射错误,mappedBy要指向Item类中关联User的属性user,而非id,同时给account设置默认初始值0(你需求里的account自动递增大概率是笔误,id已经配置了自增,账户余额初始默认0即可,如有特殊自增需求再给account加@GeneratedValue)
  • Item类删除冗余的ownerUsername持久化字段,该字段不需要存库,用户修改用户名时会出现数据不一致,直接通过关联的User对象动态返回即可,新增getOwnerId()方法适配接口返回的ownerId字段

修正后的核心代码示例:

// User类修正后的items关联
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
public Set<Item> getItems() {
    return items;
}

// Item类新增方法
public Long getOwnerId() {
    return user.getId();
}
// 删除ownerUsername的set方法,get方法保留动态取值即可

第二步:新增合约实体类Contract

按照需求定义合约字段,继承BaseEntity:

@Entity
@Table(name = "contracts")
public class Contract extends BaseEntity {
    private Long sellerId;
    private Long buyerId;
    private Long itemId;
    private Long price;
    private Boolean active;

    public Contract() {}

    @Column(nullable = false)
    public Long getSellerId() { return sellerId; }
    public void setSellerId(Long sellerId) { this.sellerId = sellerId; }

    public Long getBuyerId() { return buyerId; }
    public void setBuyerId(Long buyerId) { this.buyerId = buyerId; }

    @Column(nullable = false)
    public Long getItemId() { return itemId; }
    public void setItemId(Long itemId) { this.itemId = itemId; }

    @Column(nullable = false)
    public Long getPrice() { return price; }
    public void setPrice(Long price) { this.price = price; }

    @Column(nullable = false)
    public Boolean getActive() { return active; }
    public void setActive(Boolean active) { this.active = active; }
}

第三步:编写DTO类适配入参出参

不要直接返回实体类给前端,单独定义入参和返回DTO:

  • 入参DTO:创建商品DTO、创建合约DTO、更新合约价格DTO、关闭合约DTO
  • 返回DTO:商品查询返回DTO、生效合约返回DTO、已关闭合约返回DTO
    所有字段和你需求里的交互示例字段一一对应即可。

第四步:编写Repository层接口

三个实体分别对应一个Repository,都继承JpaRepository,同时按需求实现单条查询逻辑:

  • ItemRepository:写单条JPQL/原生SQL,关联user表一次查出指定ownerId下所有商品的id、name、ownerId、ownerUsername,避免N+1查询
  • ContractRepository:
    • 写单条原生SQL查询所有生效中合约,关联user表查sellerUsername
    • 写单条动态原生SQL,支持按itemId、sellerId、buyerId可选参数查询已关闭合约,同时关联两次user表分别查sellerUsername和buyerUsername
    • 新增根据itemId查询生效中合约的方法,避免同一个商品重复创建售卖合约

第五步:编写Service层业务逻辑

所有业务规则都在Service层实现,加事务控制避免数据不一致:

  • ItemService:创建商品前校验ownerId对应的用户存在,按ownerId查询商品直接调用Repository的单条查询方法
  • ContractService:
    • 创建合约:校验商品存在、操作人是商品所有者、该商品没有正在生效的售卖合约,保存合约时sellerId取商品的ownerId,active设为true
    • 更新合约价格:校验合约存在、处于生效状态、操作人是合约卖家再更新价格
    • 关闭合约(交易逻辑):校验合约生效、买家不是卖家、买家账户余额≥合约价格,事务内执行4个操作:扣减买家余额、增加卖家余额、修改商品所有者为买家、更新合约active=false并填入buyerId
  • 所有操作的异常情况都抛出对应的业务异常,方便上层统一处理

第六步:编写Controller层REST接口

按照需求暴露接口:

  • 用户相关接口:用户增删改查
  • 商品相关接口:创建商品、按ownerId查询商品
  • 合约相关接口:创建合约、更新合约价格、查询所有生效中合约、关闭合约、按可选参数查询已关闭合约
    入参做参数校验,出参统一封装响应格式。

第七步:配置与测试

  • 配置数据库连接(测试可以先用H2内存数据库)、JPA参数(开启SQL打印、自动建表)
  • 加全局异常处理器,统一捕获业务异常、参数校验异常返回错误信息
  • 用Postman或者curl按照你给出的交互示例逐一测试接口,确认单条查询符合要求、事务正常回滚、业务规则全部满足(比如卖家不能买自己的商品、余额不足无法交易等)

内容的提问来源于stack exchange,提问作者georgik1_

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 10:24:08