文章目录

  • 1、项目架构
    • 1.1、项目介绍
    • 1.2、技术选型
      • 1.2.1、前端技术选型
      • 1.2.2、后端技术选型
    • 1.3、项目开发环境
  • 2、Maven进阶使用(Maven聚合工程)
    • 2.1、maven的依赖传递
      • 2.1.1、什么是依赖传递
      • 2.1.2、如何解决依赖冲突
      • 2.1.3、依赖调节原则——第一声明者优先原则
      • 2.1.4、依赖调节原则——路径近者优先原则
      • 2.1.5、排除依赖
      • 2.1.6、版本锁定
      • 2.1.7、properties标签的使用
    • 2.2、maven聚合工程(分模块)
      • 2.2.1、分模块构建maven工程分析
      • 2.2.2、maven工程的继承
      • 2.2.3、maven工程的聚合
      • 2.2.4、maven聚合工程_搭建拉勾教育后台管理系统
      • 2.2.5、聚合工程创建
      • 2.2.6、父工程进行依赖管理
      • 2.2.7、子工程ssm_dao构建
      • 2.2.8、子工程ssm_serivce构建
      • 2.2.9、子工程ssm_web构建
  • 3、拉勾教育后台管理系统研发
    • 3.1、课程管理模块功能分析
    • 3.2、课程管理模块表设计
    • 3.3、课程管理模块接口实现
      • 3.3.1、多条件课程列表查询
        • 3.3.1.1、实体类创建
        • 3.3.1.2、Dao层编写
        • 3.3.1.3、Servicec层
        • 3.3.1.4、Web层编写
        • 3.3.1.5、postman接口测试
      • 3.3.2、课程图片上传
        • 3.3.2.1、代码编写
        • 3.3.2.2、postman测试
      • 3.3.3、新建课程信息
        • 3.3.3.1、dao层及其xml
        • 3.3.3.2、service层
        • 3.3.3.3、web层
        • 3.3.3.4、postman测试
      • 3.3.4、回显课程信息
        • 3.3.4.1、dao层及其xml
        • 3.3.4.2、service层
        • 3.3.4.3、web层
        • 3.3.4.4、postman测试
      • 3.3.5、修改课程信息
        • 3.3.5.1、dao层
        • 3.3.5.2、service层
        • 3.3.5.3、web层
        • 3.3.5.4、postman测试
      • 3.3.6、课程状态管理
        • 3.3.6.1、dao层
        • 3.3.6.2、service层
        • 3.3.6.3、web层
        • 3.3.6.4、postman测试
      • 3.3.7、课程内容展示
        • 3.3.7.1、实体类
        • 3.3.7.2、dao层
        • 3.3.7.3、service层
        • 3.3.7.4、web层
        • 3.3.7.5、postman测试
      • 3.3.8、回显章节对应的课程信息
        • 3.3.8.1、dao层
        • 3.3.8.2、service层
        • 3.3.8.3、web层
        • 3.3.8.4、postman测试
      • 3.3.9、新建章节信息
        • 3.3.9.1、dao层
        • 3.3.9.2、service层
        • 3.3.9.3、web层
        • 3.3.9.4、postman测试
      • 3.3.10、修改章节状态
        • 3.3.10.1、dao层
        • 3.3.10.2、service层
        • 3.3.10.3、web层
        • 3.3.10.4、postman测试
      • 3.3.11、修改章节信息
        • 3.3.11.1、dao层
        • 3.3.11.2、service层
        • 3.3.11.3、web层
        • 3.3.11.4、postman测试
      • 3.3.12、新建课时信息以及修改课时信息
        • 3.3.12.1、dao层
        • 3.3.12.2、service层
        • 3.3.12.3、web层
        • 3.3.12.4、postman测试

1、项目架构

1.1、项目介绍

拉勾教育后台管理系统,是提供给拉勾教育的相关业务人员使用的一个后台管理系统, 业务人员可以在这个后台管理系统中,对课程信息、广告信息、用户信息、 权限信息等数据进行维护
      在 web阶段,我们已经完成了拉勾教育后台管理系统中课程模块, 接下来将对拉勾教育后台管理系统进行升级改造,基于SSM框架来完成课程信息模块,广告信息模块,用户信息模块,权限信息模块

1.2、技术选型

1.2.1、前端技术选型

前端技术 说明
Vue.js 是一套用于构建用户界面的渐进式JavaScript框架
Element UI库 element-ui 是饿了么前端出品的基于 Vue.js的 后台组件库,方便程序员进行页面快速布局和构建
node.js 简单的说 Node.js 就是运行在服务端的 JavaScript 运行环境
axios 对ajax的封装, 简单来说就是ajax技术实现了局部数据的刷新,axios实现了对ajax的封装,

1.2.2、后端技术选型

后端技术 说明
Web层 借助springmvc接收请求,进行视图跳转
Service层 借助spring进行IOC、AOP、及事务管理
dao层 借助mybatis进行数据库交互

1.3、项目开发环境

  • 开发工具

    • 后端: IDEA 2022.3
    • 前端: VS code
    • 数据库客户端工具: Navicat Premium
  • 开发环境
    • JDK 11
    • Maven 3.8.6
    • MySQL 5.7

2、Maven进阶使用(Maven聚合工程)

2.1、maven的依赖传递

2.1.1、什么是依赖传递

在maven中,依赖是可以传递的,假设存在三个项目,分别是项目A,项目B以及项目C。假设C依赖B,B依赖A,那么我们可以根据maven项目依赖的特征不难推出项目C也依赖A。



      通过上面的图可以看到,我们的web项目直接依赖了spring-webmvc,而spring-webmvc依赖了sping-aop、spring-beans等。最终的结果就是在我们的web项目中间接依赖了spring-aop、spring-beans等。

  • 依赖冲突

由于依赖传递现象的存在, spring-webmvc 依赖 spirng-beans-5.1.5,spring-aop 依赖 spring-beans-5.1.6,但是发现 spirng-beans-5.1.5 加入到了工程中,而我们希望 spring-beans-5.1.6 加入工程。这就造成了依赖冲突

2.1.2、如何解决依赖冲突

  • 使用maven提供的依赖调解原则

    • 第一声明者优先原则
    • 路径近者优先原则
  • 排除依赖
  • 锁定版本

2.1.3、依赖调节原则——第一声明者优先原则

在 pom 文件中定义依赖,以先声明的依赖为准。其实就是根据坐标导入的顺序来确定最终使用哪个传递过来的依赖

最终:这里使用的依赖是spring-beans:5.1.6,为什么不用spring-webmvc中的5.1.5呢,原因就在于spring-beans位置在前spring-webmvc在后,所以5.1.6版本优先

2.1.4、依赖调节原则——路径近者优先原则


最终:使用的依赖是spring-beans是5.1.6版本的,因为这个是直接依赖的,spring-webmvc中的spring-beans是间接依赖的

2.1.5、排除依赖

可以使用exclusions标签将传递过来的依赖排除出去

2.1.6、版本锁定

采用直接锁定版本的方法确定依赖jar包的版本,版本锁定后则不考虑依赖的声明顺序或依赖的路径,以锁定的版本为准添加到工程中,此方法在企业开发中经常使用。

版本锁定的使用方式:
第一步:在dependencyManagement标签中锁定依赖的版本
第二步:在dependencies标签中声明需要导入的maven坐标

  1. 在dependencyManagement标签中锁定依赖的版本
  2. 在dependencies标签中声明需要导入的maven坐标

也就是你不用在搞版本了,你导入的依赖都是安装dependencyManagement设置的版本处理的

2.1.7、properties标签的使用

<properties><maven.compiler.source>11</maven.compiler.source><maven.compiler.target>11</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><spring.version>5.1.5.RELEASE</spring.version><springmvc.version>5.1.5.RELEASE</springmvc.version><mybatis.version>3.5.1</mybatis.version>
</properties>
<!--锁定jar版本-->
<dependencyManagement><dependencies><!-- Mybatis --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>${mybatis.version}</version></dependency><!-- springMVC --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${springmvc.version}</version></dependency><!-- spring --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-expression</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>${spring.version}</version></dependency></dependencies>
</dependencyManagement>

通过设置不同的框架的版本号,做到改一处就可以修改整个依赖的版本号,上面的代码只是约束了版本号,但是没有真正的导入依赖,导入依赖还得denpendecys那种方式去导入,不用加version了

2.2、maven聚合工程(分模块)

在现实生活中,汽车厂家进行汽车生产时,由于整个生产过程非常复杂和繁琐,工作量非常大,所以厂家都会将整个汽车的部件分开生产,最终再将生产好的部件进行组装,形成一台完整的车。

2.2.1、分模块构建maven工程分析

在企业项目开发中,由于项目规模大,业务复杂,参与的人员比较多,一般会通过合理的模块拆分将一个大型的项目拆分为N多个小模块,分别进行开发。而且拆分出的模块可以非常容易的被其他模块复用

常见的拆分方式有两种:
      第一种:按照业务模块进行拆分,每个模块拆分成一个maven工程,例如将一个项目分为用户模块,订单模块,购物车模块等,每个模块对应就是一个maven工程
      第二种:按照层进行拆分,例如持久层、业务层、表现层等,每个层对应就是一个maven工程

不管上面那种拆分方式,通常都会提供一个父工程,将一些公共的代码和配置提取到父工程中进行统一管理和配置。

2.2.2、maven工程的继承

在Java语言中,类之间是可以继承的,通过继承,子类就可以引用父类中非private的属性和方法。同样,在maven工程之间也可以继承,子工程继承父工程后,就可以使用在父工程中引入的依赖。继承的目的是为了消除重复代码。

2.2.3、maven工程的聚合

在maven工程的pom.xml文件中可以使用标签将其他maven工程聚合到一起,聚合的目的是为了进行统一操作
      例如拆分后的maven工程有多个,如果要进行打包,就需要针对每个工程分别执行打包命令,操作起来非常繁琐。这时就可以使用标签将这些工程统一聚合到maven父工中,需要打包的时候,只需要在此工程中执行一次打包命令,其下被聚合的工程就都会被打包了。

2.2.4、maven聚合工程_搭建拉勾教育后台管理系统

工程整体结构如下:

  1. lagou_edu_home_parent为父工程,其余工程为子工程,都继承父工程lagou_edu_home_parent
  2. lagou_edu_home_parent工程将其子工程都进行了聚合
  3. 子工程之间存在依赖关系:
    • ssm_domain依赖ssm_utils
    • ssm_dao依赖ssm_domain
    • ssm_service依赖ssm_dao
    • ssm_web依赖ssm_service


依赖关系建立原则:当前项目中要用到那个项目的资源,那么当前项目就依赖要用到资源的项目(直接依赖和间接依赖)

2.2.5、聚合工程创建

  1. 先创建一个maven工程lagou_edu_home_parent
  2. 然后删除掉src目录
  3. 然后创建子工程
    • 创建ssm_utils
    • 创建ssm_domain
    • 创建ssm_dao
    • 创建ssm_service
    • 创建ssm_web
      • 这里还要配置一下ssm_web中的pom中的打包方式为war,并且创建webapp和对应的webx.ml文件
  4. 然后开始配置子工程之间的依赖关系
    • ssm_domain的pom.xml中配置(ctrl+鼠标左键跳转过去就可以了)
    <dependencies><dependency><groupId>com.lzy</groupId><artifactId>ssm_utils</artifactId><version>1.0-SNAPSHOT</version></dependency>
    </dependencies>
    
    • ssm_dao的pom.xml配置
    <dependencies><dependency><groupId>com.lzy</groupId><artifactId>ssm_domain</artifactId><version>1.0-SNAPSHOT</version></dependency>
    </dependencies>
    
    • ssm_service的pom.xml配置
    <dependencies><dependency><groupId>com.lzy</groupId><artifactId>ssm_dao</artifactId><version>1.0-SNAPSHOT</version></dependency>
    </dependencies>
    
    • ssm_web的pom.xml配置
    <dependencies><dependency><groupId>com.lzy</groupId><artifactId>ssm_service</artifactId><version>1.0-SNAPSHOT</version></dependency>
    </dependencies>
    
  5. 最后输入maven install
  6. 最终的项目结构

2.2.6、父工程进行依赖管理

<properties><maven.compiler.source>11</maven.compiler.source><maven.compiler.target>11</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><spring.version>5.1.5.RELEASE</spring.version><springmvc.version>5.1.5.RELEASE</springmvc.version><mybatis.version>3.5.1</mybatis.version>
</properties><!--版本锁定-->
<dependencyManagement><dependencies><!--Mybatis--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>${mybatis.version}</version></dependency><!--SpringMVC--><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${springmvc.version}</version></dependency><!--spring--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-expression</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>${spring.version}</version></dependency></dependencies>
</dependencyManagement><dependencies><!--mybatis坐标--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.31</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.15</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency><!--spring坐标--><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.13</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId></dependency><!--mybatis整合spring坐标--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>1.3.1</version></dependency><!--springMVC坐标--><!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId></dependency><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency><dependency><groupId>javax.servlet.jsp</groupId><artifactId>jsp-api</artifactId><version>2.2</version><scope>provided</scope></dependency><dependency><groupId>jstl</groupId><artifactId>jstl</artifactId><version>1.2</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.8</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.9.8</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>2.9.0</version></dependency><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>4.1.6</version></dependency><!--Beanutils--><dependency><groupId>commons-beanutils</groupId><artifactId>commons-beanutils</artifactId><version>1.8.3</version></dependency><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.1</version></dependency><!--解决跨域问题所需依赖--><dependency><groupId>com.thetransactioncompany</groupId><artifactId>cors-filter</artifactId><version>2.5</version></dependency>
</dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.1</version><configuration><source>1.8</source><target>1.8</target><encoding>UTF-8</encoding></configuration></plugin></plugins>
</build>

2.2.7、子工程ssm_dao构建

首先要创建一个实体类在ssm_domain中

@AllArgsConstructor
@NoArgsConstructor
@Data
public class Account {private Integer id;private String name;private Double money;
}
  • 然后创建一个mapper接口和对应的mapper.xml文件
public interface AccountMapper {public List<Account> findAllTest();
}
<?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.lzy.dao.AccountMapper"><select id="findAllTest" resultType="account">select * from account</select>
</mapper>
  • 创建applicationContext-dao.xml和jdbc.properties
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!--spring整合mybaits--><context:property-placeholder location="classpath:jdbc.properties"/><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean><!--sqlSessionFactory--><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><!--配置数据源--><property name="dataSource" ref="dataSource"/><!--domain别名--><property name="typeAliasesPackage" value="com.lzy.domain"/><!--开启自动驼峰命名规则--><property name="configuration"><bean class="org.apache.ibatis.session.Configuration"><property name="mapUnderscoreToCamelCase" value="true"/></bean></property></bean><!--mapper映射扫描--><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.lzy.dao"/></bean>
</beans>
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db
jdbc.username=root
jdbc.password=xxxx

2.2.8、子工程ssm_serivce构建

  • 创建AccountServiceImpl和接口
public interface AccountService {public List<Account> findAllTest();
}
@Service
public class AccountServiceImpl implements AccountService {@Autowiredprivate AccountMapper accountMapper;@Overridepublic List<Account> findAllTest() {return accountMapper.findAllTest();}
}
  • 创建applicationContext-service.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!--配置IOC相关操作:开启注解扫描--><context:component-scan base-package="com.lzy.service"/><!--引入dao层中的spring配置文件--><import resource="classpath:applicationContext-dao.xml"/>
</beans>

2.2.9、子工程ssm_web构建

  • AccountController
@RestController
@RequestMapping("/test")
public class AccountController {@Autowiredprivate AccountService accountService;@RequestMapping("/findAllTest")public List<Account> findAllTest(){return accountService.findAllTest();}
}
  • applicationContext-web.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!--引入application_service.xml--><import resource="classpath:applicationContext-service.xml"/>
</beans>
  • spring-mvc.xml核心配置文件
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!--组件扫描--><context:component-scan base-package="com.lzy.controller"/><!--mvc注解增强--><mvc:annotation-driven/><!--视图解析器--><!--静态资源--><mvc:default-servlet-handler/>
</beans>
  • 前端控制器、中文乱码、spring监听器、跨域
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><!--配置前端控制器--><servlet><servlet-name>DispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring-mvc.xml</param-value></init-param><load-on-startup>2</load-on-startup></servlet><servlet-mapping><servlet-name>DispatcherServlet</servlet-name><url-pattern>/</url-pattern></servlet-mapping><!--中文乱码--><filter><filter-name>CharacterEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param></filter><filter-mapping><filter-name>CharacterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><!--配置spring监听器--><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext-web.xml</param-value></context-param><!--配置跨域过滤器--><filter><filter-name>CORSFilter</filter-name><filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class></filter><filter-mapping><filter-name>CORSFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>
</web-app>

最后配置tomcat然后访问/test/findAllTest,说明环境没什么大问题了

3、拉勾教育后台管理系统研发

3.1、课程管理模块功能分析

在本次的项目中,首先先来完成拉勾教育后台管理系统的 课程管理模块, 课程管理模块包含了多条件查询、 图片上传、 新建&修改课程、课程状态管理、课程内容展示、回显章节对应的课程信息、新建&修改章节信息、修改章节状态、 新建&修改课时信息等接口的编写

  • 实现以下功能:

    • 多条件查询
    • 图片上传
    • 新建课程信息
    • 回显课程信息
    • 修改课程信息
    • 课程状态管理
    • 课程内容展示
    • 回显章节对应的课程信息
    • 新建&修改章节信息
    • 修改章节状态
    • 新建课时信息

3.2、课程管理模块表设计

创建数据库及表


课程表

章节表

课时表

课程媒体

3.3、课程管理模块接口实现

3.3.1、多条件课程列表查询

接口地址: http://localhost:8080/ssm-web/course/findCourseByCondition

请求方式: POST

接口描述: 分页获取课程列表数据&多条件查询

请求参数:

参数名称 参数说明 in 是否必须 数据类型 schema
courseName false string
status false integer(int32)

请求示例:

{"courseName": "Vue.js 3.0 核心源码解析","status": 1
}

响应参数:

参数名称 参数说明 类型 schema
success boolean
state integer(int32) integer(int32)
message string
content object

响应示例:

{"success": true,"state": 0,"message": "响应成功","content": {课程数据}
}

3.3.1.1、实体类创建

Course

@AllArgsConstructor
@NoArgsConstructor
@Data
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;
}

ResponseResult

@AllArgsConstructor
@NoArgsConstructor
@Data
public class ResponseResult {private Boolean success;private Integer state;private String message;private Object content;
}

CourseVo:View Object表现层对象:主要用于表现层来接收参数的

@AllArgsConstructor
@NoArgsConstructor
@Data
public class CourseVo {private String courseName;private Integer status;
}

3.3.1.2、Dao层编写

public interface CourseMapper {public List<Course> findCourseByConditionin(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.lzy.dao.CourseMapper"><!--这里涉及到了逻辑删除,is_del != 1 --><select id="findCourseByConditionin" parameterType="coursevo" resultType="course">select id, course_name, price, sort_num, status from course<where><if test="courseName != null and courseName != ''">and course_name like concat('%', #{courseName}, '%')</if><if test="status != null and status != ''">and status = #{status}</if><if test="true">and is_del != 1</if></where></select>
</mapper>

3.3.1.3、Servicec层

public interface CourseService {/*多条件列表查询*/public List<Course> findCourseByConditioin(CourseVo courseVo);
}
@Service
public class CourseServiceImpl implements CourseService {@Autowiredprivate CourseMapper courseMapper;@Overridepublic List<Course> findCourseByConditioin(CourseVo courseVo) {return courseMapper.findCourseByConditionin(courseVo);}
}

3.3.1.4、Web层编写

@RestController
@RequestMapping("/course")
public class CourseController {@Autowiredprivate CourseService courseService;@RequestMapping("/findCourseByCondition")/*这里不加这个@RequestBody注解的话,就无法把前台传过来的数据进行封装*/public ResponseResult findCourseByCondition(@RequestBody CourseVo courseVo){System.out.println(courseVo);List<Course> courseByConditioin = courseService.findCourseByConditioin(courseVo);ResponseResult responseResult = new ResponseResult(true, 200, "成功", courseByConditioin);return responseResult;}
}

3.3.1.5、postman接口测试

3.3.2、课程图片上传

接口地址: http://localhost:8080/ssm-web/course/courseUpload

请求方式: POST

接口描述: 课程模块图片上传

请求参数:

file=1597112871741.JPG

响应参数:

参数名称 参数说明 类型 schema
success boolean
state integer(int32) integer(int32)
message string
content object

响应示例:

{"success": true,"state": 200,"message": "响应成功","content": {"fileName": "1597112871741.JPG","filePath": "http://localhost:8080/upload/1597112871741.JPG"}
}

3.3.2.1、代码编写

spring-mvc.xml

<!--配置文件解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><property name="maxUploadSize" value="1048576"/>
</bean>

web层

package com.lzy.service.impl;import com.github.pagehelper.PageInfo;
import com.lzy.dao.CourseMapper;
import com.lzy.domain.Account;
import com.lzy.domain.Course;
import com.lzy.domain.CourseVo;
import com.lzy.domain.ResponseResult;
import com.lzy.service.CourseService;
import com.sun.org.apache.bcel.internal.generic.NEW;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;@Service
public class CourseServiceImpl implements CourseService {@Autowiredprivate CourseMapper courseMapper;@Overridepublic List<Course> findCourseByConditioin(CourseVo courseVo) {return courseMapper.findCourseByConditionin(courseVo);}@RequestMapping("/courseUpload")public ResponseResult fileUpload(MultipartFile file, HttpServletRequest request){try {/*判断文件是否为空*/if(file.isEmpty()){throw new RuntimeException();}/*获取项目部署路径*/// 这里是获得了到webapps/ssm/的路径String realPath = request.getServletContext().getRealPath("/");// 这里是获得了到webapps的路径String webappsPath = realPath.substring(0, realPath.indexOf("ssm"));/*获取原文件名*/String fileName = file.getOriginalFilename();/*新的文件名*/String newFileName = System.currentTimeMillis() + fileName.substring(fileName.lastIndexOf("."));/*存储文件*/String uploadPath = webappsPath + "upload\\";File filePath = new File(uploadPath, newFileName);/*如果目录不存在就创建目录*/if(!filePath.getParentFile().exists()){filePath.getParentFile().mkdirs();System.out.println("创建目录 = " + filePath);}file.transferTo(filePath);/*将文件名和文件路径返回*/Map<String, String> map = new HashMap<>();map.put("fileName", newFileName);map.put("filePath", "htt://localhost:8080/upload/" + newFileName);ResponseResult res = new ResponseResult(true, 200, "成功", map);return res;} catch (IOException e) {e.printStackTrace();return null;}}
}

3.3.2.2、postman测试

3.3.3、新建课程信息

接口地址: http://localhost:8080/ssm-web/course/saveOrUpdateCourse

请求方式: POST

接口描述: 新建课程或修改课程

请求参数:

字段 说明 类型 是否必需 备注
id 课程id int 添加操作不用携带, 修改操作必须携带ID
courseName 课程名称 String
brief 课程简介 String 一句话介绍课程
teacherName 讲师名称 String
description 讲师介绍 String
position 讲师职位 String
previewFirstField 课程概述1 String 第一段描述 例如: 课程共15讲
previewSecondField 课程概述2 String 第二段描述 例如: 每周五更新
discounts 售卖价格 double 课程的售卖价格
price 商品原价 double 课程的原销售价
discountsTag 活动标签 String 例如: 立即抢购
courseImgUrl 课程图片url String
courseListImg 封面图url String
sortNum 课程排序 int
course_description_mark_down 课程描述 String
sales 销量 int

请求示例

//新增
{"courseName":"大数据云计算","brief":"海量大数据课程","teacherName":"维尼","description":"多年企业实战经验","position":"高级讲师","previewFirstField":"共10讲","previewSecondField":"每周四更新","discounts":66.6,"price":88,"discountsTag":"先到先得","courseImgUrl":"http://localhost:8080/upload/1596520226925.jpg","courseListImg":"http://localhost:8080/upload/1596520226925.jpg","sortNum":1,"courseDescriptionMarkDown":"介绍当前流行大数据技术,数据技术原理,并介绍其思想,介绍大数据技术培训课程,概要介绍。","sales":100
}//修改
{"id":15,"courseName":"全栈工程师","brief":"掌握多种技能,胜任前端与后端","teacherName":"药水哥","description":"多年企业实战经验","position":"高级讲师","previewFirstField":"共10讲","previewSecondField":"每周四更新","discounts":66.6,"price":88,"discountsTag":"先到先得","courseImgUrl":"http://localhost:8080/upload/1596520226925.jpg","courseListImg":"http://localhost:8080/upload/1596520226925.jpg","sortNum":1,"courseDescriptionMarkDown":"介绍当前流行大数据技术,数据技术原理,并介绍其思想,介绍大数据技术培训课程,概要介绍。","sales":100
}

响应参数:

参数名称 参数说明 类型 schema
success boolean
state integer(int32) integer(int32)
message string
content object

响应示例

{"success": true,"state": 200,"message": "响应成功","content": null
}

需求分析
      既要保存课程信息,又要保存教师的信息,并且教师的信息中存储着这门课的id值,所以这里要先保存课程信息,然后将自动生成的id作为course_id存储到教师信息中

3.3.3.1、dao层及其xml

 /*新增课程信息*/
public void saveCourse(Course course);/*新增教师信息*/
public void saveTeacher(Teacher teacher);
<!--新增课程信息-->
<insert id="saveCourse" parameterType="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});<selectKey resultType="int" order="AFTER" keyProperty="id">select LAST_INSERT_ID()</selectKey>
</insert><!--新增讲师信息-->
<insert id="saveTeacher" parameterType="teacher">INSERT INTO teacher(course_id,teacher_name,POSITION,description,create_time,update_time) VALUES(#{courseId},#{teacherName},#{position},#{description},#{createTime},#{updateTime});
</insert>

新知识点:selectKey

3.3.3.2、service层

@Override
public void saveCourseOrTeacher(CourseVo courseVo) {try {// 封装课程信息Course course = new Course();ConvertUtils.register( new DateConverter(null), java.util.Date.class);BeanUtils.copyProperties(course, courseVo);System.out.println(course);// 补全信息Date date = new Date();course.setCreateTime(date);course.setUpdateTime(date);// 保存课程信息courseMapper.saveCourse(course);// 通过那个selectKey就可以获取新插入数据的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();}
}

3.3.3.3、web层

// 保存更新课程信息
@RequestMapping("/saveOrUpdateCourse")
public ResponseResult saveOrUpdateCourse(@RequestBody CourseVo courseVo){courseService.saveCourseOrTeacher(courseVo);ResponseResult res = new ResponseResult(true, 200, "成功", null);return res;
}

3.3.3.4、postman测试

3.3.4、回显课程信息

  • 名称: findCourseById
  • 描述: 根据id查询课程信息
  • URL: http://localhost:8080/ssm-web/course/findCourseById
  • 请求方式: GET
  • 请求实例:http://localhost:8080/ssm-web/course/findCourseById?id=16
  • 请求参数
字段 说明 类型 是否必需 备注
id 课程id int
  • 响应结果示例
{"success": true,"state": 200,"message": "响应成功","content": 课程信息
}

3.3.4.1、dao层及其xml

/*回显课程信息*/
public CourseVo findCourseById(Integer id);
<select id="findCourseById" resultType="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>

3.3.4.2、service层

/*信息回显*/
public CourseVo findCourseById(Integer id);
@Override
public CourseVo findCourseById(Integer id) {return courseMapper.findCourseById(id);
}

3.3.4.3、web层

// 回显信息
@RequestMapping("/findCourseById")
public ResponseResult findCourseById(@RequestParam Integer id){CourseVo courseVo = courseService.findCourseById(id);ResponseResult res = new ResponseResult(true, 200, "成功", courseVo);return res;
}

3.3.4.4、postman测试

3.3.5、修改课程信息

3.3.5.1、dao层

/*修改课程信息*/
public void updateCourse(Course course);/*修改讲师信息*/
public void updateTeacher(Teacher teacher);
<update id="updateCourse" parameterType="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 and courseDescriptionMarkDown != ''">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="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>

3.3.5.2、service层

/*修改课程信息*/
public void updateCourseOrTeacher(CourseVo courseVo);
@Override
public void updateCourseOrTeacher(CourseVo courseVo) {try {// 封装课程数据Course course = new Course();ConvertUtils.register(new DateConverter(null), java.util.Date.class);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();}
}

3.3.5.3、web层

// 保存或更新课程信息
@RequestMapping("/saveOrUpdateCourse")
public ResponseResult saveOrUpdateCourse(@RequestBody CourseVo courseVo){if (courseVo.getId() == null) {courseService.saveCourseOrTeacher(courseVo);ResponseResult res = new ResponseResult(true, 200, "成功", null);return res;}else{courseService.updateCourseOrTeacher(courseVo);ResponseResult res = new ResponseResult(true, 200, "成功", null);return res;}
}

3.3.5.4、postman测试

3.3.6、课程状态管理

接口地址: http://localhost:8080/ssm-web/course/updateCourseStatus

请求方式: GET

接口描述: 修改课程状态

请求参数:

参数名称 参数说明 in 是否必须 数据类型 备注
id 课程id true int
status 课程状态 true int 最新的状态值

请求示例:

http://localhost:8080/ssm-web/course/updateCourseStatus?status=1&id=15

响应参数:

参数名称 参数说明 类型 schema
success boolean
state integer(int32) integer(int32)
message string
content object

响应示例:

{"success": true,"state": 200,"message": "响应成功","content": {"status": 1}
}

3.3.6.1、dao层

/*课程状态管理*/
public void updateCourseStatus(Course course);
<update id="updateCourseStatus" parameterType="course">update course set status = #{status}, update_time=#{updateTime} where id = #{id}
</update>

3.3.6.2、service层

/*修改课程状态*/
public void updateCourseStatus(Integer id, Integer status);
/*修改课程信息*/
@Override
public void updateCourseStatus(Integer id, Integer status) {// 封装课程信息Course course = new Course();course.setStatus(status);course.setId(id);course.setUpdateTime(new Date());// 修改课程状态courseMapper.updateCourseStatus(course);
}

3.3.6.3、web层

// 修改课程状态
@RequestMapping("/updateCourseStatus")
public ResponseResult updateCourseStatus(@RequestParam Integer id, @RequestParam Integer status){courseService.updateCourseStatus(id, status);HashMap<Object, Object> map = new HashMap<>();map.put("status", status);ResponseResult res = new ResponseResult(true, 200, "成功", map);return res;
}

3.3.6.4、postman测试

3.3.7、课程内容展示

接口地址: http://localhost:8080/ssm-web/courseContent/findSectionAndLesson

请求方式: GET

接口描述: 根据课程ID查询章节与课时信息

请求参数:

参数名称 参数说明 in 是否必须 数据类型 schema
courseId 课程id true int
  • 请求示例
http://localhost:8080/ssm-web/courseContent/findSectionAndLesson?courseId=7
  • 响应结果示例
{"success": true,"state": 200,"message": "响应成功","content": [{"id": 7,"courseId": 7,"sectionName": "开篇词 | 从小白到文案高手,手把手教你写出爆款文案","description": "你好,我是兔妈!第一次见面,我用几句话简单介绍下自己","createTime": null,"updateTime": null,"isDe": 0,"orderNum": 1,"status": 2,"lessonList": [{"id": 9,"courseId": 7,"sectionId": 7,"theme": "手把手教你写出爆款文案","duration": 0,"isFree": 0,"createTime": null,"updateTime": null,"isDel": 0,"orderNum": 1,"status": 2},{"id": 8,"courseId": 7,"sectionId": 7,"theme": "从小白到文案高手","duration": 0,"isFree": 1,"createTime": null,"updateTime": null,"isDel": 0,"orderNum": 1,"status": 2}]},{"id": 8,"courseId": 7,"sectionName": "重点内容总结","description": "重点内容总结","createTime": null,"updateTime": null,"isDe": 0,"orderNum": 2,"status": 2,"lessonList": [{"id": 11,"courseId": 7,"sectionId": 8,"theme": "内容总结","duration": 0,"isFree": 0,"createTime": null,"updateTime": null,"isDel": 0,"orderNum": 2,"status": 2},{"id": 10,"courseId": 7,"sectionId": 8,"theme": "重点内容","duration": 0,"isFree": 0,"createTime": null,"updateTime": null,"isDel": 0,"orderNum": 2,"status": 2}]}]
}

3.3.7.1、实体类

package com.lzy.domain;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.util.Date;
import java.util.List;@AllArgsConstructor
@NoArgsConstructor
@Data
public class CourseSection {//idprivate Integer id;//课程idprivate int courseId;//章节名private String sectionName;//章节描述private String description;//创建时间private Date createTime;//更新时间private Date updateTime;//是否删除private int isDe;//排序private int orderNum;//状态private int status;// 课时集合private List<CourseLesson> lessonList;
}
package com.lzy.domain;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.util.Date;@AllArgsConstructor
@NoArgsConstructor
@Data
public class CourseLesson {private Integer id;private Integer courseId;private Integer sectionId;private String theme;private Integer duration;private Integer isFree;private Date createTime;private Date updateTime;private Integer isDel;private Integer orderNum;private Integer status;
}

3.3.7.2、dao层

public interface CourseContentMapper {/*查询课程下的章节与课时信息*/public List<CourseSection> findSectionAndLessonByCourseId(Integer courseId);
}
<?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.lzy.dao.CourseContentMapper"><!--根据课程id查询课程内容--><select id="findSectionAndLessonByCourseId" resultMap="BaseResultMap">selectcs.*,cl.id lessonid,cl.course_id,cl.section_id,cl.theme,cl.duration,cl.create_time,cl.update_time,cl.is_del,cl.order_num,cl.status,cl.is_freefrom course_section csleft join course_lesson clon cl.section_id = cs.idwhere cs.course_id = #{courseId}order by cs.order_num</select><!--一对多配置,一个章节下有多个课时--><resultMap id="BaseResultMap" type="CourseSection"><id property="id" column="id"/><result property="courseId" column="course_id"/><result property="sectionName" column="section_name"/><result property="description" column="description"/><result property="orderNum" column="order_num"/><result property="status" column="status"/><!--使用collection,配置一对多的关系--><collection property="lessonList" resultMap="lessonListResultMap"/></resultMap><resultMap id="lessonListResultMap" type="CourseLesson"><id property="id" column="lessonid"/><result property="courseId" column="course_id"/><result property="sectionId" column="section_id"/><result property="theme" column="theme"/><result property="duration" column="duration"/><result property="isFree" column="is_free"/><result property="orderNum" column="order_num"/><result property="status" column="status"/><result property="isDel" column="is_del"/></resultMap>
</mapper>

3.3.7.3、service层

public interface CourseContentService {/*展示课程内容*/public List<CourseSection> findSectionAndLessonByCourseId(Integer courseId);
}
import java.util.List;
@Service
@Transactional
public class CourseContentServiceImpl implements CourseContentService {@Autowiredprivate CourseContentMapper courseContentMapper;@Overridepublic List<CourseSection> findSectionAndLessonByCourseId(Integer courseId) {return courseContentMapper.findSectionAndLessonByCourseId(courseId);}
}

3.3.7.4、web层

@RestController
@RequestMapping("/courseContent")
public class CourseContentController {@Autowiredprivate CourseContentService courseContentService;/*查询课程内容*/@RequestMapping("/findSectionAndLesson")public ResponseResult findSectionAndLessonByCourseId(@RequestParam Integer courseId){// 调用serviceList<CourseSection> sectionList = courseContentService.findSectionAndLessonByCourseId(courseId);// 封装返回数据ResponseResult res = new ResponseResult(true, 200, "成功", sectionList);return res;}
}

3.3.7.5、postman测试

3.3.8、回显章节对应的课程信息

  • 名称: findCourseById
  • 描述: 回显章节对应的课程信息
  • URL: http://localhost:8080/ssm-web/courseContent/findCourseByCourseId
  • 请求方式: GET
  • 请求参数
参数名称 参数说明 in 是否必须 数据类型 schema
courseId 课程id true int
  • 请求示例
http://localhost:8080/ssm-web/courseContent/findCourseByCourseId?courseId=15
  • 响应结果示例
{"success": true,"state": 200,"message": "响应成功","content": {"id": 19,"courseName": "全栈工程师",}
}

3.3.8.1、dao层

/*回显章节对应的课程信息*/
public Course findCourseByCourseId(Integer courseId);
<select id="findCourseByCourseId" resultType="course">select id, course_name from course where id = #{courseId}
</select>

3.3.8.2、service层

/*回显信息*/
@Overridepublic Course findCourseByCourseId(Integer courseId) {return courseContentMapper.findCourseByCourseId(courseId);}
/*回显信息*/
public Course findCourseByCourseId(Integer courseId);

3.3.8.3、web层

@RequestMapping("/findCourseByCourseId")
public ResponseResult findCourseByCourseId(@RequestParam Integer courseId){Course course = courseContentService.findCourseByCourseId(courseId);ResponseResult res = new ResponseResult(true, 200, "查询课程信息成功", course);return res;
}

3.3.8.4、postman测试

3.3.9、新建章节信息

  • 名称: saveOrUpdateSection
  • 描述: 保存和修改章节信息
  • URL: http://localhost:8080/ssm-web/courseContent/saveOrUpdateSection
  • 请求方式: POST
  • 请求参数
字段 说明 类型 是否必需 备注
id 章节ID int 添加操作不携带id, 修改操作必须携带ID
course_id 课程ID int
section_name 章节名称 String
description 章节描述 String
order_num 章节排序 int
  • 请求参数示例
//新增
{"courseId":8,"sectionName":"Vue脚手架","description":"快速搭建Vue项目","orderNum":2
}//修改
{"id":13,"sectionName":"Vue路由","description":"单页面应用导航","orderNum":0
}
  • 响应结果示例
{"success": true,"state": 200,"message": "响应成功","content": null
}

3.3.9.1、dao层

/*保存章节*/
public void saveSection(CourseSection section);

3.3.9.2、service层

@Override
public void saveSection(CourseSection section) {/*补全信息*/Date date = new Date();section.setCreateTime(date);section.setUpdateTime(date);courseContentMapper.saveSection(section);
}

3.3.9.3、web层

@RequestMapping("/saveOrUpdateSection")
public ResponseResult saveOrUpdateSection(@RequestBody CourseSection section){courseContentService.saveSection(section);return new ResponseResult(true, 200, "新增章节成功", null);
}

3.3.9.4、postman测试

3.3.10、修改章节状态

  • 名称: updateSectionStatus
  • 描述: 修改章节状态
  • URL: http://localhost:8080/ssm-web/courseContent/updateSectionStatus
  • 请求方式: GET
  • 请求参数
字段 说明 类型 是否必需 备注
id 章节ID int
status 章节状态 int 状态,0:隐藏;1:待更新;2:已发布
  • 请求示例
http://localhost:8080/ssm-web/courseContent/updateSectionStatus?id=7&status=1
  • 响应结果示例
{"success": true,"state": 200,"message": "响应成功","content": {"status": 1}
}

3.3.10.1、dao层

/*修改章节状态*/
public void updateSectionStatus(Course course);

3.3.10.2、service层

@Override
public void updateSectionStatus(Integer id, Integer status) {// 封装信息Course course = new Course();course.setId(id);course.setStatus(status);course.setUpdateTime(new Date());// 更新状态courseContentMapper.updateSectionStatus(course);
}

3.3.10.3、web层

@RequestMapping("/updateSectionStatus")
public ResponseResult updateSectionStatus(@RequestParam Integer id, @RequestParam Integer status){courseContentService.updateSectionStatus(id, status);HashMap<Object, Object> map = new HashMap<>();ResponseResult res = new ResponseResult(true, 200, "更新章节状态成功", map);return res;
}

3.3.10.4、postman测试

3.3.11、修改章节信息

3.3.11.1、dao层

/*修改章节信息*/
public void updateSection(CourseSection courseSection);
<update id="updateSection" parameterType="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>

3.3.11.2、service层

// 修改章节
@Override
public void updateSection(CourseSection courseSection) {// 补全信息Date date = new Date();courseSection.setUpdateTime(date);courseContentMapper.updateSection(courseSection);
}

3.3.11.3、web层

@RequestMapping("/saveOrUpdateSection")
public ResponseResult saveOrUpdateSection(@RequestBody CourseSection section){if(section.getId() == null) {courseContentService.saveSection(section);return new ResponseResult(true, 200, "新增章节成功", null);}else{courseContentService.updateSection(section);return new ResponseResult(true, 200, "更新章节成功", null);}
}

3.3.11.4、postman测试

3.3.12、新建课时信息以及修改课时信息

  • 名称: saveLesson
  • 描述: 保存课时信息
  • URL: http://localhost:8080/ssm-web/courseContent/saveLesson
  • 请求方式: POST
  • 请求参数
字段 说明 类型 是否必需 备注
id 课时ID int 添加操作不携带id, 修改操作必须携带ID
courseId 课程ID int
sectionId 章节ID int
theme 课时名称 String
duration 课时时长(分钟) int
isFree 是否免费,0 免费,1 付费 int
orderNum 排序字段 int
  • 请求示例
//新建
{"courseId":7,"sectionId":7,"theme":"文案高手养成","duration":15,"isFree":0,"orderNu":2
}

3.3.12.1、dao层

/*保存课时信息*/
public void saveLesson(CourseLesson courseLesson);
<insert id="saveLesson" parameterType="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><update id="updateLesson" parameterType="CourseLesson">update course_lesson<trim prefix="SET" suffixOverrides=","><if test="theme != null and theme != ''">theme=#{theme},</if><if test="duration != null and duration != ''">duration=#{duration},</if><if test="isFree != null and isFree != ''">is_free=#{isFree},</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>

3.3.12.2、service层

@Override
public void saveLesson(CourseLesson courseLesson) {// 补全信息Date date = new Date();courseLesson.setCreateTime(date);courseLesson.setUpdateTime(date);courseContentMapper.saveLesson(courseLesson);
}@Override
public void updateLesson(CourseLesson courseLesson) {// 补全信息Date date = new Date();courseLesson.setUpdateTime(date);courseContentMapper.updateLesson(courseLesson);
}

3.3.12.3、web层

@RequestMapping("/saveOrUpdateLesson")
public ResponseResult saveOrUpdateLesson(@RequestBody CourseLesson courseLesson){if(courseLesson.getId() == null){courseContentService.saveLesson(courseLesson);return new ResponseResult(true, 200, "保存信息成功", null);}else{courseContentService.updateLesson(courseLesson);return new ResponseResult(true, 200, "修改信息成功", null);}
}

3.3.12.4、postman测试

拉勾教育后台管理系统(SSM)(课程管理模块开发)【学习笔记】相关推荐

  1. 06_04_任务一:拉勾教育后台管理系统[课程管理模块、图片上传、 BeanUtils封装实体类](SSM)

    拉勾教育后台管理系统(SSM) 1. 项目架构 1.1 项目介绍 ​ 拉勾教育后台管理系统,是提供给拉勾教育的相关业务人员使用的一个后台管理系统, 业务人员可以在 这个后台管理系统中,对课程信息.广告 ...

  2. 06_04_任务二:SSM拉勾教育后台管理系统(广告模块与用户模块)

    拉勾教育后台管理系统(SSM) 广告模块 广告模块功能分析 拉勾教育后台管理系统的 广告管理模块包含了以下功能: 广告位列表查询 添加&修改广告位 回显广告位名称 广告分页查询 图片上传接口 ...

  3. 06_04_SSM拉勾教育后台管理系统(权限模块\登录及动态菜单)

    拉勾教育后台管理系统(SSM)权限模块 权限概念介绍 权限:权利(能做的)和限制(不能做的),在权限范围内做好自己的事情,不该看的不看,不该做的不做 认证: 验证用户名密码是否正确的过程 授权: 对用 ...

  4. SSM-下(拉勾教育后台管理系统-前端)

    第六阶段模块五 任务一 课程和广告模块前端开发 1.Vue回顾 1.1 项目结构说明 们使用脚手架快速构建Vue项目 |--- edu-boss 项目名称|--- node_modules 存放依赖包 ...

  5. 黑马简单数据后台管理系统(SSM课程中段)

    黑马视频数据后台管理系统,功能包括增删用户,增删角色(职称),只放逻辑代码 页面预览:   先配置web.xml: <?xml version="1.0" encoding= ...

  6. vue后台管理系统之日志管理模块

    前端的后台的日志管理模块功能的实现 (使用的是elementUI框架) 这是日志管理模块实现的效果图 <!-- 搜索 --><div class="log-header&q ...

  7. 教育平台项目后台管理系统:课程内容模块

    开发流程 需求分析 配置课时(课程内容管理)模块,主要是对课程内容进行管理. 数据库表分析 course - 课程表 course_section - 课程章节表 course_lesson - 课时 ...

  8. 拉勾教育java高薪训练营课程怎么样_[拉勾教育-大前端高薪训练营]这可能是迄今为止对大前端最好的解释...

    前端技术领域发展至今,已经不仅仅是 PC 端浏览器网页的开发这么简单了.现在很流行一个词来形成前端技术领域,叫做大前端.但是,至少到目前为止我个人还没有看到一个对大前端的解释非常不错的.不过,接下来的 ...

  9. 拉勾教育管理系统(后端)

    拉勾教育管理系统 项目介绍与后台系统搭建 项目架构 项目介绍 ​ 拉钩教育后台管理系统,是提供给拉钩教育的相关业务人员使用的一个后台管理系统,,业务人员可以在这个后台管理系统中,对课程信息.讲师信息. ...

最新文章

  1. oracle存储空间管理,Oracle存储空间管理
  2. ValueError: The data property of a figure may only be assigned a list or tuple that contains a .....
  3. mysql工具使用意义_MySQL性能分析、及调优工具使用详解
  4. HubSpot company数据在UI上的展示和通过API方式进行获取
  5. 全球增长最快域名解析商Top10:中国占据四席
  6. 前端学习(872):注册事件兼容性处理
  7. Go 并发编程 — 深入浅出 sync.Pool ,最全的使用姿势,最深刻的原理
  8. 不均衡数据集采样1——SMOTE算法(过采样)
  9. C.One Piece
  10. ztree 指定节点清空_zTree节点文字过多的处理方法
  11. 智能温控风扇、DS18B20、原理图、PROTEUS仿真图、PCB图
  12. 解密 RubyEncoder
  13. 开关电源初级和次级变压器之间的Y电容作用
  14. 股票涨跌的心理学原理: 过度自信理论
  15. 走近棒球运动·亚特兰大勇士队·MLB棒球创造营
  16. meethigher-定时刷步数收取蚂蚁森林能量
  17. SpringMVC创建Maven工程
  18. Farmer John's math(c++)
  19. 深度学习_深度学习基础知识_TTA(测试时增强)
  20. Vs插件 VisualSvn破解

热门文章

  1. 抄底摸顶的高概率交易技巧
  2. 为掌握Java设计模式奠基:两步搞懂UML类图
  3. 递归函数之汉诺塔(附:raptor汉诺塔)
  4. AT32F403A 224K RAM 和非零等待区关系
  5. 基于图像识别的电子相册项目
  6. ng2 angular2 使用bootstrap框架
  7. 有些弹出窗口截图截不了怎么办
  8. 如何安装Rstudio
  9. InfluxDB 修改数据存储路径
  10. php语言风格,php风格符