Scaffold-Boot-3.0框架使用文档Scaffold-Boot-3.0框架使用文档
首页
快速开始
变更记录
Source
首页
快速开始
变更记录
Source
  • 开始
  • 基础

    • 目录结构
    • 代码生成器
    • 增删改查
    • 异常处理
    • Knife4j(Swagger)文档
    • 登录&登出
    • 系统安全
    • 数据字典
    • Excel处理
    • 文件上传下载
    • 工具类
    • 定时任务
    • 微信集成
    • 短信服务
    • 参数配置
    • 接口限流
    • 日志审计
    • 数据脱敏
    • 网站管理
  • AI开发

    • AI项目工程结构
    • MCP服务
    • AI开发模式介绍
  • 开发规范
  • 常见问题
  • 深入

    • 配置详解-Config类
    • 配置详解-Yml配置文件
  • 生命周期

    • SonarQube代码质量保证
    • 部署到测试环境
    • 部署到正式环境
  • 优秀案例

    • Excel导入完整案例
  • 信创专区

    • 海量数据库
    • 神通数据库
    • 达梦数据库
    • 麒麟v10安装插件
  • 框架升级

增删改查

章节简介

本章给出了最基本的增删改查代码的示例

分页-查询(单表)

当查询返回仅限于单张表时,可以使用Params类实现分页查询。这也是代码生成器中生成的最基本的查询方法
单表分页查询主要依赖page()方法实现
params类:在查询参数字段打上@MatchType注解,通过value可以指定查询的类型,例如:EQ为等于,LIKE为模糊查询。通过fieldName可以指定查询的字段,可以是多个

public class CdoTaskSignParams extends BaseParams {
    @MatchType(value = QueryType.LIKE, fieldName = {"title", "content"})
    @ApiModelProperty(value = "关键词")
    private String keyword;
    
    @MatchType(value = QueryType.EQ)
    @ApiModelProperty(value = "类型")
    private String type;
}

Controller层:通过baseService.page(params)方法实现分页查询,并自动按照params中的字段进行查询。

@ApiOperation("分页查询")
@PostMapping("/pageQuery")
public Result pageQuery(@RequestBody CdoContactParams params) {
    IPage<CdoContactPageQueryResultVO> result = baseService.page(params).convert(it -> {
        CdoContactPageQueryResultVO record = new CdoContactPageQueryResultVO();
        BeanUtils.copyProperties(it, record);
        return record;
    });
    DataConvertUtil.trans(result.getRecords());
    return new JsonResult<>(result);
}

分页-查询(多表)

当需要多表联合查询时,直接通过Page方法进行查询显然是不行的。这时候需要自己手写SQL语句,并完成从Controller到Mapper的代码,以实现分页查询逻辑
Controller层:这里Params类中的MatchType注解已经失效,但是Params类可用于接收前端传来的查询参数

@ApiOperation("分页查询")
@PostMapping("/pageQuery")
public Result pageQuery(@RequestBody CdoWorkMomentParams params) {
    IPage<CdoWorkMomentPageQueryResultVO> result = baseService.momentPages(params).convert(it -> {
        //convert方法为IPage自带的数据转换方法,在此方法中,可编写自己的数据处理逻辑,例如类型转换,文字处理等
        CdoWorkMomentPageQueryResultVO record = new CdoWorkMomentPageQueryResultVO();
        BeanUtils.copyProperties(it, record);
        return record;
    });
    //数据字典转换/脱敏
    DataConvertUtil.trans(result.getRecords());
    return new JsonResult<>(result);
}

Service层:基本固定写法

/**
 * 分页查询
 *
 * @param params 参数
 * @return 分页结果
 */
IPage<CdoWorkMomentPageQueryResultVO> momentPages(CdoWorkMomentParams params);

ServiceImpl层:基本固定写法

@Override
public IPage<CdoWorkMomentPageQueryResultVO> momentPages(CdoWorkMomentParams params) {
    return baseMapper.momentPages(params.getPage(), params);
}

Mapper层:基本固定写法

/**
 * 分页查询
 *
 * @param page   分页对象
 * @param params 参数
 * @return 分页结果
 */
IPage<CdoWorkMomentPageQueryResultVO> momentPages(IPage<CdoWorkMomentPageQueryResultVO> page, @Param("params") CdoWorkMomentParams params);

XML层:自定义SQL语句

<select id="momentPages" resultType="com.fykj.scaffold.cdo.domain.vo.CdoWorkMomentPageQueryResultVO">
    select 
        * 
    from cdo_work_moment  m
    where m.is_deleted = false
    <if test="params.title != null and params.title != ''">
        and m.title like concat('%',#{params.title},'%')
    </if>
</select>

单个详情-查询

根据ID查询单个对象的详情。如果是简单查询,可以直接写在Controller层,如果是复杂查询,涉及多表,复杂业务逻辑,则需要写在Service层
查询可以使用getById()方法,该方法会根据ID查询出对应的Entity对象

@ApiOperation("根据ID获取活动详情")
@GetMapping("/getActivityDetail")
public Result getActivityDetail(@RequestParam Long id) {
    //可以通过getById方法查询出Entity
    CdoTaskSign entity = baseService.getById(id);
    //新建VO
    CdoTaskSignDetailResultVO result = new CdoTaskSignDetailResultVO();
    //Entity转VO
    BeanUtils.copyProperties(entity, result);
    //如果需要数据字典转换
    DictTransUtil.trans(result);
    //其他业务逻辑处理...
    //返回结果
    return new JsonResult<>(result);
}

新增/修改

新增和修改对象两者较为相似,这里一起介绍。代码应该放在对应对象的Service层中 新增可以使用save()方法,修改可以使用updateById(entity)方法或lambdaUpdate().update()方法
MybatisPlus还提供了saveOrUpdate方法,该方法会根据ID判断是新增还是修改。

public void saveNotifyList(CdoNotifyList notifyList) {
    //其他额外的业务逻辑
    notifyList.setPublishDate(LocalDate.now());
    //最后使用原始save方法,如果是修改则为updateById方法
    save(notifyList);
}

删除

删除数据操作,如果比较简单,可以直接写在Controller层。使用baseService.removeById(id)方法即可。如果比较复杂,请写在Service层
删除时需要注意,数据删除后,是否需要级联删除其他数据,例如:删除课程时,是否需要删除此课程关联的考试记录?
删除可以使用lambdaUpdate().remove()方法和removeById()方法

@Override
public void removeCourse(Long courseId) {
    //删除课程
    baseSerivice.removeById(courseId);
    //删除课程关联的考试记录
    testService.lambdaUpdate().eq(CdoTest::getCourseId, courseId).remove();
}

返回对象

在与前端交互时,我们需要约定好返回数据的格式,在系统中,我们约定的格式如下

{
  "code": 0, //状态码0代表成功,其他代表失败
  "msg": "操作成功", //状态码对应的消息,例如:操作成功,数据不存在等
  "obj": "对象数据“ //返回的对象数据,可以是单个对象也可以是列表,类似新增,修改,删除的操作,可能不会返回此字段
}

要想快速组装出上述格式,我们需要借助Result和JsonResult类

  1. 所以当不需要返回对象数据时,可以直接使用Result.ok()方法快速组装成功状态
  2. 当需要返回对象数据时,可以通过new JsonResult<>(对象)方法快速组装成功状态并返回数据
  3. 如果在业务执行中,发生异常,请参考异常处理章节,快速组装失败状态

其他基本操作

基本的增删改查操作如下,基本是基于MybatisPlus的封装,所以可以直接使用xxxService.xxx()方法实现
如果在service层中,可以直接调用

良好习惯

其实MyBatisPlus已经封装了很多便利方法,大家在做简单的单表操作时应该应用以下给出的方法,如果涉及到多表操作,也应该考虑是否在Java代码中实现
尽量少写复杂的SQL语句,应该用多个简单的操作组合成一个复杂的业务。

baseService.save(entity); //新增
baseService.saveBatch(entityList); //批量新增
baseService.updateById(entity); //修改
baseService.saveOrUpdate(entity); //新增或修改
baseService.removeById(id); //删除
baseService.page(params); //分页查询
baseService.list(params); //列表查询,带参数查询,不分页
baseService.getById(id); //根据ID查询单个对象
baseService.list(); //查询所有对象,慎用,除非数据不多
baseSerivce.lamadaQuery() //链式查询,例如:baseService.lambdaQuery().eq(CdoTaskSign::getTaskType, "1").list();
baseService.lambdaUpdate() //链式更新,例如:baseService.lambdaUpdate().eq(CdoTaskSign::getTaskType, "1").update();

方法命名规范

大家在写方法时,应该遵循以下命名规范

  1. 查询分页query${业务}Page()
  2. 查询列表query${业务}List()
  3. 查询单个query${业务}Detail()
  4. 保存save${业务}
  5. 更新update${业务}
  6. 删除remove${业务}
在 GitLab 上编辑此页
最后更新: 2025/12/4 09:05
贡献者: xuew
Prev
代码生成器
Next
异常处理