开发者学堂课程【微服务+全栈在线教育实战项目演练(SpringCloud Alibaba+SpringBoot):课程管理-课程大纲列表(后端)】学习笔记,与课程紧密连接,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/667/detail/11376
课程管理-课程大纲列表(后端)
内容介绍
一、本章内容介绍
二、课程大纲列表显示
三、主要内容总结
一、本章内容介绍
1、添加课程基本信息完善
1.1修改课程基本信息功能
(1)整合文本编辑器
2、课程大纲管理
(1)课程大纲列表显示
(2)章节添加修改删除
(3)小节添加修改删除
3、课程信息确认
(1)编写sql语句实现
(2)课程最终发布
二、课程大纲列表显示
进入第二步:创建课程大纲操作其中没有内容,当点击添加之后才会
显示章节和小节,但此时我们先创建课程大纲列表之后再做添加小节
部分。
正常顺序是先做添加小节操作,之后再创建课程大纲列表。而为了巩
固之前知识点,我们是先创建课程大纲,所以其中是没有数据的。
1.分析
要实现课程大纲列表需要使用 edu_chapter 和 edu_video 俩张表,因
为课程章节和课程小节加一起就是课程大纲。我们做的就是章节和小
节的列表功能,或者叫做章节和课时的列表功能。同时两张表都是一
对多的关系,一个章节有多个小节,一个小节属于某个章节和之前说
的一级二级分类性质一样。所以使用框线的两张表来实现列表。
(05-课程相关表关系)
2.第一步:创建两个实体类,章节和小节,在章节实体类中使用lis
t集合表示小节
参考之前的一级二级分类,在其中我们建了两个实体类,然后在一级
分类里使用集合表示了二级分类。同样我们建一个章节实体类,再建
一个小节实体类,最后在章节表示它的小节。做法与一级二级一致,
仅更改表即可。
TwoSubject.java代码
importlombok.Data;
//二级分类
@Data
OneSubject.java代码
//一级分类
@Data
//一个一级分类有多个二级分类
privateList<TwoSubjeqt>children=newArrayList<>();
(1)具体操作
首先在 entity 里新建一个包,命名为 chapter。
之后再 chapter 中创建两个实体类,一个章节两个小节。两个实体类
ChapterVo 代表章节,小节叫做 VideoVo。
在章节中再写各个属性小节部分,属性与数据库表中的一致为:id
和 title(名称),创建两个实体类后再在章节实体类 ChapterVo 中
添加小节。
ChapterVo 代码如下:
importlombok.Data;
@Data//引入get()set()方法
publicclassChapterVo{
privateStringid;//章节 id
privateStringtitle;//章节名称
//表示小节,因为章节和小节是一对多的关系,一个章节里面有很多
小节,所以使用 list。newArrayList 表示创建
privateList<VideoVo>children=newArrayList<>();
}
VideoVo 代码如下:
importlombok.Data;
@Data//引入get()set()方法
publicclassVideoVo{
privateStringid;//小节id
privateStringtitle;//小节名称
}
3.第二步:根据课程id查询课程里面所有章节
(1)编写 EduChapterController 代码内容
完成第一步后开始写具体代码,同一级二级操作,写个 control 调用
service 其中编写的具体方法。
即之前 EduSbujectServiceImpl 中先调一级分类再得到二级分类最
后封装。
此时要做的是章节小节部分是一个全新课程大纲部分,所以写入新的
EduChapterController 中实现。
代码整体与之前的一级二级差不多,但仍有区别:不同于之前查找分
类时是查找所有分类,课程大纲并非单独存在,它存在于某个课程之
中,其中的章节小节要在课程之中才会有。所以在查找时并不是查找
所有章节,而是查找课程中的章节小节。
要去查课程中的章节和小节,表中可以知道course_id就是课程id
所以我们要根据课程id把课程中的章节和小节查找出来,并做个显
示。
edu_chapter 表
4.接口代码
(1)EduChapterController代码如下:
@RestController
@RequestMapping("/eduservice/chapter")
publicclassEduChapterController{
@Autowired//注入加上Autowired
//定义变量chapterService
privateEduChapterServicechapterService;
//课程大纲列表,加上 get 提交,名字为 getChapterVideo,将课程 i
d 传入
@GetMapping("getChapterVideo/{courseId}")
//书写方法加上@PathVariable 注解获得 courseId
publicRgetChapterVideo(@PathVariableStringcourseId){
//通过课程 id 来查找其章节和小节,调用 Service,将过程都写入
其中。同时把结果赋给 list。同时在 list 结构中添加的泛型应该是
ChapterVo。
//做一个返回,名为 allChapterVideo 值为 list
returnR.ok().data(“allChapterVideo”,list):
}
到此 EduChapterController 中的代码就此完成。之后编写 service
中的代码做最后的封装实现。
(2)创建 EduChapterService 方法
首先点击getChapterVideoByCourse 创建接口方法,就会显示 EduCh
apterService.java 这就是 service 的接口。
ChapterService.java 代码
/**
*<p>
*课程服务类
*</p>
*@authortestjava
*@since2020-03-02
*/
publicinterfaceEduChapterServiceextendsService<EduChapt
er>{
//课程大纲列表,根据课程 id 进行查询
将 getChapterVideoByCourseId 方法创建。
同时在实现类中实现封装,因为封装的是章节和小节,同时并不是查
所有章节,所以第一步是根据课程id查询课程里面所有的章节;第
二步是查询其中的小节,在小节表edu_video中可以看到除了章节i
d(chapter_id)外还有字段课程id(course_id),说明根据课程i
d也可以查出小节。
所以在此我们根据课程id查询课程里面的所有小节;第三步:遍历
查询章节list集合进行封装;第四步:遍历查询小节list集合,进
行封装。
总结:先把课程中的章节和小节全部查出来,然后遍历进行封装
EduChapterServiceImpl.java代码:
*课程服务实现类*</p>
*@authortestjava
//因为此时在EduChapter中,无法直接查询小节Video,所以需要
将EduvideoService接口注入。
@Autowired
//注入小节service
privateEduvideoServicevideoService;
//课程大纲列表,根据课程id进行查询
@Override
publicList<ChapterVo>getChapterVideoByCourseld(Stringcou
rseld){
//1.根据课程id查询课程里面所有的章节
//创建一个QueryWrapper<>类型的对象,名为wrapperChapter
QueryWrapper<EduChapter>wrapperChapter=newQueryWrapper
<>();
//设置变量wrapperChapter的条件:根据课程id查询。
column表示字段,从edu_chapter表中可以查到课程id字段为cou
rse_id,同时最后写上课程id的参数值courseId。
wrapperChapter.eq(column:"course_id",courseId);
//调用方法selectList,使用this.和baseMapper.都可以。最后将
查询出满足条件的所有章节值赋给eduChapterList。
List<EduChapter>eduChapterList=baseMapper.selectList(wra
pperChapter);
//2根据课程id查询课程里面所有的小节,步骤与章节一致。
//创建一个QueryWrapper<>类型的对象,名为wrapperVideo
QueryWrapper<EduVideo>wrapperVideo=newQueryWrapper<>();
//设置变量wrapperVideo的条件:根据课程id查询。
column表示字段,从edu_video表中可以查到课程id字段为cours
e_id,同时最后写上课程id的参数值courseId。
wrapperVideo.eq(column:"course_id",courseId);
//先注入EduvideoService小节的接口,再调用方法selectList,
将,查询条件wrapperVideo传入,再将调用方法后查询的值返回给
变量eduVideoList(课程中小节集合)。
List<EduVideo>eduVideoList=videoService.list(wrapperVide
o):
//以上就是查询章节和小节数据,当有了数据后我们对其进行封装。
//创建list集合,用于最终封装数据
首先创建list集合名为finalList,用于最终封装数据。
List<ChapterVo>finalList=newArrayList<>();
//3.遍历查询章节list集合进行封装
//根据之前的一级二级分类的思路:首先遍历一级分类,将其中数据
放在Onesubject中,再遍历二级分类包括其中的if判断id是否一
致,再对其进行封装。将其中的一级二级依次变为章节和小节。
//遍历查询章节list集合
即遍历eduChapterList。
for(inti=0:i<eduChapterList.size(:i++){
//遍历后得到每个章节
编写代码eduChapterList.get(i).var即可变为下方代码。同时将其
放在eduChapter中。
EduChaptereduChapter=eduChapterList.get(i);
//将eduChapter对象值复制到ChapterVo里面
因为此时要放在集合中的对象为ChapterVo而并非eduChapter。
ChapterVochapterVo=newChapterVo();
//使用工具类BeanUtils中的copyProperties()方法,使得里面
最终chapterVo有eduChapter的值。
BeanUtils.copyProperties(eduChapter,chapterVo);
//最后把chapterVo放到最终list集合
即chapterVo中
finalList.add(chapterVo);
//创建集合,用于封装章节的小节
创建名为videoList的集合用于封装章节中的小节
List<VideoVo>videoList=newArraylist<>();
//4遍历查询小节list集合,进行封装
因为一个章节中有很多小节,所以遍历小节时要在for之中作个嵌套
循环。
//遍历所有章节
for(intm=0;m<eduVideoList.size();m++){
//得到其中每个小节
EduVideoeduVideo=eduVideoList.get(m);
判断:小节里面chapter_id和章节里面id是否一样,一样则封装
因为小节中为chapter_id,章节中为id,要找到章节中的小节,两者
应该一致。与之前的一级中的二级id作比较一样。使用equals比较。
if(eduVideo.getChapterId().equals(eduChapter.getId())){
进行封装
封装即把 eduVideo 的值放入 VideoVo 中即可。
videoVovideoVo=newvideoVo();
BeanUtils.copyProperties(eduVideo,videoVo);
//放到小节封装集合
videoList.add(videoVo);
)
//把封装之后小节list集合,放到章节对象里面
章节对象即chapterVo
chapterVo.setChildren(videoList);
}
returnfinalList;//finalList 含有最后的所有章节部分
三、主要内容总结
要实现根据课程id查询课程里面所有章节。首先编写EduChapterCo
ntroller代码,再在其中调用EduChapterServiceImpl代码中的封
装方法做真正实现。
1.EduChapterController 代码思路
在 EduChapterController中因为章节小节都在某个课程中,要根据
课程 id 进行查询,所以添加参数CourseId最后返回值allChapterV
ideo。
2.EduChapterServiceImpl代码思路
(1)第一、二步:根据课程id查询里面所有章节和小节
章节:
首先创建一个 QueryWrapper<>类型的对象,名为
wrapperChapter
其次设置变量 wrapperChapter 的条件:根据课程id查询。
最后调用方法 selectList,并将最后查询的值赋给 eduChapterList,
以此查出其中的章节。
小节:
首先创建一个 QueryWrapper<>类型的对象,名为 wrapperVideo
其次设置变量 wrapperVideo 的条件:根据课程id查询
最后先注入 EduvideoService 小节的接口,再调用方法 selectList
再将调用方法后查询的值返回给变量 eduVideoList(课程中的小节
集合),以此查出其中的小节。
(2)第三步:遍历查询章节 list 集合,进行封装
首先把查出来的章节集合 eduChapterList 使用 for 作个遍历然后得
到每个章节。其次放在集合中的对象为 ChapterVo 而并非 eduChapte
r。所以将 eduChapter 对象值复制到 ChapterVo 里面。最后将 chapt
erVo 加到最终 finallist 集合中。
(3)第四步:遍历查询小节list集合,进行封装
首先创建封装章节中小节所用的集合,使用fot遍历小节集合,得到
每个小节。
其次判断里面的小节里面 chapter_id 和章节里面id是否一样,一样
则封装。然后使用变量 videiVo 做个复制,把 eduVideo 的值放入 Vi
deoVo 中即可,再使用 BeanUtil 中的 copyProperties 方法做封装。
最后将小节数据全部放在小节封装集合中。
(4)第五步:把封装之后小节list集合放到章节对象里面 chapterVo.setChildren(videoList)
(5)第六步:最终返回给 finalList
以上就是章节和小节的封装过程。与之前的一级和二级分类一致。