05_01_单体项目介绍与后台系统搭建之二(章节内容的增删改查)

任务三 课程管理模块开发_02

1.开发流程

1.1 需求分析

我们接下来开发的是,配置课时(课程内容管理)模块,主要是对课程内容进行管理
在这里插入图片描述

1.2 数据库表分析

在这里插入图片描述

1.3 实体类设计

1.Course 类 与 Course_Section 类 是一对多关系
Course类中定义一个List集合,并指定List的泛型是 Course_Section 类型,表示 一个课程中可以包含多个章节

在Course类中进行添加:

  //添加list计划 泛型为 Course_Section
  List<Course_Section> sectionList = new ArrayList<>();

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

    //添加一个Course类型的属性
    private Course course;

2.Course_Section 类 与Course_Lesson 类是一对多关系
在Course_Section类中定义一个List集合,并指定List的泛型是 Course_Lesson类型,这样就可以表示一个章节中包含多个课时
Course_Section类添加:

//添加一个list集合 泛型是 Course_lesson 
List<Course_Lesson> lessonList = new ArrayList<>();

在Course_Lesson类中添加

//添加一个Course_Section类型的属性 
private Course_Section course_section;

1.4 Dao接口及实现类编写

/**
 * 课程内容管理 DAO层接口 新建CourseContentDao类
 */
public interface CourseContentDao {
}

/**
 * courseContentDao的实现类 新建CourseContentDaoImpl类
 */
public class CourseContentDaoImpl implements CourseContentDao {
}

1.5 Service接口及实现类编写

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

1.6 CourseContentServlet 编写

CourseContentServlet 继承 BaseServlet

/**
*新建的CourseContentServlet类,接收前端传输的值,且继承BaseServlet 
* */
@WebServlet("/courseContent") 
public class CourseContentServlet extends BaseServlet { 
}

2. 功能一: 展示课程内容

2.1 需求分析

分析: 要展示的内容是对应课程下的 章节与课时信息
在这里插入图片描述

  1. 我们先写一条查询语句: 查询ID为1 的课程的章节与课时信息
SELECT
cs.id '章节id',
cs.section_name '章节名称',
cl.id '课时id',
cl.theme '课时描述'
FROM course_section cs INNER JOIN course_lesson cl ON cs.id = cl.section_id WHERE cs.course_id = ?
  1. 我们在程序中尽量避免使用连接查询,我们可以将上面的SQL进行拆分,每一条SQL对应一个功能
--根据课程ID查询章节相关的内容
SELECT 
id, 
course_id, 
section_name,
description,
order_num
FROM course_section cs WHERE course_id = ? ;

--根据章节ID查询课时相关的内容
SELECT 
id, 
course_id, 
section_id, 
theme, 
duration, 
is_free, 
order_nu
FROM course_lesson WHERE section_id = ?;

2.2 DAO层编写

编写两个方法:

接口 在CourseContentDao中: 
//根据课程ID查询课程相关信息
public List<Course_Section> findSectionAndLessonByCourseId(int courseId);

//根据章节ID 查询章节相关的课时信息
public List<Course_Lesson> findLessonBySectionId(int sectionId);

实现类 CourseContentDaoImpl中:
 //根据课程ID查询课程相关信息
    @Override
    public List<Course_Section> findSectionAndLessonByCourseId(int courseId) {
        try {
            //1.创建QueryRunner
            QueryRunner qr = new QueryRunner(DruidUtils.getDataSource());
            //2.编写SQL
            String sql = "SELECT\n" +
                    " id,\n" +
                    " course_id,\n" +
                    " section_name,\n" +
                    " description,\n" +
                    " order_num,\n" +
                    " STATUS\n" +
                    " FROM course_section WHERE course_id=?;";
            //3.执行查询
            List<Course_Section> sectionList = qr.query(sql, new BeanListHandler<Course_Section>(Course_Section.class), courseId);

            //4.根据章节ID查询课时信息
            for (Course_Section section : sectionList) {
                //调用方法 获取章节对应的课时
                List<Course_Lesson> lessonList = findLessonBySectionId(section.getId());
                //将课时数据封装到章节对象中
                section.setLessonList(lessonList);
            }
            return sectionList;
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public List<Course_Lesson> findLessonBySectionId(int sectionId) {
        try {
            //1.创建QueryRunner
            QueryRunner qr = new QueryRunner(DruidUtils.getDataSource());
            String sql = "SELECT \n" +
                    " id,\n" +
                    " course_id,\n" +
                    " section_id,\n" +
                    " theme,\n" +
                    " duration,\n" +
                    " is_free,\n" +
                    " order_num,\n" +
                    " STATUS\n" +
                    "FROM course_lesson WHERE section_id=?";
            List<Course_Lesson> lessonList = qr.query(sql, new BeanListHandler<Course_Lesson>(Course_Lesson.class), sectionId);
            return lessonList;
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        }
    }

DAO层测试

public class TestCourseContentDao {

    CourseContentDao contentDao = new CourseContentDaoImpl();
// 测试查询对应课程下的章节和课时
    @Test
    public void testFindSectionAndLessonByCourseId() {
        List<Course_Section> list = contentDao.findSectionAndLessonByCourseId(59);
        for (Course_Section courseSection : list) {
            System.out.println(courseSection.getId() + " " + courseSection.getSection_name());

            List<Course_Lesson> lessonList = courseSection.getLessonList();
            for (Course_Lesson lesson : lessonList) {
                System.out.println(lesson.getId() + "=" + lesson.getTheme() + "=" + lesson.getSection_id());
            }
        }
    }
    
输出:
32 第一章 Vue.js 介绍
34=第一讲: Vue.js是什么?=32
35=第二讲: Vue.js的使用=32
33 第二章 Vue.js 基础
36=第三讲: Vue入门程序=33
37=第四讲: Vue常用指令=33
34 第三章 Vue.js 起步
38=第五讲: axios异步访问=34
39=第六讲: computed计算属性=34
35 第四章 Vue.js 高级
40=第七讲: Vue生命周期=35
41=第八讲: Vue Router路由=35
40 Vue高级2

2.3 Service层编写

/**
 * 课程内容管理Service层接口 为CourseContentService 
 **/
public interface CourseContentService {
    //根据课程ID查询课程相关信息
    public List<Course_Section> findSectionAndLessonByCourseId(int courseId);
}


/**
 * 课程内容管理Service层的管理 为 CourseContentServiceImpl 
 */
public class CourseContentServiceImpl implements CourseContentService {

    CourseContentDao contentDao = new CourseContentDaoImpl();

    @Override
    public List<Course_Section> findSectionAndLessonByCourseId(int courseId) {
        List<Course_Section> section = contentDao.findSectionAndLessonByCourseId(courseId);
        return section;
    }

}

2.4 Servlet编写
CourseContentServlet中添加 findSectionAndLessonByCourseId 方法

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

    //展示对应课程的章节与课时信息
    public void findSectionAndLessonByCourseId(HttpServletRequest request, HttpServletResponse response) {

        try {
            //1.获取参数
            String course_id = request.getParameter("course_id");

            //2.业务处理
            CourseContentService contentService = new CourseContentServiceImpl();
            List<Course_Section> list = contentService.findSectionAndLessonByCourseId(Integer.parseInt(course_id));

            //3.返回结果
            String result = JSON.toJSONString(list);
            response.getWriter().print(result);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

2.5 接口测试

查看接口文档,进行测试
在这里插入图片描述
Http:http://localhost:8080/lagou_edu_home/courseContent
请求:GET
methodName:findSectionAndLessonByCourseId
course_id:59

3.功能二: 新建章节信息

3.1 需求分析

在这里插入图片描述

3.2 DAO层编写

接口 CourseContentDao中:
//根据课程id回显课程信息
public Course findCourseByCourseId(int courseId);

//保存章节信息
public int saveSection(Course_Section section);
实现类 CourseContentDaoImpl中:
 //根据课程id回显课程信息
    @Override
    public Course findCourseByCourseId(int courseId) {
        try {
            //1.创建QueryRunner
            QueryRunner qr = new QueryRunner(DruidUtils.getDataSource());

            String sql = "SELECT id,course_name FROM course WHERE id = ?";

            Course course = qr.query(sql, new BeanHandler<Course>(Course.class), courseId);

            return course;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }
//保存章节信息
    @Override
    public int saveSection(Course_Section section) {
        try {
            //1.创建QueryRunner
            QueryRunner qr = new QueryRunner(DruidUtils.getDataSource());
            String sql = " INSERT INTO course_section(\n" +
                    "course_id,\n" +
                    "section_name,\n" +
                    "description,\n" +
                    "order_num,\n" +
                    "STATUS,\n" +
                    "create_time,\n" +
                    "update_time) VALUES(?,?,?,?,?,?,?);";
            Object[] param = {section.getCourse_id(), section.getSection_name(), section.getDescription(),
                    section.getOrder_num(), section.getStatus(), section.getCreate_time(), section.getUpdate_time()};

            int row = qr.update(sql, param);
            return row;
        } catch (SQLException e) {
            e.printStackTrace();
            return 0;
        }

测试Dao层:TestCourseContentDao

    //测试根据课程id 回显课程名称
    @Test
    public void testFindCourseByCourseId() {
        Course course = contentDao.findCourseByCourseId(59);
        System.out.println(course.getId() + " " + course.getCourse_name());
    }

    //测试保存章节功能
    @Test
    public void testSaveSection() {
        Course_Section section = new Course_Section();
        section.setCourse_id(59);
        section.setSection_name("Vue高级2");
        section.setDescription("Vue相关的高级技术");
        section.setOrder_num(8);

        String dateFormart = DateUtils.getDateFormart();
        section.setCreate_time(dateFormart);
        section.setUpdate_time(dateFormart);
        section.setStatus(2);
        int i = contentDao.saveSection(section);
        System.out.println(i);
    }

3.3 Service层编写

接口 CourseContentService//根据id查询课程信息
    public Course findCourseByCourseId(int courseId);
    //保存章节信息
    public String saveSection(Course_Section section);
 
实现类 CourseContentServiceImpl@Override
    public Course findCourseByCourseId(int courseId) {
        Course courseByCourseId = contentDao.findCourseByCourseId(courseId);
        return courseByCourseId;
    }

    @Override
    public String saveSection(Course_Section section) {
        //1.补全章节信息
        section.setStatus(2); //状态 0 隐藏 ,1待更新,2 已发布
        String date = DateUtils.getDateFormart();
        section.setCreate_time(date);
        section.setUpdate_time(date);
        //2.调用dao
        int row = contentDao.saveSection(section);
        //3.根据是否插入成功,封装对应信息
        if (row > 0) {
            //保存成功
            String result = StatusCode.SUCCESS.toString();
            return result;
        } else {
            String result = StatusCode.FAIL.toString();
            return result;
        }
    }

3.4 Servlet编写

CourseContentServlet中添加 findCourseById 方法

3.4.1 课程信息回显接口
   //根据课程id 回显课程信息
    public void findCourseById(HttpServletRequest request, HttpServletResponse response) {
        try {
            //1.获取参数
            String course_id = request.getParameter("course_id");
            //2.业务处理
            CourseContentService contentService = new CourseContentServiceImpl();
            Course course = contentService.findCourseByCourseId(Integer.parseInt(course_id));

            //3.返回JSON数据
            SimplePropertyPreFilter filter = new SimplePropertyPreFilter(Course.class, "id", "course_name");
            String result = JSON.toJSONString(course, filter);
            response.getWriter().print(result);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

3.4.2 保存章节信息接口

  1. POST请求方式介绍
    POST 请求方法常用的三种数据提交格式
格式说明
Content-Type : application/x-www-form-urlencoded请求体中的数据会以普通表单形式(键值对)发送到后端。
请求体中的数据会以json字符串的形式发送到后端。
Content-Type : multipart/form-data多部件上传既可以上传键值对 也可以上传文件。

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

  1. 需求分析分析
    根据接口文档描述: 前台传输的是JSON格式的数据, 使用getParameter() 方法无法获取参数
{
 "methodName":"saveOrUpdateSection", 
 "course_id":19, 
 "section_name:"微服务架构", 
 "description":"跟着药水一起学习如何使用微服务", 
 "order_num ":0 
}
  1. 修改BaseServlet
    如果请求参数是JSON格式的数, 我们可以通过 request.getReader() 这个方法,获取一个流对象来进行读取.
    1) 在BaseServlet 中创建一个方法,用来获取JSON格式的数据
  /**
     * POST请求格式为:Content-Type : application/json ; charset=utf-8
     * 使用改方法进行读取
     */

    public String getPostJSON(HttpServletRequest request) {
        try {
            //1.从request中获取缓冲输入流对象
            BufferedReader reader = request.getReader();

            //2.创建StringBuffer 保存读取数据
            StringBuffer sb = new StringBuffer();

            //3.循环读取
            String line = null;
            while ((line = reader.readLine()) != null) {
                //将每次读取的数据追加到StringBuffer
                sb.append(line);
            }

            //4.返回结果
            return sb.toString();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
  1. 修改BaseServlet中的doGet方法
    1.获取POST请求的 Content-Type类型
    2.判断传递的数据是不是JSON格式
    3.如果是 就调用上面编写的 getPostJSON方法,获取数据
    4.将获取到的JSON格式的字符串转换为 Map
    5.从Map中获取要调用的方法名
    6.将Map保存到request域对象中 (流只能使用一次)
 @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.获取参数 要访问的方法名
        //String methodName = req.getParameter("methodName");
        String methodName = null;
        //1.1获取POST请求的Content-type类型
        String contentType = req.getHeader("Content-type");
        //1.2判断传递的数据是不是JSON格式
        if ("application/json;charset=utf-8".equals(contentType)) {
            //是JSON格式那么,调用getPostJSON
            String postJSON = getPostJSON(req);
            //将JSON格式的字符串转换为map
            Map<String, String> map = JSON.parseObject(postJSON, Map.class);
            //从Map集合中获取methodName
            methodName = map.get("methodName");
            //将获取到的数据保存到request域对象中
            req.setAttribute("map", map);
        } else {
            methodName = req.getParameter("methodName");
        }
        //2.判断 执行对应的方法
        if (methodName != null) {
            //通过反射优化代码, 提升代码的可维护性
            try {
                //1.获取字节码文件对象 this = TestServlet
                Class c = this.getClass();
                //2.根据传入的方法名,获取对应的方法对象 findByName
                Method method = c.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
                //3.调用method对象的invoke方法,执行对应的功能
                method.invoke(this, req, resp);
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("请求的功能不存在");
            }

        }

    }
  1. 编写接口代码
   /**
     * b保存&修改 章节信息
     */
    public void saveOrUpdateSection(HttpServletRequest request, HttpServletResponse response) {

        try {
            //1.获取参数 从域对象中获取
            Map<String, Object> map = (Map) request.getAttribute("map");

            //2.创建Course_Section
            Course_Section section = new Course_Section();

            //3.使用BeanUtils工具类,将map封装到section中
            BeanUtils.populate(section, map);

            //4.业务处理
            CourseContentService contentService = new CourseContentServiceImpl();
            String result = contentService.saveSection(section);

            //5.响应结果
            response.getWriter().print(result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

  1. 测试接口
  1. 选择POST请求方式,设置Content-Type = application/json;charset=utf-8
    在这里插入图片描述

  2. 选择raw 发送JSON格式数据

{ 
	"methodName":"saveOrUpdateSection", 
	"course_id":19, 
	"section_name":"微服务架构", 
	"description":"跟着药水一起学习如何使用微服务", 
	"order_num ":0 
	
}

在这里插入图片描述

4.功能三: 章节信息修改

需求分析:
在这里插入图片描述
注意: 接口文档中并没有要求编写回显接口,说明回显操作由前端完成.

4.1 DAO层编写

接口 CourseContentDao:
 //修改章节
public int updateSectionStatus(Course_Section section);

实现类 CourseContentDaoImpl//修改章节
    @Override
    public int updateSectionStatus(Course_Section section) {
        try {
            QueryRunner qr = new QueryRunner(DruidUtils.getDataSource());

            String sql = "UPDATE course_Section SET\n" +
                    "section_name=?,\n" +
                    "description=?,\n" +
                    "order_num=?,\n" +
                    "update_time=? WHERE id=?";

            Object[] param = {section.getSection_name(), section.getDescription(), section.getOrder_num(), section.getUpdate_time(), section.getId()};

            int row = qr.update(sql, param);
            return row;
        } catch (SQLException e) {
            e.printStackTrace();
            return 0;
        }
    }

测试dao层代码:TestCourseContentDao

 //测试修改章节功能
    @Test
    public void testUpdateSection(){
        Course_Section section = new Course_Section();
        section.setId(49);
        section.setSection_name("微服务架构");
        section.setDescription("微服务架构详细描写");
        section.setOrder_num(3);
        section.setUpdate_time(DateUtils.getDateFormart());

        int i = contentDao.updateSectionStatus(section);
        System.out.println(i);
    }

6.3 Service层编写

接口 CourseContentService//修改章节
    public String updateSection(Course_Section section);
实现类 CourseContentServiceImpl@Override
    public String updateSection(Course_Section section) {
        //1.补齐信息
        String date = DateUtils.getDateFormart();
        section.setUpdate_time(date);

        //2.调用DAO
        int row = contentDao.updateSection(section);

        //3.判断是否插入成功
        if (row >0){
            String result = StatusCode.SUCCESS.toString();
            return result;
        }else {
            String result = StatusCode.FAIL.toString();
            return result;
        }
    }

4.3 Servlet编写

保存章节信息和修改章节信息,访问的是同一个接口,所以在saveOrUpdateSection方法中中,我们要进行一下判断

  • 携带id 就是修改章节操作
  • 未携带id就是新增章节操作
 	/**
     * 保存&修改 章节信息
     */
    public void saveOrUpdateSection(HttpServletRequest request, HttpServletResponse response) {

        try {
            //1.获取参数 从域对象中获取
            Map<String, Object> map = (Map) request.getAttribute("map");

            //2.创建Course_Section
            Course_Section section = new Course_Section();

            //3.使用BeanUtils工具类,将map封装到section中
            BeanUtils.populate(section, map);

            //4.业务处理
            CourseContentService contentService = new CourseContentServiceImpl();

            //进行判断ID是否为0,如果是那么代表是新增的操作,如果不是0那么代表不是新增的操作,所以进行修改
            if (section.getId() == 0) {
                //新增操作
                String result = contentService.saveSection(section);
                //5.响应结果
                response.getWriter().print(result);
            } else {
                //修改操作
                String result = contentService.updateSection(section);
                //5.响应结果
                response.getWriter().print(result);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

4.4 接口测试

查看接口文档,进行测试
对比新增,多增加了ID
在这里插入图片描述

5.功能四: 章节状态管理

6.1 需求分析

根据选择的状态信息,发送对应的状态编号 进行修改, status 状态,0:隐藏;1:待更新;2:已发布
在这里插入图片描述
6.2 DAO层编写

接口 CourseContentDao//修改章节状态
    public int updateSectionStatus(int id,int status);
实现类 CourseContentDaoImpl//修改章节状态
    @Override
    public int updateSectionStatus(int id, int status) {
        try {
            QueryRunner qr = new QueryRunner(DruidUtils.getDataSource());

            String sql = "UPDATE course_section SET STATUS=?,update_time=? WHERE id=?";

            Object[] param = {status, DateUtils.getDateFormart(), id};

            int row = qr.update(sql, param);
            return row;
        } catch (SQLException e) {
            e.printStackTrace();
            return 0;
        }
    }

测试DAO层:

 //测试修改章节状态
    @Test
    public void testUpdateSectionStatus(){
        int i = contentDao.updateSectionStatus(1, 2);
        System.out.println(i);
    }

6.3 Service层编写

接口 CourseContentService//修改章节状态
    public String updateSectionStatus(int id,int status);

实现类 CourseContentServiceImpl@Override
    public String updateSectionStatus(int id, int status) {
        int row = contentDao.updateSectionStatus(id, status);
        //判断是否修改成功
        if (row > 0) {
            String result = StatusCode.SUCCESS.toString();
            return result;
        } else {
            String result = StatusCode.FAIL.toString();
            return result;
        }
    }

6.4 Servlet编写

 //修改章节状态
    public void  updateSectionStatus(HttpServletRequest request, HttpServletResponse response){
        try {
            //1.接收参数
            int id = Integer.parseInt(request.getParameter("id"));//章节id
            int status = Integer.parseInt(request.getParameter("status"));//章节状态

            //2.业务处理
            CourseContentService contentService = new CourseContentServiceImpl();
            String result = contentService.updateSectionStatus(id,status);

            //3.返回结果
            response.getWriter().print(result);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

6.5 接口测试

按照接口文档进行测试

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值