从零开发一个接口-创建主要类与接口

SpringBoot开发全流程

Controller层往传输层传是VO,接受数据是DTO

**1.分析需求

2.创建Controller**

常用注解:

@Slf4j
@RestController
@Api("权限点管理")
@RequestMapping("/api/fill")

service注入接口:

@Autowired
private XXXService xxServbice;

创建方法:增删查改的请求方法不甚相同。

- 获取

    /**
     * 注解:这是方法的作用
     *
     * @return
     */
  @Operation(summary = "档案目录全量树", description = "获取档案目录全量树")
  @**GetMapping**("/tree")
 public RestApiResult<> funtion({
 1.调用Service
 xxx=xxxService.funtion();
 2.return RestApiResult.success();
 }

- 新增

 @Operation(summary = "新增档案目录文件夹结点", description = "新增档案目录文件夹结点")
 @**PostMapping**("/dir")
 与上同。。。

- 修改

@Operation(summary = "修改档案目录文件夹结点", description = "修改档案目录文件夹结点", parameters = {
            @Parameter(name = "id", description = "档案目录id")
    })
    @**PutMapping**("/dir/{id}")
    与上同。。。

- 删除

 @Operation(summary = "删除档案目录文件夹结点", description = "删除档案目录文件夹结点")
@**DeleteMapping**("/dir/{id}")

3.创建Service接口interface

/**
 * XXX服务
 *
 * @author lcj
 */
   /**
     * 注解:方法作用
     *
     * @param archiveCatalogue
     * @return
     */
     //抽象方法
     List<ArchiveCatalogueTreeNode> getAllArchiveCatalogueDir();
     返回值 方法名(形参 实参)

4.创建ServiceImpl

@Slf4j
@Service
/**
 * 注解:xxx服务实现类
 *
 * @Author:xxx
 * @Date:2021/4/23
 */
 @Autowired
    private xxxDao xxxDao;

锁内校验:

   @Override
    @Transactional(rollbackFor = Exception.class)
       //锁到同一parentId下
        String lockStrByFatherId = LOCK_FLAG_FOR_MOVE + archiveCatalogue.getParentId();
        synchronized (lockStrByFatherId.intern()) {
            //校验:如果查不到要修改的结点,则返回找不到结点
             Optional<ArchiveCatalogue> upArchive = Optional.ofNullable(archiveCatalogueDao.getById(archiveCatalogue.getId()));
            if (!upArchive.isPresent() || upArchive.get().getDeleted()) {
              throw new ApmCommonException("找不到要修改的档案目录,档案目录的id有误");
            });

            archiveCatalogueDao.updateNameById(archiveCatalogue);

        }

抽象:
第一步:将传过来的DTO转化为POJO实体类对象。

 ArchiveCatalogue archiveCatalogue = ArchiveCatalogue.builder()
                .name(archiveCatalogueVO.getDirName())
                .id(id)
                .parentId(archiveCatalogueVO.getParentId())
                .gmtModified(DateUtils.localTimeNow())
                .build();

第二步:将传过来的值进行校验:包括但不限于空值校验,重名校验,是否删除校验等

//校验:如果查不到要修改的结点,则返回找不到结点
            Optional<ArchiveCatalogue> upArchive = Optional.ofNullable(archiveCatalogueDao.getById(archiveCatalogue.getId()));
            if (!upArchive.isPresent() || upArchive.get().getDeleted()) {
                throw new ApmCommonException("找不到要修改的档案目录,档案目录的id有误");
            }
             //校验:询修改后的结点是否在同级有重名
            archiveCatalogueDao.getArchiveByName(archiveCatalogue.getParentId(), archiveCatalogue.getName())
                    .ifPresent(dupNode -> {
                       log.error("新增失败,档案目录名称发生重复,ArchiveCatalogue:{}", archiveCatalogue);
                        throw new ApmCommonException("修改后的档案目录名称不能与同级档案重名!");
                    });

第三步:
调用Dao层方法

 archiveCatalogueDao.updateNameById(archiveCatalogue);

5.创建Dao接口extends IService

public interface ArchiveCatalogueDao extends IService<ArchiveCatalogue> {

}
  /**
     * 方法作用注解
     *
     * @return
     */
    List<ArchiveCatalogue> getAllarchiveCatalogues();

6.创建DaoImpl

@Dao
@Component
public class ArchiveCatalogueDaoImpl extends ServiceImpl<ArchiveCatalogueMapper,ArchiveCatalogue> implements ArchiveCatalogueDao {
 private static final String ID = "id";//数据库字段一一映射关系
 //注入mapper
  @Autowired
    private ArchiveCatalogueMapper archiveCatalogueMapper;
   @Override
    public List<ArchiveCatalogue> listCatalogues(Collection<Integer> catalogueIds) {
        //dao层校验
        if (CollectionUtils.isEmpty(catalogueIds)) {
            return Lists.newArrayList();
  }
//调用QueryMapper的各种方法,in,eq等过滤
//selectList,selectone等
        QueryWrapper<ArchiveCatalogue> queryWrapper = new QueryWrapper<>();
        queryWrapper.in(ID, catalogueIds).eq(IS_DELETED, false);
        return archiveCatalogueMapper.selectList(queryWrapper);
    }   
}


7.创建接口mapper

extends BaseMapper
常用注解
@Component
把普通pojo实例化到spring容器中

/**
 *
 * 数据库表名 Mapper
 *
 * @Author:liangchangjian
 * @Date:2021/4/23
 */
@Component
public interface ArchiveCatalogueMapper extends BaseMapper<ArchiveCatalogue> {

}

8.创建DTO

接受前端传输的数据是DTO
主要注解:

@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class AddArchiveCatalogueDirDTO {
 @Schema(description = "名称")
 @NotBlank(message = "名称不能为空")
    @Schema(description = "父级节点id")
    @NotNull(message = "父级节点id不能为空")
    @Min(value = 0, message = "父级节点id最小为0")
    private Integer parentId;
    /**
     * afterId. 默认为0,可以不传
     */
    @Schema(description = "afterId. 默认为0,可以不传")
    @Nullable
    @Min(0)
    private Integer afterId;
    //将DTO转实体对象
       public ArchiveCatalogue toArchiveCatalogue() {
        return ArchiveCatalogue.builder()
                .name(this.dirName)
                .afterId(Objects.isNull(afterId) ? TemplateConstant.LLAST_AFTER_ID : afterId)
                .type(ArchiveCatalogueNodeType.DIR.getCode())
                .parentId(this.parentId)
                 .deleted(Boolean.FALSE)
                .gmtCreate(DateUtils.localTimeNow())
                .gmtModified(DateUtils.localTimeNow())
                .build();
    }

9.创建VO

往传输层前端传是VO
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ArchiveCatalogueVO {
  /**
     * 后继结点id
     */
    @Schema(description = "afterId. 默认为0,可以不传")
    @Nullable
    @Min(0)
    private Integer afterId;
//将处理完的实体对象转化为VO对象
 public static ArchiveCatalogueVO from(ArchiveCatalogue catalogue) {
        return ArchiveCatalogueVO.builder()
                .id(catalogue.getId())
                .dirName(catalogue.getName())
                .parentId(catalogue.getParentId())
                .afterId(catalogue.getAfterId()).build();
    }               
}

10.创建枚举类

public enum ArchiveCatalogueNodeType {
    /**
     *类型:文件夹
     **/
     DIR(2,Boolean.FALSE,"dir");
    @Getter
    private final Integer code;
    @Getter
    private final Boolean isFile;
        ArchiveCatalogueNodeType(Integer code, Boolean isFile, String name) {
        this.code = code;
        this.isFile = isFile;
        this.name = name;
    }
 /**
     * 根据传值校验文件夹类型
     * @param type
     * @return
     */
    /**
     * 根据传入值返回对应枚举对象
     *
     * @param b Boolean
     * @return TemplateType
     */
       public static ArchiveCatalogueNodeType valueOf(@NonNull Boolean b) {
        for (ArchiveCatalogueNodeType type : ArchiveCatalogueNodeType.values()) {
            if (type.isFile.equals(b)) {
           }
        }

        throw new IllegalArgumentException();
    }
}

完结,撒花!

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值