06_04_任务一:拉勾教育后台管理系统[课程管理模块、图片上传、 BeanUtils封装实体类](SSM)
拉勾教育后台管理系统(SSM)
1. 项目架构
1.1 项目介绍
拉勾教育后台管理系统,是提供给拉勾教育的相关业务人员使用的一个后台管理系统, 业务人员可以在 这个后台管理系统中,对课程信息、广告信息、用户信息、 权限信息等数据进行维护.
在 web阶段,我们已经完成了拉勾教育后台管理系统中课程模块, 接下来将对拉勾教育后台管理系统进 行升级改造,基于SSM框架来完成课程信息模块,广告信息模块,用户信息模块,权限信息模块
1.2 页面原型展示
访问 http://eduboss.lagou.com
用户名:18201288771 密码:111111
1.3 技术选型
1.3.1前端技术选型
前端技术 | 说明 |
---|---|
Vue.js: | 是一套用于构建用户界面的渐进式JavaScript框架 |
Element UI: | 是饿了么前端出品的基于 Vue.js的 后台组件库,方便程序员进行页面快速布局和构建 |
node.js: | 简单的说 Node.js 就是运行在服务端的 JavaScript 运行环境 . |
axios: | 对ajax的封装, 简单来说就是ajax技术实现了局部数据的刷新,axios实现了对ajax的封装 |
1.3.2 后端技术选型
后端技术 | 说明 |
---|---|
Web层 | 借助springmvc接收请求,进行视图跳转 |
Service层 | 借助spring进行IOC、AOP、及事务管理 |
dao层 | 借助mybatis进行数据库交互 |
项目开发环境
开发工具
- 后端: IDEA 2019
- 前端: VS code
- 数据库客户端工具: SQLYog
开发环境
- JDK 11
- Maven 3.6.3
- MySQL 5.7
2.学习Maven进阶的使用(maven聚合工程)
https://blog.csdn.net/weixin_41596178/article/details/123157208
3. 拉勾教育后台管理系统研发
3.1 课程管理模块功能分析
在本次的项目中,首先先来完成拉勾教育后台管理系统的 课程管理模块, 课程管理模块包含了多条件查询、 图片上传、 新建&修改课程、课程状态管理、课程内容展示、回显章节对应的课程信息、新建&修改章节信息、修改章节状态、 新建&修改课时信息等接口的编写
3.1.1 课程管理
- 多条件查询
- 图片上传
- 新建课程信息
- 回显课程信息
- 修改课程信息
- 课程状态管理
- 课程内容展示
- 回显章节对应的课程信息
- 新建&修改章节信息
- 修改章节状态
- 新建课时信息
3.2 课程管理模块表设计
3.2.1 创建数据库及表
在资料中找到 ssm_lagou_edu.sql,使用SQLYog 执行SQL脚本 ,导入表结构及表信息
3.2.2 表关系介绍
1.ER图
2.数据实体描述
2.1 课程表
字段名称 | 类型 | 约束 | 描述 |
---|---|---|---|
id | int(11) unsigned NOT NUL AUTO_INCREMENT | PK | 主键PK |
course_name | varchar(255) | 课程名 | |
brief | varchar(255) | 课程一句话简介 | |
price | double(10,2) | 原价 | |
price_tag | varchar(255) | 原价标签 | |
discounts | double(10,2) | 优惠价 | |
discounts_tag | varchar(255) | 优惠标签 | |
course_description_mark_down | longtext | 描述markdown | |
course_description | longtext | 课程描述 | |
course_img_url | varchar(255) | 课程列表图 | |
is_new | tinyint(1) | 是否新品 | |
is_new_des | varchar(255) | 广告语 | |
last_operator_id | int(11) | 最后操作者 | |
create_time | datetime | 创建时间 | |
update_time | datetime | 更新时间’ | |
is_del | tinyint(1) | 是否删除 | |
total_duration | int(11) | 总时长(分钟) | |
course_list_img | varchar(255) | 课程列表展示图片 | |
status | int(2) | 课程状态,0-草稿,1-上架 | |
sort_num | int(11) | 课程排序,用于后台保存草稿时用到 | |
preview_first_field | varchar(255) | 课程预览第一个字段 | |
preview_second_field | varchar(255) | 课程预览第二个字段 | |
sales | int(11) | 销量 |
2.2 章节表
字段名称 | 类型 | 约束 | 描述 |
---|---|---|---|
id | int(11) | PK | 主键ID |
course_id | int(11) | 课程id | |
section_name | varchar(255) | 章节名 | |
description | varchar(255) | ‘章节描述’ | |
status | int(1) | 状态,0:隐藏;1:待更新;2:已发布 | |
order_num | int(11) | 排序字段 | |
is_de | tinyint(1) | 是否删除 | |
update_time | datetime | '更新时间 | |
create_time | datetime | 记录创建时间 |
2.3 课时表
字段名称 | 类型 | 约束 | 描述 |
---|---|---|---|
id | int(11) | PK | 主键 |
course_id | int(11) | 课程id | |
section_id | int(11) | 章节id | |
theme | varchar(255) | 课时主题 | |
duration | int(11) | '课时时长(分钟) | |
is_free | tinyint(1) | 是否免费 | |
is_del | tinyint(1) | 是否删除 | |
order_num | int(11) | 排序字段 | |
status | int(2) | 课时状态,0-隐藏,1-未发布,2-已发布 | |
update_time | datetime | 更新时间 | |
create_time | datetime | 记录创建时间 |
2.4 课程媒体
字段名称 | 类型 | 约束 | 描述 |
---|---|---|---|
id | int(11) | PK | '课程媒体主键ID |
course_id | int(11) | 课程id | |
section_id | int(11) | 章节id | |
cover_image_url | varchar(255) | 封面图URL | |
duration | varchar(50) | 时长(06:02) | |
file_edk | varchar(500) | 媒体资源文件对应的EDK | |
file_size | double(10,2) | 文件大小MB | |
file_name | varchar(100) | 文件名称 | |
file_dk | varchar(100) | '媒体资源文件对应的DK | |
duration_num | varchar(50) | 时长,秒数 | |
file_id | varchar(50) | 媒体资源文件ID | |
is_del | tinyint(1) | 是否删除,0未删除,1删除 | |
update_time | datetime | 更新时间 | |
create_time | datetime | 创建时间 |
3.3 课程管理模块接口实现
多条件课程列表查询
3.3.1 需求分析
根据课程名称及课程状态进行多条件查询
3.3.2 查看接口文档,进行编码
查看接口文档
实体类:Course
/*** 课程类*/
public class Course {//主键private int id;//课程名称private String courseName;//课程一句话简介private String brief;//原价private double price;//原价标签private String priceTag;//优惠价private double discounts;//优惠价标签private String discountsTag;//课程内容markdownprivate String courseDescriptionMarkDown;//课程描述private String courseDescription;//课程分享图片urlprivate String courseImgUrl;//是否新品private int isNew;//广告语private String isNewDes;//最后操作者private int lastOperatorId;//自动上架时间private Date autoOnlineTime;//创建时间private Date createTime;//更新时间private Date updateTime;//是否删除private int isDel;//总时长private int totalDuration;//课程列表展示图片private String courseListImg;//课程状态,0-草稿,1-上架private int status;//课程排序private int sortNum;//课程预览第一个字段private String previewFirstField;//课程预览第二个字段private String previewSecondField;//销量private int sales;get&set...
}
返回结果实体类:ResponseResult
public class ResponseResult {private Boolean success;private Integer state;private String message;private Object content;public ResponseResult() {}public ResponseResult(Boolean success, Integer state, String message, Objectcontent) {this.success = success;this.state = state;this.message = message;this.content = content;}//getter/setter..
}
实体类:CourseVo(View Object表现层对象:主要用于表现层来接收参数的你)
public class CourseVO {/**
* 课程名称
* */private String courseName;/**
* 课程状态
* */private Integer status;// getter/setter....
}
Dao层:CourseMapper
public interface CourseMapper {/*** 多条件课程列表查询*/public List<Course> findCourseByConditioin(CourseVo courseVo);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lagou.dao.CourseMapper"><!-- 多条件课程列表查询 --><select id="findCourseByConditioin"parameterType="com.lagou.domain.CourseVO" resultType="com.lagou.domain.Course">SELECTid,course_name,price,sort_num,STATUSFROM course<where><if test="true">and is_del != 1</if><if test="courseName != null and courseName != ''">and course_name like concat('%',#{courseName},'%')</if><if test="status != null and status !=''">and status = #{status}</if></where></select>
Service层:CourseService
public interface CourseService {/**
* 多条件查询课程列表
* */public List<Course> findCourseByConditioin(CourseVO courseVO);
}@Service
public class CourseServiceImpl implements CourseService {@Autowiredprivate CourseMapper courseMapper;@Overridepublic List<Course> findCourseByConditioin(CourseVO courseVO) {List<Course> courseList = courseMapper.findCourseByConditioin(courseVO);return courseList;}
}
Web层:CourseController
@RestController
@RequestMapping("/course")
public class CourseController {@Autowiredprivate CourseService courseService;/**
* 查询课程信息&条件查询 接口
* */@RequestMapping("/findCourseByConditioin")public ResponseResult findCourseByConditioin(@RequestBody CourseVO courseVO){List<Course> courseList = courseService.findCourseByConditioin(courseVO);ResponseResult result = new ResponseResult(true,200,"响应成功",courseList);return result;}
}
Postman测试接口
课程图片上传
需求:在新增课程页面需要进行图片上传,并回显图片信息
查看接口文档,进行编码
springmvc.xml配置文件解析器
<!--5.配置文件解析器-->
<!-- 此处id为固定写法,不能随便取名-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><property name="maxUploadSize" value="1048576"></property>
</bean>
Web层:CourseController
/**
* 图片上传接口
* */
@RequestMapping("/courseUpload")
public ResponseResult fileUpload(@RequestParam("file")MultipartFile file,HttpServletRequest request){try {//1.判断文件是否为空if(file.isEmpty()){throw new RuntimeException();}//2.获取项目部署路径// D:\apache-tomcat-8.5.56\webapps\ssm_web\String realPath = request.getServletContext().getRealPath("/");// D:\apache-tomcat-8.5.56\webapps\String webappsPath = realPath.substring(0,realPath.indexOf("ssm_web"));//3.获取原文件名String fileName = file.getOriginalFilename();//4.新文件名String newFileName = System.currentTimeMillis() +fileName.substring(fileName.lastIndexOf("."));//5.上传文件String uploadPath = webappsPath+"upload\\";File filePath = new File(uploadPath,newFileName);//如果目录不存在就创建目录if(!filePath.getParentFile().exists()){filePath.getParentFile().mkdirs();System.out.println("创建目录: " + filePath);}file.transferTo(filePath);//6.将文件名和文件路径返回Map<String,String> map = new HashMap<>();map.put("fileName",newFileName);map.put("filePath",LOCAL_URL+"/upload/"+newFileName);ResponseResult result = new ResponseResult(true,200,"响应成功",map);return result;} catch (Exception e) {e.printStackTrace();return null;}
}
如果想要通过地址直接获取到图片,那么需要在tomcat配置中配置图片文件夹
Postman测试接口
新建课程信息
需求分析: 填写好新增课程信息后,点击保存,将表单信息保存到数据库中
domain层:CourseVO进行修改
存储课程信息和教师信息
/*VO:View Object 表现层对象:在表现层接收前台参数*/
public class CourseVO {//主键private int id;//课程名称private String courseName;//课程一句话简介private String brief;//原价private double price;//原价标签private String priceTag;//优惠价private double discounts;//优惠价标签private String discountsTag;//课程内容markdownprivate String courseDescriptionMarkDown;//课程描述private String courseDescription;//课程分享图片urlprivate String courseImgUrl;//是否新品private int isNew;//广告语private String isNewDes;//最后操作者private int lastOperatorId;//是否删除private int isDel;//总时长private int totalDuration;//课程列表展示图片private String courseListImg;//课程状态,0-草稿,1-上架private int status;//课程排序private int sortNum;//课程预览第一个字段private String previewFirstField;//课程预览第二个字段private String previewSecondField;//销量private int sales;//讲师姓名private String teacherName;//讲师职务private String position;//介绍private String description;
}
查看接口文档,进行编码
Dao层:CourseMapper
public interface CourseMapper {/**
* 保存课程信息
*/public int saveCourse(Course course);/**
* 保存讲师信息
* */public void saveTeacher(Teacher teacher);
}
CourseMapper.xml
<!-- 保存课程信息 -->
<insert id="saveCourse" parameterType="com.lagou.domain.Course" >INSERT INTO course(course_name,brief,preview_first_field,preview_second_field,course_img_url,course_list_img,sort_num,price,discounts,sales,discounts_tag,course_description_mark_down,create_time,update_time) VALUES(#{courseName},#{brief},#{previewFirstField},#{previewSecondField},#{courseImgUrl},#{courseListImg},#{sortNum},#{price},#{discounts},#{sales},#{discountsTag},#{courseDescriptionMarkDown},#{createTime},#{updateTime});<!-- 获取提交成功记录方法的ID值复制给Course实体中ID属性--><selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id">SELECT LAST_INSERT_ID();</selectKey>
</insert><!-- 保存讲师信息 -->
<insert id="saveTeacher" parameterType="com.lagou.domain.Teacher">INSERT INTO teacher(course_id,teacher_name,POSITION,description,create_time,update_time) VALUES(#{courseId},#{teacherName},#{position},#{description},#{createTime},#{updateTime});
</insert>
BeanUtils封装实体类
通过Spring中的BeanUtils.copyProperties()来进行封装实体类
介绍:反射将一个对象的值赋值个另外一个对象(前提是对象中属性的名字相同,前面复制给后面)
引用:
<dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>4.3.2.RELEASE</version>
</dependency>
Service层:CourseService
import org.apache.commons.beanutils.BeanUtils;public interface CourseService {/**
* 保存课程信息
* */public void saveCourseOrTeacher(CourseVO courseVO);
}@Service
public class CourseServiceImpl implements CourseService {@Autowiredprivate CourseMapper courseMapper;@Overridepublic void saveCourseOrTeacher(CourseVO courseVO) {try {//封装课程信息Course course = new Course();//通过反射将一个对象的值赋值个另外一个对象(前提是对象中属性的名字相同,前面复制给后面)BeanUtils.copyProperties(course,courseVO);//补全信息Date date = new Date();course.setCreateTime(date);course.setUpdateTime(date);//保存课程courseMapper.saveCourse(course);//获取新插入数据的idint id = course.getId();//封装讲师信息Teacher teacher = new Teacher();BeanUtils.copyProperties(teacher,courseVO);//补全信息teacher.setCourseId(id);teacher.setCreateTime(date);teacher.setUpdateTime(date);//保存讲师信息courseMapper.saveTeacher(teacher);} catch (Exception e) {e.printStackTrace();}}
}
Web层:CourseController
@RestController
@RequestMapping("/course")
public class CourseController {@Autowiredprivate CourseService courseService;/**
* 保存&修改课程信息接口
* */@RequestMapping("/saveOrUpdateCourse")public ResponseResult saveOrUpdateCourse(@RequestBody CourseVO courseVO){try {if(courseVO.getId() == null){courseService.saveCourseOrTeacher(courseVO);ResponseResult result = new ResponseResult(true,200,"响应成功",null);return result;}else{courseService.updateCourseOrTeacher(courseVO);ResponseResult result = new ResponseResult(true,200,"响应成功",null);return result;}} catch (Exception e) {e.printStackTrace();return null;}}
}
Postman测试接口
回显课程信息
需求分析: 点击编辑按钮,回显课程信息
查看接口文档,进行编码
Dao层:CourseMapper
public interface CourseMapper {/**
* 根据id 获取课程信息
* */public CourseVO findCourseById(int id);
}
CourseMapper.xml
<!-- 根据id查询 -->
<select id="findCourseById" parameterType="int" resultType="com.lagou.domain.CourseVO">SELECTcourse_name,brief,teacher_name,POSITION,description,preview_first_field,preview_second_field,course_img_url,course_list_img,sort_num,discounts,price,sales,discounts_tag,course_description_mark_downFROM course LEFT JOIN teacher ON course.id = teacher.course_idWHERE course.id = #{id}
</select>
Service层:CourseService
public interface CourseService {/**
* 根据id获取课程信息
* */public CourseVO findCourseById(int id);
}@Service
public class CourseServiceImpl implements CourseService {@Autowiredprivate CourseMapper courseMapper;@Overridepublic CourseVO findCourseById(int id) {return courseMapper.findCourseById(id);}
}
Web层:CourseController
@RestController
@RequestMapping("/course")
public class CourseController {@Autowiredprivate CourseService courseService;/**
* 根据id获取课程信息
* */@RequestMapping("/findCourseById")public ResponseResult findCourseById(@RequestParam int id) {try {CourseVO courseVO = courseService.findCourseById(id);ResponseResult result = new ResponseResult(true,200,"响应成功",courseVO);return result;} catch (Exception e) {e.printStackTrace();return null;}}
}
Postman测试接口
修改课程信息
需求分析: 点击保存按钮,将修改后的课程信息保存到数据库中
查看接口文档,进行编码
Dao层:CourseMapper
public interface CourseMapper {/**
* 修改课程信息
* */public void updateCourse(Course course);/**
* 修改讲师信息
* */public void updateTeacher(Teacher teacher);
}
CourseMapper.xml
<!--trim元素的主要功能是可以在自己包含的内容前加上某些前缀,也可以在其后加上某些后缀,与之对应的属性是prefix和suffix;
可以把包含内容的首部某些内容覆盖,即忽略,也可以把尾部的某些内容覆盖,对应的属性是prefixOverrides和suffixOverrides;
正因为trim有这样的功能,所以我们也可以非常简单的利用trim来代替where元素的功能。-->
<!-- 修改课程信息 -->
<update id="updateCourse" parameterType="com.lagou.domain.Course">UPDATE course<trim prefix="SET" suffixOverrides=","><if test="courseName != null and courseName != ''">course_name = #{courseName},</if><if test="brief != null and brief != ''">brief=#{brief},</if><if test="previewFirstField != null and previewFirstField != ''">preview_first_field=#{previewFirstField},</if><if test="previewSecondField != null and previewSecondField != ''">preview_second_field=#{previewSecondField},</if><if test="courseImgUrl != null and courseImgUrl != ''">course_img_url=#{courseImgUrl},</if><if test="courseListImg != null and courseListImg != ''">course_list_img=#{courseListImg},</if><if test="sortNum != null and sortNum != ''">sort_num=#{sortNum},</if><if test="price != null and price != ''">price=#{price},</if><if test="discounts != null and discounts != ''">discounts=#{discounts},</if><if test="sales != null and sales != '' or sales==0">sales=#{sales},</if><if test="discountsTag != null and discountsTag != ''">discounts_tag=#{discountsTag},</if><if test="courseDescriptionMarkDown != null andcourseDescriptionMarkDown != ''">course_description_mark_down=#{courseDescriptionMarkDown},</if><if test="updateTime != null">update_time=#{updateTime},</if></trim><where><if test="id!=null and id != '' ">id=#{id}</if></where>
</update><!-- 修改讲师信息 -->
<update id="updateTeacher" parameterType="com.lagou.domain.Teacher">UPDATE teacher<trim prefix="SET" suffixOverrides=","><if test="teacherName != null and teacherName != ''">teacher_name = #{teacherName},</if><if test="position != null and position != ''">position = #{position},</if><if test="description != null and description != ''">description = #{description},</if><if test="updateTime != null">update_time=#{updateTime}</if></trim><where><if test="courseId != null and courseId != '' ">course_id = #{courseId}</if></where>
</update>
Service层:CourseService
public interface CourseService {/*** 修改课程信息* */public void updateCourseOrTeacher(CourseVO courseVO);
}@Service
public class CourseServiceImpl implements CourseService {@Autowiredprivate CourseMapper courseMapper;@Overridepublic void updateCourseOrTeacher(CourseVO courseVO) {try {//封装课程信息Course course = new Course();BeanUtils.copyProperties(course,courseVO);//补全信息Date date = new Date();course.setUpdateTime(date);//更新课程courseMapper.updateCourse(course);//封装讲师信息Teacher teacher = new Teacher();BeanUtils.copyProperties(teacher,courseVO);//补全信息teacher.setCourseId(course.getId());teacher.setUpdateTime(date);//更新讲师信息courseMapper.updateTeacher(teacher);} catch (Exception e) {e.printStackTrace();}}
}
Web层:CourseController
@RestController
@RequestMapping("/course")
public class CourseController {@Autowiredprivate CourseService courseService;/*新增课程信息及讲师信息新增课程信息和修改课程信息要写在同一个方法中,通过传过来的值中是否有id来进行判断*/@RequestMapping("/saveOrUpdateCourse")public ResponseResult saveOrUpdateCourse(@RequestBody CourseVO courseVO) throws InvocationTargetException, IllegalAccessException {ResponseResult responseResult = null;//对CourseVO中的id类型修改为Integerif (courseVO.getId() == null) {courseService.saveCourseOrTeacher(courseVO);responseResult = new ResponseResult(true, 200, "新增成功", null);} else {courseService.updateCourseOrTeacher(courseVO);responseResult = new ResponseResult(true, 200, "更新成功", null);}return responseResult;}
}
课程状态管理
需求分析: 在课程列表展示页面中,可以通过点击 上架/下架按钮,修改课程状态
访问:http://localhost:8080/ssm-web/course/updateCourseStatus?status=1&id=15
查看接口文档,进行编码
Dao层:CourseMapper
public interface CourseMapper {/**
* 修改课程状态
* */public void updateCourseStatus(Course course);
}
CourseMapper.xml
<!-- 修改课程状态 -->
<update id="updateCourseStatus" parameterType="com.lagou.domain.Course">UPDATE course SET STATUS = #{status} ,update_time = #{updateTime} WHERE id = #{id}
</update>
Service层:CourseService
/**
* 修改课程状态
* */
public void updateCourseStatus(int id,int status);@Override
public void updateCourseStatus(int id,int status) {try {//封装数据Course course = new Course();course.setStatus(status);course.setId(id);course.setUpdateTime(new Date());//调用DaocourseMapper.updateCourseStatus(course);} catch (Exception e) {e.printStackTrace();}
}
Web层:CourseController
/**
* 修改课程状态
* */
@RequestMapping("/updateCourseStatus")
public ResponseResult updateCourseStatus(@RequestParam Integer id,@RequestParam Integer status){try {//执行修改操作courseService.updateCourseStatus(id, status);//保存修改后的状态,并返回Map<String,Integer> map = new HashMap<>();map.put("status",status);ResponseResult result = new ResponseResult(true,200,"响应成功",map);return result;} catch (Exception e) {e.printStackTrace();}return null;
}
课程内容展示
需求:点击内容管理,展示课程对应的课程内容(课程内容包含了章节和课时)
查看接口文档,进行编码
实体类CourseSection
注意一对多关系:课时集合lessonList;
Dao层:CourseContentMapper
public interface CourseContentMapper {/**
* 查询课程下的章节与课时信息
* */public List<CourseSection> findSectionAndLessonByCourseId(int courseId);
}
<!-- 课时表字段信息 -->
<sql id="lesson_column_list">cl.id as lessonId,cl.course_id,cl.section_id,cl.theme,cl.duration,cl.is_free,cl.order_num,cl.status
</sql><!-- 根据课程ID 查询课程内容(章节与课时) -->
<select id="findSectionAndLessonByCourseId" parameterType="int" resultMap="SectionAndLessonResultMap">SELECTcs.*,<include refid="lesson_column_list"/>FROM course_section csLEFT JOIN course_lesson cl ON cs.id = cl.section_idWHERE cs.course_id = #{courseId} ORDER BY cs.order_num;
</select><!-- 一对多配置,一个章节下有多个课时 -->
<resultMap id="SectionAndLessonResultMap" type="com.lagou.domain.CourseSection"><result property="id" column="id"></result><result property="courseId" column="course_id"></result><result property="sectionName" column="section_name"></result><result property="description" column="description"></result><result property="orderNum" column="order_num"></result><result property="status" column="status"></result><!-- 使用 collection,配置一对多关系 --><collection property="lessonList" resultMap="lessionListResultMap"/>
</resultMap><resultMap id="lessionListResultMap" type="com.lagou.domain.CourseLesson"><id property="id" column="lessonId"></id><result property="courseId" column="course_id"></result><result property="sectionId" column="section_id"></result><result property="theme" column="theme"></result><result property="duration" column="duration"></result><result property="isFree" column="is_free"></result><result property="orderNum" column="order_num"></result><result property="status" column="status"></result>
</resultMap>
Service层:CourseContentService
public interface CourseContentService {public List<CourseSection> findSectionAndLessonByCourseId(int courseId);
}@Service
public class CourseContentServiceImpl implements CourseContentService {@Autowiredprivate CourseContentMapper contentMapper;@Overridepublic List<CourseSection> findSectionAndLessonByCourseId(int courseId) {List<CourseSection> sectionList = contentMapper.findSectionAndLessonByCourseId(courseId);return sectionList;}
}
Web层:CourseContentController
@RestController
@RequestMapping("/courseContent")
public class CourseContentController {@Autowiredprivate CourseContentService contentService;/**
* 查询课程内容
* */@RequestMapping("/findSectionAndLesson")public ResponseResult findSectionAndLessonByCourseId(@RequestParam int courseId){try {//调用serviceList<CourseSection> sectionList =contentService.findSectionAndLessonByCourseId(courseId);//封装数据并返回ResponseResult result = new ResponseResult(true,200,"响应成功",sectionList);return result;} catch (Exception e) {e.printStackTrace();return null;}}
}
回显章节对应的课程信息
需求:在课程内容界面回显课程信息
查看接口文档,进行编码
Dao层:CourseContentMapper
public interface CourseContentMapper {/**
* 回显章节对应的课程信息
* */public Course findCourseByCourseId(int courseId);
}
<!-- 回显课程信息 -->
<select id="findCourseByCourseId" parameterType="int" resultType="com.lagou.domain.Course">SELECT id,course_name FROM course WHERE id = #{courseId}
</select>
Service层:CourseContentService
public interface CourseContentService {public Course findCourseByCourseId(int courseId);
}@Service
public class CourseContentServiceImpl implements CourseContentService {@Autowiredprivate CourseContentMapper contentMapper;@Overridepublic Course findCourseByCourseId(int courseId) {Course course = contentMapper.findCourseByCourseId(courseId);return course;}
}
Web层:CourseContentController
@RestController
@RequestMapping("/courseContent")
public class CourseContentController {@Autowiredprivate CourseContentService contentService;/**
* 回显章节对应的课程信息
* */@RequestMapping("/findCourseByCourseId")public ResponseResult findCourseByCourseId(@RequestParam int courseId){try {//调用serviceCourse course = contentService.findCourseByCourseId(courseId);ResponseResult result = new ResponseResult(true,200,"响应成功",course);return result;} catch (Exception e) {e.printStackTrace();return null;}}
新建章节信息
需求分析: 在课程内容展示页面中,可以通过点击添加阶段按钮,添加章节信息
查看接口文档,进行编码
Dao层:CourseContentMapper
/**
* 保存章节
* */
public void saveSection(CourseSection section);
<!-- 保存章节 -->
<insert id="saveSection" parameterType="com.lagou.domain.CourseSection">INSERT INTO course_section(course_id,section_name,description,order_num,STATUS,create_time,update_time)VALUES(#{courseId},#{sectionName},#{description},#{orderNum},#{status},#{createTime},#{updateTime});
</insert>
Service层:CourseContentService
public void saveSection(CourseSection section);@Override
public void saveSection(CourseSection section) {//补全信息Date date = new Date();section.setCreateTime(date);section.setUpdateTime(date);contentMapper.saveSection(section);
}
Web层:CourseContentController
@RequestMapping("/saveOrUpdateSection")
public ResponseResult saveOrUpdateSection(@RequestBody CourseSection section) {try {contentService.saveSection(section);return new ResponseResult(true,200,"响应成功",null);} catch (Exception e) {e.printStackTrace();return null;}
}
修改章节信息
需求分析: 点击确定按钮,将修改后的章节信息保存到数据库中
查看接口文档,进行编码
Dao层:CourseContentMapper
/**
* 修改章节
* */
public void updateSection(CourseSection section);
<!-- 修改章节 -->
<update id="updateSection" parameterType="com.lagou.domain.CourseSection">UPDATE course_section<trim prefix="SET" suffixOverrides=","><if test="sectionName != null and sectionName != ''">section_name = #{sectionName},</if><if test="description != null and description != ''">description = #{description},</if><if test="orderNum != null and orderNum != '' or orderNum == 0">order_num = #{orderNum},</if><if test="updateTime != null">update_time=#{updateTime}</if></trim><where><if test="id != null and id != '' ">id = #{id}</if></where>
</update>
Service层:CourseContentService
public void updateSection(CourseSection section);@Override
public void updateSection(CourseSection section) {//补全信息Date date = new Date();section.setUpdateTime(date);contentMapper.updateSection(section);
}
Web层:CourseContentController
/**
* 保存&修改章节信息
*/
@RequestMapping("/saveOrUpdateSection")
public ResponseResult saveOrUpdateSection(@RequestBody CourseSection section) {try {//判断携带id是修改操作否则是插入操作if(section.getId() == null){contentService.saveSection(section);return new ResponseResult(true,200,"响应成功",null);}else{contentService.updateSection(section);return new ResponseResult(true,200,"响应成功",null);}} catch (Exception e) {e.printStackTrace();return null;}
}
修改章节状态
需求:点击修改章节状态按钮,将当前章节信息的状态进行修改
Dao层:CourseContentMapper
/**
* 修改章节状态
* */
public void updateSectionStatus(CourseSection section);
CourseContentMapper.xml
<!-- 修改章节状态 -->
<update id="updateSectionStatus" parameterType="com.lagou.domain.CourseSection">UPDATE course_section setstatus = #{status},update_time = #{updateTime}WHERE id = #{id}
</update>
Service层:CourseContentService
public void updateSectionStatus(int id,int status);@Override
public void updateSectionStatus(int id,int status) {//封装数据CourseSection section = new CourseSection();section.setId(id);section.setStatus(status);section.setUpdateTime(new Date());contentMapper.updateSectionStatus(section);
}
Web层:CourseContentController
/**
* 修改章节状态
* 状态,0:隐藏;1:待更新;2:已发布
* */
@RequestMapping("/updateSectionStatus")
public ResponseResult updateSectionStatus(@RequestParam int id,@RequestParam int status){try {contentService.updateSectionStatus(id,status);//封装最新的状态信息Map<String,Integer> map = new HashMap<>();map.put("status",status);ResponseResult result = new ResponseResult(true,200,"响应成功",map);return result;} catch (Exception e) {e.printStackTrace();return null;}
}
新建课时信息
需求:点击添加阶段按钮,将弹出页面填写的章节信息保存到数据库中
Dao层:CourseContentMapper
/**
* 保存课时
* */
public void saveLesson(CourseLesson lesson);
<!-- 添加课时 -->
<insert id="saveLesson" parameterType="com.lagou.domain.CourseLesson">INSERT INTO course_lesson (id,course_id,section_id,theme,duration,is_free,order_num,create_time,update_time)VALUES(#{id},#{courseId},#{sectionId},#{theme},#{duration},#{isFree},#{orderNum},#{createTime},#{updateTime});
</insert>
Service层:CourseContentService
public void saveLesson(CourseLesson lesson);@Override
public void saveLesson(CourseLesson lesson) {//补全信息Date date = new Date();lesson.setCreateTime(date);lesson.setUpdateTime(date);contentMapper.saveLesson(lesson);
}
Web层:CourseContentController
/**
* 保存&修改课时
* */
@RequestMapping("/saveOrUpdateLesson")
public ResponseResult saveOrUpdateLesson(@RequestBody CourseLesson lesson){try {if(lesson.getId() == null){contentService.saveLesson(lesson);return new ResponseResult(true,200,"响应成功",null);}else{contentService.updateLesson(lesson);return new ResponseResult(true,200,"响应成功",null);}} catch (Exception e) {e.printStackTrace();return null;}
}
06_04_任务一:拉勾教育后台管理系统[课程管理模块、图片上传、 BeanUtils封装实体类](SSM)相关推荐
- 06_04_任务二:SSM拉勾教育后台管理系统(广告模块与用户模块)
拉勾教育后台管理系统(SSM) 广告模块 广告模块功能分析 拉勾教育后台管理系统的 广告管理模块包含了以下功能: 广告位列表查询 添加&修改广告位 回显广告位名称 广告分页查询 图片上传接口 ...
- 拉勾教育后台管理系统(SSM)(课程管理模块开发)【学习笔记】
文章目录 1.项目架构 1.1.项目介绍 1.2.技术选型 1.2.1.前端技术选型 1.2.2.后端技术选型 1.3.项目开发环境 2.Maven进阶使用(Maven聚合工程) 2.1.maven的 ...
- 06_04_SSM拉勾教育后台管理系统(权限模块\登录及动态菜单)
拉勾教育后台管理系统(SSM)权限模块 权限概念介绍 权限:权利(能做的)和限制(不能做的),在权限范围内做好自己的事情,不该看的不看,不该做的不做 认证: 验证用户名密码是否正确的过程 授权: 对用 ...
- 电商生鲜网站开发(四)——后台开发:商品模块-图片上传/多条件拼接sql
电商生鲜网站开发(四)--后台开发:商品模块-图片上传/多条件拼接sql 增加商品 上传图片 更新商品 删除商品 批量上下架 图片上传功能 文件名UUID 通用唯一识别码(Universally Un ...
- SSM-下(拉勾教育后台管理系统-前端)
第六阶段模块五 任务一 课程和广告模块前端开发 1.Vue回顾 1.1 项目结构说明 们使用脚手架快速构建Vue项目 |--- edu-boss 项目名称|--- node_modules 存放依赖包 ...
- Java-Web机试练习题一、后台管理系统——管理员管理模块
题目:后台管理系统--管理员管理模块 一. 语言和环境 1. 实现语言:JAVA 语言. 2. 环境要求:MyEclipse/Eclipse + Tomcat + MySql. 3. 使用技术:Jsp ...
- SSM框架之酒店管理系统十一(房型管理,图片上传)
SSM框架之酒店管理系统十一(房型管理,图片上传) 1.数据库完善 create table t_room_type (id int auto_increment comment '房间类型id'pr ...
- 9.1黑马Vue电商后台管理系统商品管理模块完善:编辑商品的功能
在原视频中,老师跳过了这个功能,我觉得自己去实现也可以锻炼自己,于是自己补充了编辑功能 同用户管理,权限管理等之前各个模块的编辑功能不同,因为商品具有很多可编辑的选项,所以选择像添加商品一样,单独放在 ...
- 上传文件java后台获取为空_java图片上传,通过MultipartFile方式,如果后台获取null检查是否缺少步骤...
本方法基于springMvc 1.首先需要在webap下创建images 2.在springmvc.xml上引入 3.配置web.xml过滤器 4.后台代码 import org.springfram ...
最新文章
- python 类属性及限制
- MySQL唯一约束(UNIQUE KEY)
- 网络库urillib3
- 200设备管理器找不到蓝牙_达尔优LK200蓝牙键盘,一键切换+支持三台设备+百元不到...
- linux网络存储服务器选题意义,基于嵌入式Linux的网络存储的实现和研究
- HihoCoder - 1457 后缀自动机四·重复旋律7(后缀自动机)
- Spark NaiveBayes Demo 朴素贝叶斯分类算法
- 【Python】Python中的lambda匿名函数
- 无法读取内存属于错误吗_索佳全站仪错误信息讲解
- Python 3.8与普通程序员有关的几个新特性
- python的线程组怎么写_Python高级——多任务编程之线程
- 如何不用更改底层来实现Dao多样化
- html5数组循环右移,下面的程序代码实现将一个一维数组中元素向右循环移动 移位次数由文本框Text输入。例如数组各元素...
- 每日一句20191019
- ckeditor4.x操作之在页面中引入(一)
- 2016中国大数据市场研究报告
- 信号的宽带和计算机网络的宽带有什么不同,路由器和调制解调器(宽带猫)有什么区别?...
- 没有公网IP,3个路由器就能解决连锁视频监控
- 2019.7山东省夏令营游记
- Google Chrome浏览器调整分辨率的插件