上一篇中,我们介绍了项目的基本架构和相关知识。这一篇,我们将在上一篇已搭建好的项目基础架构上进行整合 MyBatis-Plus 、Knife4j。

1. 整合 MyBatis-Plus

1.1. 关于 MyBatis-Plus

MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。关于 MyBatis-Plus 的具体介绍,请参照官方文档( 链接地址)。Spring Cloud Alibaba

1.2. 版本选择

由于我们项目使用的是 Spring Boot 3.0.2,需要 MyBatis-Plus3.5.3 及以上版本才支持,我们选择

MyBatis-Plus 的版本为 3.5.3.1。

1.3. 项目整合

1.3.1. 创建组件

我们在使用 MyBatis-Plus 的时候,也经常会对它的一些特性进行封装。因此,我们将在 mall-component 工程下创建一个 MyBatis-Plus 的工程,作为组件工程,供各个模块使用。

在 mall-component 工程下创建名称为 mall-component-mybatis 的子工程。

mall-component-mybatis 工程的 pom.xml 文件内容如下。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.example.component</groupId>
        <artifactId>mall-component</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>mall-component-mybatis</artifactId>
    <name>mall-component-mybatis</name>
    <description>mybatis组件</description>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>

    <dependencies>

        <!-- mybatis-plus 3.5.3及以上版本 才支持 spring boot 3-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.3.1</version>
        </dependency>

    </dependencies>

</project>

在 mall-component-mybatis 工程中创建 org.example.component.mybatis.config 包目录,在该包目录下创建 MyBatis-Plus 配置类,取名为:MybatisPlusConfig。

MybatisPlusConfig 内容如下。

@Configuration
public class MybatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        //添加分页拦截器
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        //添加乐观锁拦截器
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }

}

mall-component-mybatis 组件工程结构如下。

基于 COLA 架构的 Spring Cloud Alibaba(二)整合 MyBatis-Plus、 Knife4j_MyBatis-Plus、Knife4j

1.3.2. 使用组件

在上面,我们已经创建好了 mall-component-mybatis 组件工程,下面就要被账户模块、商品模块、订单模块依赖使用了。

由于我们的 model 是放在 domain 层工程的,model 中实体类的字段会涉及到 MyBatis-Plus 的东西,加上 infra 层工程需要依赖 domain 层工程,我们就将 mall-component-mybatis 组件依赖添加在domain 层工程中。

分别在账户模块、商品模块、订单模块的 domain 层工程的 pom.xml 添加如下依赖。

<!--mybatis-->
<dependency>
  <groupId>org.example.component</groupId>
  <artifactId>mall-component-mybatis</artifactId>
  <version>1.0-SNAPSHOT</version>
</dependency>

账户模块 domain 层工程的 pom.xml 添加依赖后,内容如下。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.example.account</groupId>
        <artifactId>mall-account-center</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>mall-account-center-domain</artifactId>
    <name>mall-account-center-domain</name>
    <description>领域层</description>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!--mall-account-center-dto-->
        <dependency>
            <groupId>org.example.account</groupId>
            <artifactId>mall-account-center-dto</artifactId>
        </dependency>
        <!--mybatis-->
        <dependency>
            <groupId>org.example.component</groupId>
            <artifactId>mall-component-mybatis</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

商品模块 domain 层工程的 pom.xml 添加依赖后,内容如下。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.example.product</groupId>
        <artifactId>mall-product-center</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>mall-product-center-domain</artifactId>
    <name>mall-product-center-domain</name>
    <description>领域层</description>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!--mall-product-center-dto-->
        <dependency>
            <groupId>org.example.product</groupId>
            <artifactId>mall-product-center-dto</artifactId>
        </dependency>
        <!--mybatis-->
        <dependency>
            <groupId>org.example.component</groupId>
            <artifactId>mall-component-mybatis</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

    </dependencies>

</project>

订单模块 domain 层工程的 pom.xml 添加依赖后,内容如下。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.example.order</groupId>
        <artifactId>mall-order-center</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>mall-order-center-domain</artifactId>
    <name>mall-order-center-domain</name>
    <description>领域层</description>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!--mall-order-center-dto-->
        <dependency>
            <groupId>org.example.order</groupId>
            <artifactId>mall-order-center-dto</artifactId>
        </dependency>
        <!--mybatis-->
        <dependency>
            <groupId>org.example.component</groupId>
            <artifactId>mall-component-mybatis</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

    </dependencies>

</project>

1.3.3. 实体类创建

创建数据库表 mall_account、mall_product、mall_order 对应的实体类,类名分别为:AccountEntity、ProductEntity、OrderEntity。MyBatis-Plus也有代码生成器,可以利用代码生成器生成。

AccountEntity 内容如下。

@Data
@Accessors(chain = true)
@TableName("mall_account")
public class AccountEntity extends  Model<AccountEntity> {

    private static final long serialVersionUID = 1L;

    /**
     * 主键id
     */
    @TableId(value = "id", type = IdType.ASSIGN_ID)
    private Long id;

    /**
     * 用户id
     */
    @TableField("user_id")
    private Long userId;

    /**
     * 账户code
     */
    @TableField("account_code")
    private String accountCode;

    /**
     * 账户名称
     */
    @TableField("account_name")
    private String accountName;

    /**
     * 金额
     */
    @TableField("amount")
    private BigDecimal amount;

    /**
     * 是否被删除
     */
    @TableField("is_deleted")
    public Integer isDeleted;

    /**
     * 创建人
     */
    @TableField("created_by")
    public Long createdBy;

    /**
     * 创建时间
     */
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @TableField("created_time")
    public Date createdTime;

    /**
     * 修改人
     */
    @TableField("updated_by")
    public Long updatedBy;

    /**
     * 修改时间
     */
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @TableField("updated_time")
    public Date updatedTime;

    /**
     * 版本号
     */
    @Version
    @TableField("reversion")
    private Integer reversion;

    @Override
    public Serializable pkVal() {
        return this.id;
    }
}

ProductEntity 内容如下。

@Data
@Accessors(chain = true)
@TableName("mall_product")
public class ProductEntity extends  Model<ProductEntity> {

    private static final long serialVersionUID = 1L;

    /**
     * 主键id
     */
    @TableId(value = "id", type = IdType.ASSIGN_ID)
    private Long id;

    /**
     * 商品code
     */
    @TableField("product_code")
    private String productCode;

    /**
     * 商品名称
     */
    @TableField("product_name")
    private String productName;

    /**
     * 商品数量
     */
    @TableField("count")
    private Integer count;

    /**
     * 商品价格
     */
    @TableField("price")
    private BigDecimal price;

    /**
     * 是否被删除
     */
    @TableField("is_deleted")
    public Integer isDeleted;

    /**
     * 创建人
     */
    @TableField("created_by")
    public Long createdBy;

    /**
     * 创建时间
     */
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @TableField("created_time")
    public Date createdTime;

    /**
     * 修改人
     */
    @TableField("updated_by")
    public Long updatedBy;

    /**
     * 修改时间
     */
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @TableField("updated_time")
    public Date updatedTime;

    /**
     * 版本号
     */
    @Version
    @TableField("reversion")
    private Integer reversion;

    @Override
    public Serializable pkVal() {
        return this.id;
    }
}

OrderEntity 内容如下。

@Data
@Accessors(chain = true)
@TableName("mall_order")
public class OrderEntity extends  Model<OrderEntity> {

    private static final long serialVersionUID = 1L;

    /**
     * 主键id
     */
    @TableId(value = "id", type = IdType.ASSIGN_ID)
    private Long id;

    /**
     * 订单编号
     */
    @TableField("order_no")
    private String orderNo;

    /**
     * 账户code
     */
    @TableField("account_code")
    private String accountCode;

    /**
     * 商品编号
     */
    @TableField("product_code")
    private String productCode;

    /**
     * 商品数量
     */
    @TableField("count")
    private Integer count;

    /**
     * 金额
     */
    @TableField("amount")
    private BigDecimal amount;

    /**
     * 是否被删除
     */
    @TableField("is_deleted")
    public Integer isDeleted;

    /**
     * 创建人
     */
    @TableField("created_by")
    public Long createdBy;

    /**
     * 创建时间
     */
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @TableField("created_time")
    public Date createdTime;

    /**
     * 修改人
     */
    @TableField("updated_by")
    public Long updatedBy;

    /**
     * 修改时间
     */
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @TableField("updated_time")
    public Date updatedTime;

    /**
     * 版本号
     */
    @Version
    @TableField("reversion")
    private Integer reversion;

    @Override
    public Serializable pkVal() {
        return this.id;
    }
}

1.3.4. Mapper 接口创建

创建实体类 AccountEntity、ProductEntity、OrderEntity 对应的 Mapper 接口,名称分别为:AccountMapper、ProductMapper、OrderMapper。

AccountMapper 内容如下。

@Mapper
public interface AccountMapper extends BaseMapper<AccountEntity> {
    
}

ProductMapper 内容如下。

@Mapper
public interface ProductMapper extends BaseMapper<ProductEntity> {

}

OrderMapper 内容如下。

@Mapper
public interface OrderMapper extends BaseMapper<OrderEntity> {

}

1.3.5. 领域接口创建

创建实体类 AccountEntity、ProductEntity、OrderEntity 对应的领域接口,名称分别为:AccountService、ProductService、OrderService。

AccountService 内容如下。

public interface AccountService extends IService<AccountEntity> {

    
    /**
     *  新增账户
     */
    void add(AccountReqDTO accountReqDTO,Long id) throws BaseException;

    /**
     *  编辑账户
     */
    void edit(AccountReqDTO accountReqDTO) throws BaseException;

	/**
     *  扣减金额
     */
    void reduceAmount(Long id, BigDecimal amount) throws BizException;

    /**
     * 分页查询账户列表
     */
     PageDTO<AccountRspDTO> pageList(PageQuery<AccountQuery> pageQuery);

    /**
     *查询满足条件的记录
     */
     List<AccountRspDTO> queryList(AccountQuery accountQuery);
}

ProductService 内容如下。

public interface ProductService extends IService<ProductEntity> {

    /**
     *  新增商品
     */
    void add(ProductReqDTO productReqDTO,Long id) throws BaseException;

    /**
     *  编辑商品
     */
    void edit(ProductReqDTO productReqDTO) throws BaseException;

     /**
     * 扣减数量
     */
    void reduceCount(Long id, Integer count) throws BizException;

    /**
     *分页查询账户列表
     */
     PageDTO<ProductRspDTO> pageList(PageQuery<ProductQuery> pageQuery);

    /**
     *查查满足条件的记录
     */
     List<ProductRspDTO> queryList(ProductQuery productQuery);
}

OrderService 内容如下。

public interface OrderService extends IService<OrderEntity> {

     /**
     *  新增订单
     */
    void add(OrderReqDTO orderReqDTO, Long id) throws BaseException;

    /**
     *  编辑订单
     */
    void edit(OrderReqDTO orderReqDTO) throws BaseException;

    /**
     *分页查询账户列表
     */
     PageDTO<OrderRspDTO> pageList(PageQuery<OrderQuery> pageQuery);

    /**
     *查询满足条件的记录
     */
     List<OrderRspDTO> queryList(OrderQuery productQuery);
}

上面的 PageQuery,从 COLA 官方项目中拷贝过来稍加修改作为公共组件使用。AccountQuery、ProductQuery、OrderQuery 分别创建在各模块的 dto 组件工程下作为每个模块的列表查询入参。

1.3.6. 领域接口实现类创建

创建 AccountService、ProductService、OrderService 对应的实现类,名称分别为:AccountServiceImpl、ProductServiceImpl、OrderServiceImpl。

AccountServiceImpl 内容如下。

@Service
public class AccountServiceImpl extends ServiceImpl<AccountMapper, AccountEntity> implements AccountService {

    /**
     *构建查询信息
     */
    private LambdaQueryWrapper<AccountEntity> buildAccountLambdaQueryWrapper(AccountQuery accountQuery){
        LambdaQueryWrapper<AccountEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        if(Objects.nonNull(accountQuery)){
            lambdaQueryWrapper.eq(Objects.nonNull(accountQuery.getId()),AccountEntity::getId,accountQuery.getId());
        	lambdaQueryWrapper.like(Objects.nonNull(accountQuery.getAccountCode()),AccountEntity::getAccountCode,accountQuery.getAccountCode());
        	lambdaQueryWrapper.like(Objects.nonNull(accountQuery.getAccountName()),AccountEntity::getAccountName,accountQuery.getAccountName());
        }
        return lambdaQueryWrapper;
    }

    @Override
    public void add(AccountReqDTO accountReqDTO, Long id) throws BaseException {
        AccountEntity accountEntity = new AccountEntity();
        BeanUtils.copyProperties(accountReqDTO,accountEntity);
        accountEntity.setId(id);
        accountEntity.setCreatedBy(1L);
        accountEntity.setCreatedTime(new Date());
        try {
            this.save(accountEntity);
        } catch (Exception e) {
            e.printStackTrace();
            throw ExceptionFactory.sysException("新增账户,保存数据异常");
        }
    }

     @Override
    public void edit(AccountReqDTO accountReqDTO) throws BaseException {
        AccountEntity accountEntity = this.getById(accountReqDTO.getId());
        if(Objects.isNull(accountEntity)){
            throw ExceptionFactory.bizException("账户信息不存在!");
        }
        BeanUtils.copyProperties(accountReqDTO,accountEntity);
        accountEntity.setUpdatedBy(1L);
        accountEntity.setUpdatedTime(new Date());
        try {
            this.updateById(accountEntity);
        } catch (Exception e) {
            e.printStackTrace();
            throw ExceptionFactory.sysException("编辑账户,保存数据异常");
        }
    }
    
    @Override
    public void reduceAmount(Long id, BigDecimal amount) throws BizException {
        AccountEntity accountEntity = this.getById(id);
        if(Objects.isNull(accountEntity)){
            throw ExceptionFactory.bizException("账户信息不存在!");
        }
        accountEntity.setAmount(accountEntity.getAmount().subtract(amount));
        accountEntity.setUpdatedBy(1L);
        accountEntity.setUpdatedTime(new Date());
        this.updateById(accountEntity);
    }
    
    @Override
    public PageDTO<AccountRspDTO> pageList(PageQuery<AccountQuery> pageQuery) {
        PageDTO<AccountEntity> page = new PageDTO<>();

        AccountQuery accountQuery = pageQuery.getQuery();
        LambdaQueryWrapper<AccountEntity> lambdaQueryWrapper = this.buildAccountLambdaQueryWrapper(accountQuery);
        page.setSize(pageQuery.getSize());
        page.setCurrent(pageQuery.getCurrent());
        page = this.page(page,lambdaQueryWrapper);

        PageDTO<AccountRspDTO>  pageAccountRspDTO = (PageDTO<AccountRspDTO>)page.convert(accountEntity->{
            AccountRspDTO accountRspDTO = new AccountRspDTO();
            BeanUtils.copyProperties(accountEntity,accountRspDTO);
            return accountRspDTO;
        });
        return pageAccountRspDTO;
    }

    @Override
    public List<AccountRspDTO> queryList(AccountQuery accountQuery) {
        LambdaQueryWrapper<AccountEntity> lambdaQueryWrapper = this.buildAccountLambdaQueryWrapper(accountQuery);
        List<AccountEntity> accountEntityList = this.list(lambdaQueryWrapper);
        if(!CollectionUtils.isEmpty(accountEntityList)){
            List<AccountRspDTO> accountRspDTOList = accountEntityList.stream().map(accountEntity->{
                AccountRspDTO accountRspDTO = new AccountRspDTO();
                BeanUtils.copyProperties(accountEntity,accountRspDTO);
                return accountRspDTO;
            }).collect(Collectors.toList());
            return accountRspDTOList;
        }
        return null;
    }
}

ProductServiceImpl 内容如下。

@Service
public class ProductServiceImpl extends ServiceImpl<ProductMapper, ProductEntity> implements ProductService {


    /**
     *构建查询信息
     */
    private LambdaQueryWrapper<ProductEntity> buildProductLambdaQueryWrapper(ProductQuery productQuery){
        LambdaQueryWrapper<ProductEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Objects.nonNull(productQuery.getId()), ProductEntity::getId,productQuery.getId());
        lambdaQueryWrapper.like(Objects.nonNull(productQuery.getProductCode()), ProductEntity::getProductCode,productQuery.getProductCode());
        lambdaQueryWrapper.like(Objects.nonNull(productQuery.getProductName()), ProductEntity::getProductName,productQuery.getProductName());
        return lambdaQueryWrapper;
    }

      @Override
    public void add(ProductReqDTO productReqDTO, Long id) throws BaseException {
        ProductEntity productEntity = new ProductEntity();
        BeanUtils.copyProperties(productReqDTO,productEntity);
        productEntity.setId(id);
        productEntity.setCreatedBy(1L);
        productEntity.setCreatedTime(new Date());
        try {
            this.save(productEntity);
        } catch (Exception e) {
            e.printStackTrace();
            throw ExceptionFactory.sysException("新增商品,保存数据异常");
        }
    }

    @Override
    public void edit(ProductReqDTO productReqDTO) throws BaseException {
        ProductEntity productEntity = this.getById(productReqDTO.getId());
        if(Objects.isNull(productEntity)){
            throw ExceptionFactory.bizException("商品信息不存在!");
        }
        BeanUtils.copyProperties(productReqDTO,productEntity);
        productEntity.setUpdatedBy(1L);
        productEntity.setUpdatedTime(new Date());
        try {
            this.updateById(productEntity);
        } catch (Exception e) {
            e.printStackTrace();
            throw ExceptionFactory.sysException("编辑商品,保存数据异常");
        }
    }

     @Override
    public void reduceCount(Long id, Integer count) throws BizException {
        ProductEntity productEntity = this.getById(id);
        if(Objects.isNull(productEntity)){
            throw ExceptionFactory.bizException("商品信息不存在!");
        }
        productEntity.setCount(productEntity.getCount()-count);
        productEntity.setUpdatedBy(1L);
        productEntity.setUpdatedTime(new Date());
        this.updateById(productEntity);
    }

    @Override
    public PageDTO<ProductRspDTO> pageList(PageQuery<ProductQuery> pageQuery) {
        PageDTO<ProductEntity> page = new PageDTO<>();

        ProductQuery productQuery = pageQuery.getQuery();
        LambdaQueryWrapper<ProductEntity> lambdaQueryWrapper = this.buildProductLambdaQueryWrapper(productQuery);
        page.setSize(pageQuery.getSize());
        page.setCurrent(pageQuery.getCurrent());
        page = this.page(page,lambdaQueryWrapper);

        PageDTO<ProductRspDTO>  pageProductRspDTO = (PageDTO<ProductRspDTO>)page.convert(productEntity->{
            ProductRspDTO productRspDTO = new ProductRspDTO();
            BeanUtils.copyProperties(productEntity,productRspDTO);
            return productRspDTO;
        });
        return pageProductRspDTO;
    }

    @Override
    public List<ProductRspDTO> queryList(ProductQuery ProductQuery) {
        LambdaQueryWrapper<ProductEntity> lambdaQueryWrapper = this.buildProductLambdaQueryWrapper(ProductQuery);
        List<ProductEntity> ProductEntityList = this.list(lambdaQueryWrapper);
        if(!CollectionUtils.isEmpty(ProductEntityList)){
            List<ProductRspDTO> ProductRspDTOList = ProductEntityList.stream().map(productEntity->{
                ProductRspDTO ProductRspDTO = new ProductRspDTO();
                BeanUtils.copyProperties(productEntity,ProductRspDTO);
                return ProductRspDTO;
            }).collect(Collectors.toList());
            return ProductRspDTOList;
        }
        return null;
    }
}

OrderServiceImpl 内容如下。

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, OrderEntity> implements OrderService {

    /**
     *构建查询信息
     */
    private LambdaQueryWrapper<OrderEntity> buildOrderLambdaQueryWrapper(OrderQuery orderQuery){
        LambdaQueryWrapper<OrderEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Objects.nonNull(orderQuery.getId()), OrderEntity::getId,orderQuery.getId());
        lambdaQueryWrapper.like(Objects.nonNull(orderQuery.getOrderNo()), OrderEntity::getOrderNo,orderQuery.getOrderNo());
        lambdaQueryWrapper.like(Objects.nonNull(orderQuery.getAccountCode()), OrderEntity::getAccountCode,orderQuery.getAccountCode());
        lambdaQueryWrapper.like(Objects.nonNull(orderQuery.getProductCode()), OrderEntity::getProductCode,orderQuery.getProductCode());
        return lambdaQueryWrapper;
    }

     @Override
    public void add(OrderReqDTO orderReqDTO, Long id) throws BaseException {
        OrderEntity orderEntity = new OrderEntity();
        BeanUtils.copyProperties(orderReqDTO,orderEntity);
        String orderNo = "DD"+System.currentTimeMillis();
        orderEntity.setId(id);
        orderEntity.setOrderNo(orderNo);
        orderEntity.setCreatedBy(1L);
        orderEntity.setCreatedTime(new Date());
        try {
            this.save(orderEntity);
        } catch (Exception e) {
            e.printStackTrace();
            throw ExceptionFactory.sysException("新增订单,保存数据异常");
        }
    }

    @Override
    public void edit(OrderReqDTO orderReqDTO) throws BaseException {
        OrderEntity orderEntity = this.getById(orderReqDTO.getId());
        if(Objects.isNull(orderEntity)){
            throw ExceptionFactory.bizException("订单信息不存在!");
        }
        BeanUtils.copyProperties(orderReqDTO,orderEntity);
        orderEntity.setUpdatedBy(1L);
        orderEntity.setUpdatedTime(new Date());
        try {
            this.updateById(orderEntity);
        } catch (Exception e) {
            e.printStackTrace();
            throw ExceptionFactory.sysException("编辑订单,保存数据异常");
        }
    }

    @Override
    public PageDTO<OrderRspDTO> pageList(PageQuery<OrderQuery> pageQuery) {
        PageDTO<OrderEntity> page = new PageDTO<>();

        OrderQuery orderQuery = pageQuery.getQuery();
        LambdaQueryWrapper<OrderEntity> lambdaQueryWrapper = this.buildOrderLambdaQueryWrapper(orderQuery);
        page.setSize(pageQuery.getSize());
        page.setCurrent(pageQuery.getCurrent());
        page = this.page(page,lambdaQueryWrapper);

        PageDTO<OrderRspDTO>  pageOrderRspDTO = (PageDTO<OrderRspDTO>)page.convert(orderEntity->{
            OrderRspDTO orderRspDTO = new OrderRspDTO();
            BeanUtils.copyProperties(orderEntity,orderRspDTO);
            return orderRspDTO;
        });
        return pageOrderRspDTO;
    }

    @Override
    public List<OrderRspDTO> queryList(OrderQuery OrderQuery) {
        LambdaQueryWrapper<OrderEntity> lambdaQueryWrapper = this.buildOrderLambdaQueryWrapper(OrderQuery);
        List<OrderEntity> OrderEntityList = this.list(lambdaQueryWrapper);
        if(!CollectionUtils.isEmpty(OrderEntityList)){
            List<OrderRspDTO> OrderRspDTOList = OrderEntityList.stream().map(orderEntity->{
                OrderRspDTO OrderRspDTO = new OrderRspDTO();
                BeanUtils.copyProperties(orderEntity,OrderRspDTO);
                return OrderRspDTO;
            }).collect(Collectors.toList());
            return OrderRspDTOList;
        }
        return null;
    }
}

2. 整合 Knife4j

2.1. 关于 Knife4j

Knife4j 是为 Java MVC 框架集成 Swagger 生成 Api 文档的增强解决方案,前身是 swagger-bootstrap-ui。关于 Knife4j 的具体介绍,请参照官方文档(链接地址)。

2.2. 版本选择

由于我们项目使用的是 Spring Boot 3.0.2,Knife4j 需要4.0及以上版本才适配。目前最新版本为4.3.0,那我们选择 Knife4j 的版本为4.3.0。

2.3. 项目整合

2.3.1. 添加 Knife4j

2.3.1.1. 添加依赖

Knife4j 的注解一般都是添加在 DTO 或 Controller 上的,在 Controller 的方法中,DTO 又往往被作为入参或出参。因此本系列将 knife4j 的依赖添加在 DTO 文件所在的地方。本系列将 COLA 官方项目的部分 DTO 拷贝到 mall-component-common 工程中作为公共组件,为使 mall-component-common 工程中的 DTO 也能使用 knife4j 的注解,于是将 knife4j 的依赖添加到 mall-component-common 工程中。

mall-component-common 工程中的 pom.xml 文件内容如下。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.example.component</groupId>
        <artifactId>mall-component</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>mall-component-common</artifactId>
    <name>mall-component-common</name>
    <description>组件工具</description>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.26</version>
        </dependency>
        <!--fastjson-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>2.0.32</version>
        </dependency>
        <!-- https://www.pangugle.com/lib/maven/view/cn.hutool/hutool-all.html -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.19</version>
        </dependency>
        <!--knife4j-->
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
            <version>4.3.0</version>
        </dependency>
    </dependencies>
</project>
2.3.1.2. 添加注解

以账户模块为例,给 AccountReqDTO 添加注解后如下。

@Schema(name = "AccountReqDTO",description = "account入参DTO")
@Data
public class AccountReqDTO extends DTO implements Serializable {

    private static final long serialVersionUID = 1L;

    @Schema(description = "主键id,新增时,不必传,编辑时,必传。")
    private Long id;

    @Schema(description = "用户id")
    private Long userId;

    @Schema(description = "账户code")
    private String accountCode;

    @Schema(description = "账户名称")
    private String accountName;

    @Schema(description = "金额")
    private BigDecimal amount;
}
2.3.1.3. 添加分组

由于我们的适配层(Adapter Layer)接口根据 web、wireless、wap 等类型的适配做了归类,我们也的 knife4j 文档也可以按此进行分组。以账户模块为例,在 mall-account-center-dto 工程中创建org.example.account.config 包目录,在该目录下创建 knife4j 配置类,名称为:Knife4jConfig。

Knife4jConfig 内容如下。

@Configuration
@EnableKnife4j
public class Knife4jConfig {


    private static final String GLOBAL_HEADER = "header";
    private static final String GLOBAL_TOKEN = "token";


    @Bean
    public GroupedOpenApi webApi() {
        return GroupedOpenApi.builder()
                .group("adapter-"+BaseConstant.AdapterType.WEB)
                .pathsToMatch("/"+ BaseConstant.AdapterType.WEB+"/**")
                .build();
    }

    @Bean
    public GroupedOpenApi wapApi() {
        return GroupedOpenApi.builder()
                .group("adapter-"+BaseConstant.AdapterType.WAP)
                .pathsToMatch("/"+ BaseConstant.AdapterType.WAP+"/**")
                .build();
    }

    @Bean
    public GroupedOpenApi wirelessApi() {
        return GroupedOpenApi.builder()
                .group("adapter-"+BaseConstant.AdapterType.WIRELESS)
                .pathsToMatch("/"+ BaseConstant.AdapterType.WIRELESS+"/**")
                .build();
    }

    @Bean
    public OpenAPI openAPI() {
        return new OpenAPI().info(info()).components(new Components()
                .addSecuritySchemes(GLOBAL_TOKEN,
                        new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("bearer").bearerFormat("JWT")));
    }

    private Info info() {
        return new Info()
                .title("账户服务-API文档")
                .version("v1.0")
                .description("本文档描述了后端微服务接口定义")
                .termsOfService("https://www.xxx.com")
                .license(new License().name("Apache 2.0").url("https://springdoc.org"));
    }
}

对应 Knife4j 配置,也支持在 yml 文件中进行配置,例如官方示例。

基于 COLA 架构的 Spring Cloud Alibaba(二)整合 MyBatis-Plus、 Knife4j_COLA_02

2.3.2. 添加前端控制器

分别在账户模块、商品模块、订单模块的适配层 web 目录下,创建前端控制器,添加对应的 CRUD 接口,前端控制器名称分别为:AccountController、ProductController、OrderController。

AccountController 内容如下。

@Slf4j
@Tag(name = "account-wep端api")
@RestController
@RequestMapping(BaseConstant.AdapterType.WEB+"/v1/account")
public class AccountController {

    @Resource
    private AccountExecutor accountExecutor;

    @Operation(summary = "新增账户")
    @PostMapping("/add")
    public ResponseResult<String> add(@RequestBody AccountReqDTO accountReqDTO){
        log.info("add account, accountReqDTO:{}",accountReqDTO);
        this.accountExecutor.addAccount(accountReqDTO);
        return ResponseResult.ok("add account succeed");
    }

    @Operation(summary = "编辑账户")
    @PostMapping("/edit")
    public  ResponseResult<String> edit(@RequestBody AccountReqDTO accountReqDTO){
        log.info("edit account, accountReqDTO:{}",accountReqDTO);
        this.accountExecutor.editAccount(accountReqDTO);
        return ResponseResult.ok("update account succeed");
    }

    @Operation(summary = "根据id删除账户")
    @PostMapping("/removeById")
    @Parameter(name = "id",description = "主键id",required = true)
    public ResponseResult<String> removeById(@RequestParam Long id){
        log.info("delete account,id is {}",id);
        this.accountExecutor.removeAccountById(id);
        return ResponseResult.ok("delete account succeed");
    }

    @Operation(summary = "根据id查询账户")
    @GetMapping("/queryById/{id}")
    @Parameter(name = "id",description = "主键id",required = true)
    public ResponseResult<AccountRspDTO> queryById(@PathVariable(value = "id") Long id){
        log.info("query account detail,id is :{}",id);
        AccountRspDTO accountRspDTO = this.accountExecutor.queryAccountById(id);
        return ResponseResult.ok(accountRspDTO);
    }

    @Operation(summary = "分页查询账户列表")
    @PostMapping("/pageList")
    public ResponseResult<PageDTO<AccountRspDTO> > pageList(@RequestBody PageQuery<AccountQuery>  pageQuery){
        log.info("page account list, pageQuery:{}",pageQuery);
        PageDTO<AccountRspDTO> pageDTO = this.accountExecutor.pageAccountList(pageQuery);
        return ResponseResult.ok(pageDTO);
    }

    @Operation(summary = "查查满足条件的记录")
    @PostMapping("/queryList")
    public ResponseResult<List<AccountRspDTO>> queryList(@RequestBody AccountQuery accountQuery){
        log.info("query account list, accountQuery:{}",accountQuery);
        List<AccountRspDTO> dtoList = this.accountExecutor.queryAccountList(accountQuery);
        return ResponseResult.ok(dtoList);
    }

    @Operation(summary = "扣减金额")
    @PostMapping("/reduceAmount")
    @Parameters ({
            @Parameter(name = "id",description = "主键id",required = true),
            @Parameter(name = "amount",description = "金额",required = true)
    })
    public  ResponseResult<String> reduceAmount(@RequestParam("id") Long id,@RequestParam("amount") BigDecimal amount){
        log.info("reduce account amount, id:{},amount:{}",id,amount);
        this.accountExecutor.reduceAccountAmount(id,amount);
        return ResponseResult.ok("reduce amount succeed");
    }
}

ProductController 内容如下。

@Slf4j
@Tag(name = "product-wep端api")
@RestController
@RequestMapping(BaseConstant.AdapterType.WEB+"/v1/product")
public class ProductController {

    @Resource
    private ProductExecutor productExecutor;

    @Operation(summary = "新增商品")
    @PostMapping("/add")
    public ResponseResult<String> add(@RequestBody ProductReqDTO productReqDTO){
        log.info("add product, productReqDTO:{}",productReqDTO);
        this.productExecutor.addProduct(productReqDTO);
        return ResponseResult.ok("add Product succeed");
    }

    @Operation(summary = "编辑商品")
    @PostMapping("/edit")
    public  ResponseResult<String> edit(@RequestBody ProductReqDTO productReqDTO){
        log.info("edit product, productReqDTO:{}",productReqDTO);
        this.productExecutor.editProduct(productReqDTO);
        return ResponseResult.ok("update Product succeed");
    }

    @Operation(summary = "根据id删除商品")
    @PostMapping("/removeById")
    @Parameter(name = "id",description = "主键id",required = true)
    public ResponseResult<String> removeById(@RequestParam Long id){
        log.info("delete product,id is {}",id);
        this.productExecutor.removeProductById(id);
        return ResponseResult.ok("delete Product succeed");
    }

    @Operation(summary = "根据id查询商品")
    @GetMapping("/queryById/{id}")
    @Parameter(name = "id",description = "主键id",required = true)
    public ResponseResult<ProductRspDTO> queryById(@PathVariable(value = "id") Long id){
        log.info("query product detail,id is :{}",id);
        ProductRspDTO productRspDTO = this.productExecutor.queryProductById(id);
        return ResponseResult.ok(productRspDTO);
    }

    @Operation(summary = "扣减数量")
    @PostMapping("/reduceAmount")
    @Parameters({
            @Parameter(name = "id",description = "主键id",required = true),
            @Parameter(name = "count",description = "数量",required = true)
    })
    public  ResponseResult<String> reduceCount(@RequestParam("id") Long id,@RequestParam("count") Integer count){
        log.info("reduce product count, id:{},count:{}",id,count);
        this.productExecutor.reduceProductCount(id,count);
        return ResponseResult.ok("reduce account succeed");
    }


    @Operation(summary = "分页查询商品列表")
    @PostMapping("/pageList")
    public ResponseResult<PageDTO<ProductRspDTO> > pageList(@RequestBody PageQuery<ProductQuery>  pageQuery){
        log.info("page product list, pageQuery:{}",pageQuery);
        PageDTO<ProductRspDTO> pageDTO = this.productExecutor.pageProductList(pageQuery);
        return ResponseResult.ok(pageDTO);
    }

    @Operation(summary = "查查满足条件的记录")
    @PostMapping("/queryList")
    public ResponseResult<List<ProductRspDTO>> queryList(@RequestBody ProductQuery productQuery){
        log.info("query product list, productQuery:{}",productQuery);
        List<ProductRspDTO> dtoList = this.productExecutor.queryProductList(productQuery);
        return ResponseResult.ok(dtoList);
    }
}

OrderController 内容如下。

@Slf4j
@Tag(name = "order-wep端api")
@RestController
@RequestMapping(BaseConstant.AdapterType.WEB+"/v1/order")
public class OrderController {

    @Resource
    private OrderExecutor orderExecutor;

    @Operation(summary = "新增订单")
    @PostMapping("/add")
    public ResponseResult<String> add(@RequestBody OrderReqDTO orderReqDTO){
        log.info("add order, orderReqDTO:{}",orderReqDTO);
        this.orderExecutor.addOrder(orderReqDTO);
        return ResponseResult.ok("add Order succeed");
    }

    @Operation(summary = "编辑订单")
    @PostMapping("/edit")
    public  ResponseResult<String> edit(@RequestBody OrderReqDTO orderReqDTO){
        log.info("edit order, orderReqDTO:{}",orderReqDTO);
        this.orderExecutor.editOrder(orderReqDTO);
        return ResponseResult.ok("update Order succeed");
    }

    @Operation(summary = "根据id删除订单")
    @PostMapping("/removeById")
    @Parameter(name = "id",description = "主键id",required = true)
    public ResponseResult<String> removeById(@RequestParam Long id){
        log.info("delete order,id is {}",id);
        this.orderExecutor.removeOrderById(id);
        return ResponseResult.ok("delete Order succeed");
    }

    @Operation(summary = "根据id查询订单")
    @GetMapping("/queryById/{id}")
    @Parameter(name = "id",description = "主键id",required = true)
    public ResponseResult<OrderRspDTO> queryById(@PathVariable(value = "id") Long id){
        log.info("query order detail,id is :{}",id);
        OrderRspDTO orderRspDTO = this.orderExecutor.queryOrderById(id);
        return ResponseResult.ok(orderRspDTO);
    }

    @Operation(summary = "分页查询订单列表")
    @PostMapping("/pageList")
    public ResponseResult<PageDTO<OrderRspDTO> > pageList(@RequestBody PageQuery<OrderQuery>  pageQuery){
        log.info("page order pageQuery:{}",pageQuery);
        PageDTO<OrderRspDTO> pageDTO = this.orderExecutor.pageOrderList(pageQuery);
        return ResponseResult.ok(pageDTO);
    }

    @Operation(summary = "查查满足条件的记录")
    @PostMapping("/queryList")
    public ResponseResult<List<OrderRspDTO>> queryList(@RequestBody OrderQuery orderQuery){
        log.info("query order list, orderQuery:{}",orderQuery);
        List<OrderRspDTO> dtoList = this.orderExecutor.queryOrderList(orderQuery);
        return ResponseResult.ok(dtoList);
    }
}

2.3.3. 添加应用层业务类

上面的前端控制器都需要调用应用层的业务方法。分别在账户模块、商品模块、订单模块的应用层executor 目录下,创建业务类,添加对应的方法。业务类名称分别为:AccountExecutor、ProductExecutor、OrderExecutor。

AccountExecutor 内容如下。

@Component
public class AccountExecutor {

    @Resource
    private AccountService accountService;

    /**
     *新增账户信息
     */
    public void addAccount(AccountReqDTO accountReqDTO) throws BaseException {
        Long id = IdWorker.getId();
        this.accountService.add(accountReqDTO,id);
    }

    /**
     *编辑账户
     */
    public void editAccount(AccountReqDTO accountReqDTO) throws BaseException {
        this.accountService.edit(accountReqDTO);
    }

    /**
     *根据id删除账户
     */
    public void removeAccountById(Long id) throws BizException {
        this.accountService.removeById(id);
    }

    /**
     *根据id查询账户
     */
    public AccountRspDTO queryAccountById(Long id) {
        AccountEntity accountEntity = this.accountService.getById(id);
        AccountRspDTO accountRspDTO = new AccountRspDTO();
        BeanUtils.copyProperties(accountEntity,accountRspDTO);
        return accountRspDTO;
    }

    /**
     *扣减金额
     */
    public void reduceAccountAmount(Long id, BigDecimal amount) throws BizException {
       this.accountService.reduceAmount(id,amount);
    }

    /**
     *分页查询
     */
    public PageDTO<AccountRspDTO> pageAccountList(PageQuery<AccountQuery> pageQuery) {
        return this.accountService.pageList(pageQuery);
    }

    /**
     *查查满足条件的记录
     */
    public List<AccountRspDTO> queryAccountList(AccountQuery accountQuery) {
        return this.accountService.queryList(accountQuery);
    }
}

ProductExecutor 内容如下。

@Component
public class ProductExecutor {

    @Resource
    private ProductService productService;

    /**
     *新增商品信息
     */
    public void addProduct(ProductReqDTO productReqDTO) throws BaseException {
      	Long id = IdWorker.getId();
        this.productService.add(productReqDTO,id);
    }

    /**
     *编辑商品
     */
    public void editProduct(ProductReqDTO productReqDTO) throws BaseException {
       this.productService.edit(productReqDTO);
    }

    /**
     *根据id删除商品
     */
    public void removeProductById(Long id) throws BizException {
        this.productService.removeById(id);
    }

    /**
     *根据id查询商品
     */
    public ProductRspDTO queryProductById(Long id) {
        ProductEntity productEntity = this.productService.getById(id);
        ProductRspDTO productRspDTO = new ProductRspDTO();
        BeanUtils.copyProperties(productEntity,productRspDTO);
        return productRspDTO;
    }

    /**
     *扣减数量
     */
    public void reduceProductCount(Long id, Integer count) throws BizException {
        this.productService.reduceCount(id,count);
    }


    /**
     *分页查询
     */
    public PageDTO<ProductRspDTO> pageProductList(PageQuery<ProductQuery> pageQuery) {
        return this.productService.pageList(pageQuery);
    }

    /**
     *查查满足条件的记录
     */
    public List<ProductRspDTO> queryProductList(ProductQuery productQuery) {
        return this.productService.queryList(productQuery);
    }
}

OrderExecutor 内容如下。

@Component
public class OrderExecutor {

    @Resource
    private OrderService orderService;

    /**
     *新增订单信息
     */
    public void addOrder(OrderReqDTO orderReqDTO) throws BaseException {
       	Long id = IdWorker.getId();
        this.orderService.add(orderReqDTO,id);
    }

    /**
     *编辑订单
     */
    public void editOrder(OrderReqDTO orderReqDTO) throws BaseException {
       this.orderService.edit(orderReqDTO);
    }

    /**
     *根据id删除订单
     */
    public void removeOrderById(Long id) throws BizException {
        this.orderService.removeById(id);
    }

    /**
     *根据id查询订单
     */
    public OrderRspDTO queryOrderById(Long id) {
        OrderEntity orderEntity = this.orderService.getById(id);
        OrderRspDTO orderRspDTO = new OrderRspDTO();
        BeanUtils.copyProperties(orderEntity,orderRspDTO);
        return orderRspDTO;
    }

    /**
     *分页查询
     */
    public PageDTO<OrderRspDTO> pageOrderList(PageQuery<OrderQuery> pageQuery) {
        return this.orderService.pageList(pageQuery);
    }

    /**
     *查查满足条件的记录
     */
    public List<OrderRspDTO> queryOrderList(OrderQuery orderQuery) {
        return this.orderService.queryList(orderQuery);
    }
}

3. MyBatis-Plus+Knife4j 测试

分别启动账户模块、商品模块、订单模块服务。

3.1. 测试文档效果

3.1.1. 账户模块

3.1.1.1. 文档首页

打开浏览器,输入 http://localhost:7030/doc.html# 地址,效果如下。

基于 COLA 架构的 Spring Cloud Alibaba(二)整合 MyBatis-Plus、 Knife4j_Spring Cloud Alibaba_03

3.1.1.2. 文档分组

分组下拉效果如下所示。

基于 COLA 架构的 Spring Cloud Alibaba(二)整合 MyBatis-Plus、 Knife4j_Spring Cloud Alibaba_04

选择 adapter-web 组,效果如下。

基于 COLA 架构的 Spring Cloud Alibaba(二)整合 MyBatis-Plus、 Knife4j_COLA_05

3.1.2. 商品模块

3.1.2.1. 文档首页

打开浏览器,输入 http://localhost:7040/doc.html# 地址,效果如下。

基于 COLA 架构的 Spring Cloud Alibaba(二)整合 MyBatis-Plus、 Knife4j_COLA_06

3.1.2.2. 文档分组

分组下拉效果如下所示。

基于 COLA 架构的 Spring Cloud Alibaba(二)整合 MyBatis-Plus、 Knife4j_Spring Boot3_07

选择 adapter-web 组,效果如下。

基于 COLA 架构的 Spring Cloud Alibaba(二)整合 MyBatis-Plus、 Knife4j_Spring Cloud Alibaba_08

3.1.3. 订单模块

3.1.3.1. 文档首页

打开浏览器,输入 http://localhost:7050/doc.html# 地址,效果如下。

基于 COLA 架构的 Spring Cloud Alibaba(二)整合 MyBatis-Plus、 Knife4j_MyBatis-Plus、Knife4j_09

3.1.3.2. 文档分组

分组下拉效果如下所示。

基于 COLA 架构的 Spring Cloud Alibaba(二)整合 MyBatis-Plus、 Knife4j_MyBatis-Plus、Knife4j_10

选择 adapter-web 组,效果如下。

基于 COLA 架构的 Spring Cloud Alibaba(二)整合 MyBatis-Plus、 Knife4j_MyBatis-Plus、Knife4j_11

3.2. 测试接口效果

以账户模块为例进行测试。

3.2.1. 新增账户

打开新增账户接口文档。

3.2.1.1. 入参信息

基于 COLA 架构的 Spring Cloud Alibaba(二)整合 MyBatis-Plus、 Knife4j_Spring Cloud Alibaba_12

3.2.1.2. 出参信息

基于 COLA 架构的 Spring Cloud Alibaba(二)整合 MyBatis-Plus、 Knife4j_Spring Cloud Alibaba_13

3.2.1.3. 执行效果

基于 COLA 架构的 Spring Cloud Alibaba(二)整合 MyBatis-Plus、 Knife4j_Spring Cloud Alibaba_14

3.2.2. 分页查询

打开分页查询接口文档。

3.2.2.1. 入参信息

基于 COLA 架构的 Spring Cloud Alibaba(二)整合 MyBatis-Plus、 Knife4j_COLA_15

3.2.2.2. 出参信息

基于 COLA 架构的 Spring Cloud Alibaba(二)整合 MyBatis-Plus、 Knife4j_COLA_16

3.2.2.3. 执行效果

基于 COLA 架构的 Spring Cloud Alibaba(二)整合 MyBatis-Plus、 Knife4j_Spring Boot3_17

基于 COLA 架构的 Spring Cloud Alibaba(二)整合 MyBatis-Plus、 Knife4j_Spring Boot3_18

3.2.3. 详情接口

打开根据 id 查询账户接口文档。

3.2.3.1. 入参信息

基于 COLA 架构的 Spring Cloud Alibaba(二)整合 MyBatis-Plus、 Knife4j_Spring Cloud Alibaba_19

3.2.3.2. 出参信息

基于 COLA 架构的 Spring Cloud Alibaba(二)整合 MyBatis-Plus、 Knife4j_COLA_20

3.2.3.3. 执行效果

基于 COLA 架构的 Spring Cloud Alibaba(二)整合 MyBatis-Plus、 Knife4j_Spring Boot3_21

4. 总结

本篇根据上一篇搭建好的项目基础架构,介绍了 MyBatis-Plus 、Knife4j 的整合,并分别给账户模块、商品模块、订单模块下的各层工程,添加了 CRUD 接口。同时对 MyBatis-Plus 、Knife4j 整合后的效果进行了相关测试。


基础篇项目代码:链接地址