jquery后台内容管理_教育平台项目后台管理系统:课程内容模块
发布日期:2021-06-24 13:16:33 浏览次数:3 分类:技术文章

本文共 15502 字,大约阅读时间需要 51 分钟。

351f7a51fcabd3981e3c1f0705e7549e.png

开发流程

需求分析

配置课时(课程内容管理)模块,主要是对课程内容进行管理。

数据库表分析

course - 课程表

course_section - 课程章节表

course_lesson - 课时信息表

一个课程表对多个课程章节表,一个课程章节表对多个课时表。

实体类设计

Course 类与 Course_Section 类是一对多关系;Course_Section 类与 Course_Lesson 类是一对多关系。

在 Course 类中定义一个 List 集合,并指定 List 的泛型是 Course_Section 类型,表示 一个课程中可以包含多个章节。

在 Course_Section 类中,定义一个 Course 类型的属性,用来保存章节所对应的具体的课程信息。

在 Course_Section 类中定义一个 List 集合,并指定 List 的泛型是 Course_Lesson 类型,这样就可以表示一个章节中包含多个课时。

// Course 类:...  List sectionList = new ArrayList<>();...// Course_Section 类:...  List lessonList = new ArrayList<>();  private Course course;...​// Course_Lesson 类:...  private Course_Section course_section;...

Dao 接口及实现类编写

/** * 课程内容管理 DAO 层接口 * */public interface CourseContentDao {}​/** * 课程内容管理 DAO 层实现类 * */public class CourseContentDaoImpl implements CourseContentDao {}

Service 接口及实现类编写

/** * 课程内容管理 Service 层接口 * */public interface CourseContentService {}​/** * 课程内容管理 Service 层实现类 * */public class CourseContentServiceImpl implements CourseContentService {}

CourseContentServlet 编写

CourseContentServlet 继承 BaseServlet

@WebServlet("/courseContent")public class CourseContentServlet extends BaseServlet {}

功能一:展示课程内容

需求分析

分析:要展示的内容是对应课程下的章节与课时信息

-- 查询 ID 为 1 的课程的章节与课时信息SELECT     cs.`id`,    cs.`section_name`,    cl.`theme` '课时名称'FROM course_section cs INNER JOIN course_lesson clON cs.`id` = cl.`section_id` WHERE cs.`course_id` = 59;​-- 在程序中尽量避免使用连接查询。可以将上面的 SQL 进行拆分,每一条 SQL 对应一个功能​-- 根据课程 ID 查询章节相关的内容SELECT     id,    course_id,    section_name,    description,    order_num,    `status`FROM course_section WHERE course_id = 59;​-- 根据章节 ID 查询课时相关的内容SELECT    id,    course_id,    section_id,    theme,    is_free,    order_num,    `status`FROM course_lesson WHERE section_id = 32;

DAO 层编写

编写两个方法

CourseContentDaoImpl

/** * 根据课程 ID 查询课程相关信息 * * @param courseId */@Overridepublic List findSectionAndLessonByCourseId(int courseId) {    try {        // 创建 QueryRunner        QueryRunner qr = new QueryRunner(DruidUtils.getDataSource());​        // 编写 SQL        String sql = "SELECT " +                "id," +                "course_id," +                "section_name," +                "description," +                "order_num," +                "STATUS" +                "FROM course_section WHERE course_id = ?";​        // 执行查询        List sectionList = qr.query(sql,                new BeanListHandler(Course_Section.class), courseId);​        // 根据章节 ID 查询课时信息        for (Course_Section section : sectionList) {            // 调用获取章节对应的课时方法,将课时数据封装到章节对象中            section.setLessonList(findLessonBySectionId(section.getId()));        }​        // 返回结果        return sectionList;    } catch (SQLException throwables) {        throwables.printStackTrace();    }    return null;}​/** * 根据章节 ID 查询章节相关的课时信息 * * @param sectionId */@Overridepublic List findLessonBySectionId(int sectionId) {    try {        // 创建 QueryRunner        QueryRunner qr = new QueryRunner(DruidUtils.getDataSource());​        // 编写 SQL        String sql = "SELECT " +                "id," +                "course_id," +                "section_id," +                "theme," +                "duration," +                "is_free," +                "order_num," +                "STATUS" +                "FROM course_lesson WHERE section_id = ?";​        // 执行查询        return qr.query(sql, new BeanListHandler(Course_Lesson.class), sectionId);    } catch (SQLException throwables) {        throwables.printStackTrace();    }​    return null;}

DAO 层测试

public class TestCourseContentDao {​    CourseContentDao contentDao = new CourseContentDaoImpl();​    /**     * 测试 查询对应课程下的章节与课时     */    @Test    public void testFindSectionAndLessonByCourseId(){        List list = contentDao.findSectionAndLessonByCourseId(59);        // 遍历输出章节信息        for (Course_Section courseSection : list) {            System.out.println(courseSection.getId() + " = " + courseSection.getSection_name());​            List lessonList = courseSection.getLessonList();            // 遍历输出课时信息            for (Course_Lesson courseLesson : lessonList) {                System.out.println(courseLesson.getId() + " = " + courseLesson.getTheme() + " = "                        + courseLesson.getSection_id());            }            System.out.println();        }    }}

Service 层编写

CourseContentServiceImpl

CourseContentDao contentDao = new CourseContentDaoImpl();/** * 根据课程 id 查询课程内容 */@Overridepublic List findSectionAndLessonByCourseId(int courseId) {    return contentDao.findSectionAndLessonByCourseId(courseId);}

Servlet 编写

CourseContentServlet 中添加 findSectionAndLessonByCourseId 方法

/** * 展示对应课程的章节与课时信息 */public void findSectionAndLessonByCourseId(HttpServletRequest request, HttpServletResponse response) {    try {        // 获取参数        String course_id = request.getParameter("course_id");        // 业务处理        CourseContentService contentService = new CourseContentServiceImpl();        List sectionList = contentService.findSectionAndLessonByCourseId(Integer.parseInt(course_id));        // 返回结果        response.getWriter().println(JSON.toJSONString(sectionList));    } catch (IOException e) {        e.printStackTrace();    }}

接口测试:使用 Postman 根据接口文档进行测试

功能二:新建章节信息

需求分析

首先根据课程 ID 查询课程名称进行回显,然后获取输入的新的章节信息,执行保存章节数据。

Dao 层编写

CourseContentDaoImpl

...​/** * 添加章节时进行数据回显 */@Overridepublic Course findCourseByCourseId(int courseId) {    try {        // 创建 QueryRunner        QueryRunner qr = new QueryRunner(DruidUtils.getDataSource());​        // 编写 SQL        String sql = "SELECT id, course_name FROM course WHERE id = ?";​        // 执行查询并返回结果        return qr.query(sql, new BeanHandler(Course.class), courseId);    } catch (SQLException throwables) {        throwables.printStackTrace();    }​    return null;}​/** * 保存章节信息 */@Overridepublic int saveSection(Course_Section section) {    try {        // 创建 QueryRunner        QueryRunner qr = new QueryRunner(DruidUtils.getDataSource());​        // 编写 SQL        String sql = "INSERT INTO course_section(" +                "course_id, " +                "section_name, " +                "description, " +                "order_num, " +                "`status`, " +                "create_time, " +                "update_time)" +                "VALUES(?, ?, ?, ?, ?, ?, ?);";​        // 准备参数        Object[] params = {section.getCourse_id(), section.getSection_name(),                section.getDescription(), section.getOrder_num(), section.getStatus(),                section.getCreate_time(), section.getUpdate_time()};​        // 返回受影响的行数        return qr.update(sql, params);    } catch (SQLException throwables) {        throwables.printStackTrace();    }​    return 0;}​...

Dao 层测试 TestCourseContentDao

/** * 测试 根据课程 id 回显课程名称 */@Testpublic void testFindCourseByCourseId() {    Course course = contentDao.findCourseByCourseId(59);    System.out.println(course.getId() + " " + course.getCourse_name());}​/** * 测试 保存章节信息 */@Testpublic void testSaveSection() {    Course_Section section = new Course_Section();    section.setCourse_id(59);    section.setSection_name("章节名字");    section.setDescription("章节描述");    section.setOrder_num(8);    // 更新时间    String dateFormat = DateUtils.getDateFormat();    section.setCreate_time(dateFormat);    section.setUpdate_time(dateFormat);    // 状态:0 隐藏,1 待更新,2 已发布    section.setStatus(2);    System.out.println(contentDao.saveSection(section));}

Service 层编写

CourseContentServiceImpl

...​/** * 添加章节时进行数据回显 */@Overridepublic Course findCourseById(int courseId) {    return contentDao.findCourseByCourseId(courseId);}​/** * 保存章节信息 */@Overridepublic String saveSection(Course_Section section) {    // 补全章节信息    // 状态:0 隐藏,1 待更新,2 已发布    section.setStatus(2);    String date = DateUtils.getDateFormat();    section.setCreate_time(date);    section.setUpdate_time(date);​    // 调用 Dao 进行插入    if (contentDao.saveSection(section) > 0) {        // 保存成功        return StatusCode.SUCCESS.toString();    } else {        // 保存失败        return StatusCode.FAIL.toString();    }}​...

Servlet 编写

课程信息回显接口

/** * 回显章节对应的课程信息 */public void findCourseById(HttpServletRequest request , HttpServletResponse response){    try {        // 获取参数        String courseId = request.getParameter("course_id");        // 业务处理        CourseContentService contentService = new CourseContentServiceImpl();        Course course = contentService.findCourseById(Integer.parseInt(courseId));        // 返回数据,将对象转换为 JSON,只转换需要的字段        SimplePropertyPreFilter filter = new SimplePropertyPreFilter(Course.class,                "id", "course_name");        response.getWriter().println(JSON.toJSONString(course,filter));    } catch (IOException e) {        e.printStackTrace();    }}

保存章节信息接口

POST 请求方法常用的三种数据提交格式:

  • Content-Type : application/x-www-form-urlencoded 请求体中的数据会以普通表单形式(键值对)发送到后端。
  • Content-Type : application/json ; charset=utf-8 请求体中的数据会以 JSON 字符串的形式发送到后端。
  • Content-Type : multipart/form-data 多部件上传既可以上传键值对,也可以上传文件。

第二种 JSON 格式与第三种多部件上传都无法使用 getParameter() 方法获取数据。

根据接口文档描述:前台传输的是 JSON 格式的数据,使用 getParameter() 方法无法获取参数。

如果请求参数是 JSON 格式的数,可以通过 request.getReader() 这个方法获取一个流对象来进行 读取。

首先,在 BaseServlet 中创建一个方法用来获取 JSON 格式的数据:

/** * 如果 POST 请求格式为 application/json;charset=utf-8 * 则在这个方法中使用流的方式获取到 POST 请求的数据 */public String getPostJSON(HttpServletRequest request){    try {        // 从 request 中获取字符缓冲输入流对象        BufferedReader reader = request.getReader();​        // 创建 StringBuffer 用来保存读取出的数据        StringBuffer sb = new StringBuffer();​        // 循环读取        String line = null;        while((line = reader.readLine()) != null){            // 追加到 StringBuffer 中            sb.append(line);        }​        // 将读取到的内容转换为字符串并返回        return sb.toString();    } catch (IOException e) {        e.printStackTrace();    }​    return null;}

然后,修改 BaseServlet 中的 doPost 方法:

@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {    // 要访问的方法名    String methodName = null;​    // 获取 POST 请求的 Content-Type 类型    String contentType = req.getHeader("Content-Type");​    // 判断传递的数据是不是 JSON 格式    if("application/json;charset=utf-8".equals(contentType)){        // 是 JSON 格式 调用 getPostJSON        String postJSON = getPostJSON(req);        // 将 JSON 格式的字符串转化为 map        Map map = JSON.parseObject(postJSON, Map.class);        // 从 map 集合中获取 methodName        methodName = (String) map.get("methodName");        // 将获取到的数据保存到 request 域对象中        req.setAttribute("map", map);    } else {        methodName = req.getParameter("methodName");    }​    // 判断并执行对应的方法    if (methodName != null) {        // 使用反射方式提升代码的可维护性        try {            // 获取字节码对象            Class aClass = this.getClass();            // 根据传入的方法名获取对应的方法对象            Method method = aClass.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);            method.invoke(this, req, resp);        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {            e.printStackTrace();            System.out.println("请求的功能不存在");        }    }}

最后,编写接口代码,CourseContentServlet:

/** * 保存 & 修改 章节信息 */public void saveOrUpdateSection(HttpServletRequest request, HttpServletResponse response){    try {        // 从 request 域对象中获取获取参数        Map map = (Map) request.getAttribute("map");​        // 创建 Course_Section        Course_Section section = new Course_Section();​        // 使用 BeanUtils 工具类,将 map 中的数据封装到 section        BeanUtils.populate(section, map);​        // 业务处理并响应结果        CourseContentService contentService = new CourseContentServiceImpl();        response.getWriter().print(contentService.saveSection(section));    } catch (IllegalAccessException | InvocationTargetException | IOException e) {        e.printStackTrace();    }}

使用 Postman 测试接口:

  • 选择 POST 请求方式,设置 Content-Type = application/json
  • 选择 raw 发送 JSON 格式数据

功能三:章节信息修改

需求分析

选择章节,点击编辑,传递章节 id;根据章节 id 修改章节信息。

根据接口文档,没有要求编写回显接口,不需要后台根据章节 id 查询对应章节信息进行回显,所以回显操作由前端代码完成。

DAO 层编写

CourseContentDaoImpl

/** * 修改章节信息 */@Overridepublic int updateSection(Course_Section section) {    try {        // 创建 QueryRunner        QueryRunner qr = new QueryRunner(DruidUtils.getDataSource());​        // 编写 SQL        String sql = "UPDATE course_section SET " +                "section_name = ?," +                "description = ?," +                "order_num = ?," +                "update_time = ?" +                "WHERE id = ?";​        // 准备参数        Object[] param = {section.getSection_name(), section.getDescription(),                section.getOrder_num(), section.getUpdate_time(), section.getId()};​        // 执行修改操作        return qr.update(sql, param);    } catch (SQLException throwables) {        throwables.printStackTrace();    }​    return 0;}

Dao 层测试 TestCourseContentDao

/** * 测试 修改章节信息 */@Testpublic void testUpdateSection() {    Course_Section section = new Course_Section();    section.setId(41);    section.setSection_name("微服务架构-Renda");    section.setDescription("微服务架构详解-Renda");    section.setOrder_num(3);    section.setUpdate_time(DateUtils.getDateFormat());​    System.out.println(contentDao.updateSection(section));}

Service 层编写

CourseContentServiceImpl

/** * 修改章节信息 * * @param section */@Overridepublic String updateSection(Course_Section section) {    // 补全章节信息    String date = DateUtils.getDateFormat();    section.setUpdate_time(date);​    // 调用 Dao 进行插入,根据修改是否成功,封装对应信息    if (contentDao.updateSection(section) > 0) {        return StatusCode.SUCCESS.toString();    } else {        return StatusCode.FAIL.toString();    }​}

Servlet 编写

保存章节信息和修改章节信息,访问的是同一个接口,所以在 CourseContentServlet 的 saveOrUpdateSection 方法中进行一下判断:携带 id 就是修改章节操作;未携带 id 就是新增章节操作。

...if (section.getId() != 0) {    // 修改操作    response.getWriter().print(contentService.updateSection(section));} else {    // 保存操作    response.getWriter().print(contentService.saveSection(section));}...

接口测试:根据接口文档,使用 Postman 进行测试。

功能四:章节状态管理

需求分析

根据选择的状态信息,发送对应的状态编号,进行修改 status 状态;0 隐藏,1 待更新,2 已发布。

DAO 层编写

CourseContentDaoImpl

/** * 修改章节的状态 */@Overridepublic int updateSectionStatus(int id, int status) {    try {        // 创建 QueryRunner        QueryRunner qr = new QueryRunner(DruidUtils.getDataSource());​        // 编写 SQL        String sql = "UPDATE course_section SET `status` = ?, update_time = ? WHERE id = ?";​        // 准备参数        Object[] param = {status, DateUtils.getDateFormat(), id};​        // 执行修改操作        return qr.update(sql, param);    } catch (SQLException throwables) {        throwables.printStackTrace();    }​    return 0;}

Dao 层测试 TestCourseContentDao

/** * 测试 修改章节状态 */@Testpublic void testUpdateSectionStatus() {    System.out.println(contentDao.updateSectionStatus(1, 0));}

Service 层编写

CourseContentServiceImpl

/** * 修改章节的状态 */@Overridepublic String updateSectionStatus(int id, int status) {    // 调用 Dao 修改状态,根据修改是否成功,封装对应信息    if (contentDao.updateSectionStatus(id, status) > 0){        return StatusCode.SUCCESS.toString();    } else {        return StatusCode.FAIL.toString();    }}

Servlet 编写

CourseContentServlet

/** * 修改章节状态 */public void updateSectionStatus(HttpServletRequest request , HttpServletResponse response) {    try {        // 获取参数        int id = Integer.parseInt(request.getParameter("id"));        int status = Integer.parseInt(request.getParameter("status"));​        // 业务处理并返回结果数据        CourseContentService contentService = new CourseContentServiceImpl();        response.getWriter().println(contentService.updateSectionStatus(id, status));    } catch (IOException e) {        e.printStackTrace();    }}

接口测试:根据接口文档,使用 Postman 进行测试。

想了解更多,欢迎关注我的微信公众号:Renda_Zhang

转载地址:https://blog.csdn.net/weixin_33073525/article/details/113491427 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:grouping函数 mysql_sql聚合函数有哪些
下一篇:nums在python_程序找到一对(i,j),其中nums [i] + nums [j] +(i -j)在Python中最大化?...

发表评论

最新留言

很好
[***.229.124.182]2024年04月24日 19时18分36秒