增删改查
章节简介
本章给出了最基本的增删改查代码的示例
分页-查询(单表)
当查询返回仅限于单张表时,可以使用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类
- 所以当不需要返回对象数据时,可以直接使用
Result.ok()方法快速组装成功状态 - 当需要返回对象数据时,可以通过
new JsonResult<>(对象)方法快速组装成功状态并返回数据 - 如果在业务执行中,发生异常,请参考异常处理章节,快速组装失败状态
其他基本操作
基本的增删改查操作如下,基本是基于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();
方法命名规范
大家在写方法时,应该遵循以下命名规范
- 查询分页query${业务}Page()
- 查询列表query${业务}List()
- 查询单个query${业务}Detail()
- 保存save${业务}
- 更新update${业务}
- 删除remove${业务}
