章与节是绑定在一起的,查询章的时候,对应的小节也要一起查询出来
sql语句这样写,会有问题。
如果有课程(课程下面无小节),这样的话关联出的内容都是空的
那么 在执行t2.del_flag = '2'时, 空值和2是比不出来的,所以这个章节会查不出来
在用最后一行 t1.course id = #{courseId}时,无论传入什么内容,课程下无小节的内容都查不出来
在排除假删的时候用的是t2.delflag != '2',要多或一个条件 t2.lessonId IS NULL
记得要设置好排序
同样先把在 com.mashang.elearing.domain下,用自定义生成实体类工具:
数据类型改成包装类,设置好主键是自动递增,章不需要设置自动填充之类的
package com.mashang.elearing.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.util.Date;
@Data
public class MsChapter {
@TableId(type = IdType.AUTO)
private Long chapterId;
private Long courseId;
private String chapterName;
private Long chapterSort;
private String delFlag;
private String createBy;
private Date createTime;
private String updateBy;
private Date updateTime;
private String remark;
}
在domai下的Vo包创建MsChapterLessonVo
章节是一对多的关系,在创建章之前,要先创建节的MsLessonVo
package com.mashang.elearing.domain.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ApiModel("节模块")
@Data
public class MsLessonsVo {
@ApiModelProperty("节id")
private Long lessonId;
@ApiModelProperty("节名称")
private String lessonName;
@ApiModelProperty("节排序")
private Long lessonSort;
}
package com.mashang.elearing.domain.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@ApiModel("查询章节信息")
@Data
public class MsChapterLessonsVo {
@ApiModelProperty("章id")
private Long chapterId;
@ApiModelProperty("课程id")
private Long courseId;
@ApiModelProperty("章名称")
private String chapterName;
@ApiModelProperty("章排序")
private Long chapterSort;
//一对多的查询,把小节作为章的一个信息
@ApiModelProperty("节信息")
private List lessons;
}
在mapper层建一个接口MsChapterMapper继承BaseMapper
写一个方法list(),返回的是节的集合,传入的是课程Id
package com.mashang.elearing.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.mashang.elearing.domain.MsChapter;
import com.mashang.elearing.domain.vo.MsChapterLessonsVo;
import java.util.List;
public interface MsChapterMapper extends BaseMapper {
List list(Long courseId);
}
创建MsChapterMapper.xml
绑定com.mashang.elearing.mapper.MsChapterMapper
在service包下创建接口IMsChapterService,继承IService
package com.mashang.elearing.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.mashang.elearing.domain.MsChapter;
import com.mashang.elearing.domain.vo.MsChapterLessonsVo;
import java.util.List;
public interface IMsChapterService extends IService {
List list(Long courseId);
}
在service/impl里创建MsChapterServiceImpl继承ServiceImpl
@Service
public class MsChapterServiceImpl extends ServiceImpl implements
IMsChapterService {
@Autowired
private MsChapterMapper msChapterMapper;
@Override
public List list(Long courseId) {
return msChapterMapper.list(courseId);
}
}
@Api(tags = "章模块")
@RestController
@RequestMapping("/chapter")
public class MsChapterController extends BaseController {
@Autowired
private IMsChapterService msChapterService;
@ApiOperation("章节信息查询")
@GetMapping
public Result> list(Long courseId){
List list = msChapterService.list(courseId);
return Result.success(list);
}
}
按找之前的方法,在各个层建好小节的类,用mybatisPlus来查询小节信息。
在章得到控制层注入小节的信息
先查询章下是否有小节,如果有小节的话,不让删,没有小节的话就直接删
注意:ById结尾的方法要在主键设置TableId,不然会识别不出来
@ApiOperation("删除")
@DeleteMapping("/{chapterId}")
public Result delete(@PathVariable Long chapterId){
// plus的查询方法需要传入条件构造器
LambdaQueryWrapper qw = new LambdaQueryWrapper<>();
qw.ne(MsLesson::getDelFlag,"2"); //假删不能查出来
qw.eq(MsLesson::getChapterId,chapterId); //根据章id查询小节信息
long count = msLessonService.count(qw); //查询章下面是否含有小节
if(count > 0){
return Result.error("删除失败,章下面仍含有节");
}
//count == 0
MsChapter msChapter = new MsChapter();
msChapter.setDelFlag("2");
msChapter.setChapterId(chapterId);
//updatebyid需要传入MsChapter实体类
return Result.to(msChapterService.updateById(msChapter));
}
先删除章,再判断章下面有没有小节,如果有小节,就把该章对应的小节的del_flag都设置成2(假删) --- 涉及到两张表的删除,最好加上事物的注解@Transactional
在mapper,和serice写上对应方法,去ServiceImpl实现,记得要在ServiceImpl注入节的对象
@Transactional
@Override
public int delete(Long chapterId) {
int rs = 0;
//先删除章信息
MsChapter msChapter = new MsChapter();
msChapter.setChapterId(chapterId);
msChapter.setDelFlag("2");
rs = msChapterMapper.updateById(msChapter);
//先查一下是否含有小节信息
LambdaQueryWrapper qw = new LambdaQueryWrapper<>();
qw.ne(MsLesson::getDelFlag,"2");
qw.eq(MsLesson::getChapterId,chapterId);
// qw.eq(MsLesson::getChapterSort,msChapter.getChapterSort());
//查询出没被假删且对应章下面的课程
Long count = msLessonMapper.selectCount(qw);
//含有小节信息
//如果有节,就根据章id将节的del_flag设置成2
if (count > 0){
MsLesson msLesson = new MsLesson();
msLesson.setDelFlag("2");
LambdaUpdateWrapper uw = new LambdaUpdateWrapper<>();
//更新当前传进来的章id的小节的del_flag = '2'
uw.eq(MsLesson::getChapterId,chapterId);
//需要传入一个实体类和条件构造器
//把满足条件的uw都设置成MsLesson
msLessonMapper.update(msLesson,uw);
}
return rs;
}
在com.mashan.elearning.domain.params.chapter下创建添加的参数实体类
添加不需要courseId,章Id可以自动递增
必要要串课程Id
package com.mashang.elearing.domain.params.chapter;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@ApiModel("章添加")
@Data
public class MsChapterCreate {
// @ApiModelProperty("章id")
// private Long chapterId;
@ApiModelProperty(value = "课程id",required = true)
@NotNull(message = "课程id不为空")
private Long courseId;
@ApiModelProperty(value = "章名称",required = true)
@NotBlank(message = "章名称不为空")
private String chapterName;
@ApiModelProperty(value = "序号")
private Long chapterSort;
}
先判断章是否存在,存在的话序号要批量递增,不存在可以直接插入,涉及到了事务的操作
在IMsChapterService接口下创建添加方法去impl去实现,实现时要加上事物的注解
int create(MsChapterCreate create);
传入的参数和最后create方法所需参数不同,依然需要转
package com.mashang.elearing.mapping;
import com.mashang.elearing.domain.MsChapter;
import com.mashang.elearing.domain.params.chapter.MsChapterCreate;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface MsChapterMapping {
MsChapterMapping INSTANCE = Mappers.getMapper(MsChapterMapping.class);
MsChapter to(MsChapterCreate create);
}
//添加章
@Transactional
@Override
public int create(MsChapterCreate create) {
MsChapter msChapter = MsChapterMapping.INSTANCE.to(create);
//先判断当前课程是否有该章,有的话把chapterId > 传入章id 的所有chapterId + 1
updateSort(msChapter);
int rs = msChapterMapper.insert(msChapter);
return rs;
}
public void updateSort(MsChapter msChapter){
//查询当前课程存不存在该序号
LambdaQueryWrapper qw = new LambdaQueryWrapper<>();
qw.ne(MsChapter::getDelFlag,"2"); //固定排除假删除
qw.eq(MsChapter::getCourseId,msChapter.getCourseId()); //查询当前课程
qw.eq(MsChapter::getChapterSort,msChapter.getChapterSort()); //如果有相同序号的就代表重复了
Long count = msChapterMapper.selectCount(qw);
//如果有该章,需要将该章后面的sort+1
if (count > 0){
//将该章后面的sort+1
LambdaUpdateWrapper uw = new LambdaUpdateWrapper<>();
uw.ge(MsChapter::getChapterSort, msChapter.getChapterSort());
uw.setSql("chapter_sort = chapter_sort + 1");
msChapterMapper.update(null,uw);
}
}
@ApiOperation("添加")
@PostMapping
public Result create(@RequestBody @Validated MsChapterCreate create){
int rs = msChapterService.create(create);
return Result.to(rs);
}
修改和添加类型,都是需要先判断该序号是否存在,如何存在,把该序号以后的序号做统一递增,然后再执行添加或者修改操作
在domain下的params包下创建关于章的实体类
修改需要传courseId,要查询当前课程下是否有该章节
package com.mashang.elearing.domain.params.chapter;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@ApiModel("章修改")
@Data
public class MsChapterUpdate {
@ApiModelProperty("章id")
@NotNull(message = "章id不为空")
private Long chapterId;
@ApiModelProperty(value = "课程id",required = true)
@NotNull(message = "课程id不为空")
private Long courseId;
@ApiModelProperty(value = "章名称",required = true)
@NotBlank(message = "章名称不为空")
private String chapterName;
@ApiModelProperty(value = "序号")
private Long chapterSort;
}
MsChapter to(MsChapterUpdate update);
IMsChapterService下定义一个方法
int create(MsChapterCreate create);
去Impl实现
@Transactional
@Override
public int update(MsChapterUpdate update) {
//修改接口,先修改,修改完如果有冲突的序号,该序号后面需要再递增
//这样的话,自己也会被修改掉 比如 4 改成 2
//原本就有2的话,调用updateSort方法,会把两个2都+1,这样就冲突了
//所以应该是先判断是否存在修改后的序号,有的话先统一递增。再修改
//先进行实体类转化
MsChapter msChapter = MsChapterMapping.INSTANCE.to(update);
//先判断当前课程是否有该章,有的话把chapterId >= 传入章id 的所有chapterId + 1
updateSort(msChapter);
//然后再执行操作
int rs = msChapterMapper.updateById(msChapter);
return rs;
}
public void updateSort(MsChapter msChapter){
//查询当前课程存不存在该序号
LambdaQueryWrapper qw = new LambdaQueryWrapper<>();
qw.ne(MsChapter::getDelFlag,"2"); //固定排除假删除
qw.eq(MsChapter::getCourseId,msChapter.getCourseId()); //查询当前课程
qw.eq(MsChapter::getChapterSort,msChapter.getChapterSort()); //如果有相同序号的就代表重复了
Long count = msChapterMapper.selectCount(qw);
//如果有该章,需要将该章后面的sort+1
if (count > 0){
//将该章后面的sort+1
LambdaUpdateWrapper uw = new LambdaUpdateWrapper<>();
uw.ge(MsChapter::getChapterSort, msChapter.getChapterSort());
uw.setSql("chapter_sort = chapter_sort + 1");
msChapterMapper.update(null,uw);
}
}
记得再控制层加上参数验证@Validated,和用Json的形式传参@RequestBody
@ApiOperation("修改")
@PutMapping
public Result update(@RequestBody @Validated MsChapterUpdate update){
int rs = msChapterService.update(update);
return Result.to(rs);
}
//修改的时候要先把章节信息查出来
//查询详情直接用plus构造就行
@ApiOperation("详情")
@GetMapping("/{chapterId}")
public Result getById(@PathVariable Long chapterId){
MsChapter msChapter = msChapterService.getById(chapterId);
return Result.success(MsChapterMapping.INSTANCE.to(msChapter));
}