拉勾教育后台管理系统(SSM)(课程管理模块开发)【学习笔记】
文章目录
- 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坐标
- 在dependencyManagement标签中锁定依赖的版本
- 在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聚合工程_搭建拉勾教育后台管理系统
工程整体结构如下:
- lagou_edu_home_parent为父工程,其余工程为子工程,都继承父工程lagou_edu_home_parent
- lagou_edu_home_parent工程将其子工程都进行了聚合
- 子工程之间存在依赖关系:
- ssm_domain依赖ssm_utils
- ssm_dao依赖ssm_domain
- ssm_service依赖ssm_dao
- ssm_web依赖ssm_service
依赖关系建立原则:当前项目中要用到那个项目的资源,那么当前项目就依赖要用到资源的项目(直接依赖和间接依赖)
2.2.5、聚合工程创建
- 先创建一个maven工程lagou_edu_home_parent
- 然后删除掉src目录
- 然后创建子工程
- 创建ssm_utils
- 创建ssm_domain
- 创建ssm_dao
- 创建ssm_service
- 创建ssm_web
- 这里还要配置一下ssm_web中的pom中的打包方式为war,并且创建webapp和对应的webx.ml文件
- 然后开始配置子工程之间的依赖关系
- 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>
- 最后输入maven install
- 最终的项目结构
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)(课程管理模块开发)【学习笔记】相关推荐
- 06_04_任务一:拉勾教育后台管理系统[课程管理模块、图片上传、 BeanUtils封装实体类](SSM)
拉勾教育后台管理系统(SSM) 1. 项目架构 1.1 项目介绍 拉勾教育后台管理系统,是提供给拉勾教育的相关业务人员使用的一个后台管理系统, 业务人员可以在 这个后台管理系统中,对课程信息.广告 ...
- 06_04_任务二:SSM拉勾教育后台管理系统(广告模块与用户模块)
拉勾教育后台管理系统(SSM) 广告模块 广告模块功能分析 拉勾教育后台管理系统的 广告管理模块包含了以下功能: 广告位列表查询 添加&修改广告位 回显广告位名称 广告分页查询 图片上传接口 ...
- 06_04_SSM拉勾教育后台管理系统(权限模块\登录及动态菜单)
拉勾教育后台管理系统(SSM)权限模块 权限概念介绍 权限:权利(能做的)和限制(不能做的),在权限范围内做好自己的事情,不该看的不看,不该做的不做 认证: 验证用户名密码是否正确的过程 授权: 对用 ...
- SSM-下(拉勾教育后台管理系统-前端)
第六阶段模块五 任务一 课程和广告模块前端开发 1.Vue回顾 1.1 项目结构说明 们使用脚手架快速构建Vue项目 |--- edu-boss 项目名称|--- node_modules 存放依赖包 ...
- 黑马简单数据后台管理系统(SSM课程中段)
黑马视频数据后台管理系统,功能包括增删用户,增删角色(职称),只放逻辑代码 页面预览: 先配置web.xml: <?xml version="1.0" encoding= ...
- vue后台管理系统之日志管理模块
前端的后台的日志管理模块功能的实现 (使用的是elementUI框架) 这是日志管理模块实现的效果图 <!-- 搜索 --><div class="log-header&q ...
- 教育平台项目后台管理系统:课程内容模块
开发流程 需求分析 配置课时(课程内容管理)模块,主要是对课程内容进行管理. 数据库表分析 course - 课程表 course_section - 课程章节表 course_lesson - 课时 ...
- 拉勾教育java高薪训练营课程怎么样_[拉勾教育-大前端高薪训练营]这可能是迄今为止对大前端最好的解释...
前端技术领域发展至今,已经不仅仅是 PC 端浏览器网页的开发这么简单了.现在很流行一个词来形成前端技术领域,叫做大前端.但是,至少到目前为止我个人还没有看到一个对大前端的解释非常不错的.不过,接下来的 ...
- 拉勾教育管理系统(后端)
拉勾教育管理系统 项目介绍与后台系统搭建 项目架构 项目介绍 拉钩教育后台管理系统,是提供给拉钩教育的相关业务人员使用的一个后台管理系统,,业务人员可以在这个后台管理系统中,对课程信息.讲师信息. ...
最新文章
- oracle存储空间管理,Oracle存储空间管理
- ValueError: The data property of a figure may only be assigned a list or tuple that contains a .....
- mysql工具使用意义_MySQL性能分析、及调优工具使用详解
- HubSpot company数据在UI上的展示和通过API方式进行获取
- 全球增长最快域名解析商Top10:中国占据四席
- 前端学习(872):注册事件兼容性处理
- Go 并发编程 — 深入浅出 sync.Pool ,最全的使用姿势,最深刻的原理
- 不均衡数据集采样1——SMOTE算法(过采样)
- C.One Piece
- ztree 指定节点清空_zTree节点文字过多的处理方法
- 智能温控风扇、DS18B20、原理图、PROTEUS仿真图、PCB图
- 解密 RubyEncoder
- 开关电源初级和次级变压器之间的Y电容作用
- 股票涨跌的心理学原理: 过度自信理论
- 走近棒球运动·亚特兰大勇士队·MLB棒球创造营
- meethigher-定时刷步数收取蚂蚁森林能量
- SpringMVC创建Maven工程
- Farmer John's math(c++)
- 深度学习_深度学习基础知识_TTA(测试时增强)
- Vs插件 VisualSvn破解