SSM单体项目:拉勾教育后台管理系统(上)
任务一:课程模块
1.项目架构
1.1 项目介绍
拉勾教育后台管理系统,是提供给拉勾教育的相关业务人员使用的一个后台管理系统, 业务人员可以在这个后台管理系统中,对课程信息、广告信息、用户信息、 权限信息等数据进行维护.
在 web阶段,我们已经完成了拉勾教育后台管理系统中课程模块, 接下来将对拉勾教育后台管理系统进行升级改造,基于SSM框架来完成课程信息模块,广告信息模块,用户信息模块,权限信息模块
1.2 页面原型展示
用户名:18201288771 密码:111111
1.3 技术选型
1.3.1 前端技术选型
1.3.2 后端技术选型
1.4 项目开发环境
- 开发工具
- 后端: IDEA 2019
- 前端: VS code
- 数据库客户端工具: SQLYog
- 开发环境
- JDK 11
- Maven 3.6.3
- MySQL 5.7
2.Maven进阶使用(Maven聚合工程)
2.1 maven基础知识回顾
2.1.1 maven介绍
maven 是一个项目管理工具,主要作用是在项目开发阶段对Java项目进行依赖管理和项目构建。
依赖管理:就是对jar包的管理。通过导入maven坐标,就相当于将仓库中的jar包导入了当前项目中。
项目构建:通过maven的一个命令就可以完成项目从清理、编译、测试、报告、打包,部署整个过程。
2.1.2 maven的仓库类型
1.本地仓库
2.远程仓库
①maven中央仓库(地址:http://repo2.maven.org/maven2/)
②maven私服(公司局域网内的仓库,需要自己搭建)
③其他公共远程仓库(例如apache提供的远程仓库,地址:http://repo.maven.apache.org/maven2/)
本地仓库---》maven私服---》maven中央仓库
2.1.3 maven常用命令
clean: 清理
compile:编译
test: 测试
package:打包
install: 安装
2.1.4 maven坐标书写规范
2.2 maven的依赖传递
2.2.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.2.2 如何解决依赖冲突
1.使用maven提供的依赖调解原则
第一声明者优先原则
路径近者优先原则
2.排除依赖
3.锁定版本
2.2.3 依赖调节原则——第一声明者优先原则
在 pom 文件中定义依赖,以先声明的依赖为准。其实就是根据坐标导入的顺序来确定最终使用哪个传递过来的依赖。
结论:通过上图可以看到,spring-aop和spring-webmvc都传递过来了spring-beans,但是因为spring-aop在前面,所以最终使用的spring-beans是由spring-aop传递过来的,而spring-webmvc传递过来的spring-beans则被忽略了。
2.2.4 依赖调节原则——路径近者优先原则
总结:直接依赖大于依赖传递
2.2.5 排除依赖
可以使用exclusions标签将传递过来的依赖排除出去。
2.2.6 版本锁定
采用直接锁定版本的方法确定依赖jar包的版本,版本锁定后则不考虑依赖的声明顺序或依赖的路径,以锁定的版本为准添加到工程中,此方法在企业开发中经常使用。
版本锁定的使用方式:
第一步:在dependencyManagement标签中锁定依赖的版本
第二步:在dependencies标签中声明需要导入的maven坐标
①在dependencyManagement标签中锁定依赖的版本
②在dependencies标签中声明需要导入的maven坐标
2.2.7 properties标签的使用
<properties>
<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>
2.3 maven聚合工程(分模块)
概念:
在现实生活中,汽车厂家进行汽车生产时,由于整个生产过程非常复杂和繁琐,工作量非常大,所以厂家都会将整个汽车的部件分开生产,最终再将生产好的部件进行组装,形成一台完整的汽车。
2.3.1 分模块构建maven工程分析
在企业项目开发中,由于项目规模大,业务复杂,参与的人员比较多,一般会通过合理的模块拆分将一个大型的项目拆分为N多个小模块,分别进行开发。而且拆分出的模块可以非常容易的被其他模块复用
常见的拆分方式有两种:
第一种:按照业务模块进行拆分,每个模块拆分成一个maven工程,例如将一个项目分为用户模块,订单模块,购物车模块等,每个模块对应就是一个maven工程
第二种:按照层进行拆分,例如持久层、业务层、表现层等,每个层对应就是一个maven工程
不管上面那种拆分方式,通常都会提供一个父工程,将一些公共的代码和配置提取到父工程中进行统一管理和配置。
2.3.2 maven工程的继承
在Java语言中,类之间是可以继承的,通过继承,子类就可以引用父类中非private的属性和方法。同样,在maven工程之间也可以继承,子工程继承父工程后,就可以使用在父工程中引入的依赖。继承的目的是为了消除重复代码。
2.3.3 maven工程的聚合
在maven工程的pom.xml文件中可以使用标签< modules>将其他maven工程聚合到一起,聚合的目的是为了进行统一操作。
例如拆分后的maven工程有多个,如果要进行打包,就需要针对每个工程分别执行打包命令,操作起来非常繁琐。这时就可以使用标签将这些工程统一聚合到maven父工程中,需要打包的时候,只需要在此工程中执行一次打包命令,其下被聚合的工程就都会被打包了。
2.3.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
① 父工程lagou_edu_home_parent构建
修改pom.xml,添加依赖
<properties>
<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>
<dependencies>
<!--mybatis坐标-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</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.12</version>
</dependency>
<!--spring坐标-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<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-tx</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
<!--mybatis整合spring坐标-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<!--springMVC坐标-->
<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>
② 子工程ssm_utils构建
③ 子工程ssm_domain构建
<!-- 依赖ssm_utils -->
<dependencies>
<dependency>
<groupId>com.lagou</groupId>
<artifactId>ssm_utils</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
④ 子工程ssm_dao构建
配置ssm_domain工程的pom.xml文件
<!--依赖ssm_domain-->
<dependencies>
<dependency>
<groupId>com.lagou</groupId>
<artifactId>ssm_domain</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
创建DAO接口和Mapper映射文件
package com.lagou.dao;
import com.lagou.domain.Test;
import java.util.List;
public interface TestMapper {
public List<Test> 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.lagou.dao.TestMapper">
<select id="findAllTest" resultType="com.lagou.domain.Test">
select * from test;
</select>
</mapper>
在resources目录下创建spring配置文件applicationContext-dao.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/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--spring整合mybatis-->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<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的创建权交给了spring 生产sqlSession-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="typeAliasesPackage" value="com.lagou.domain"></property>
<!--引入加载mybatis的核心配置文件,可以不用去加载-->
<property name="configLocation" value="classpath:SqlMapConfig.xml"></property>
</bean>
<!--mapper映射扫描 MapperScannerConfigurer扫描该包下所有接口,生成代理对象存到IOC容
器中-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.lagou.dao"></property>
</bean>
</beans>
sqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!-- 是否开启自动驼峰命名规则(camel case)映射,
即从数据库列名 A_COLUMN 到属性名aColumn 的类似映射 a_name aName-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
</configuration>
⑤子工程ssm_service构建
第一步:创建ssm_service工程
第二步:配置ssm_service工程的pom.xml文件
<dependencies>
<dependency>
<groupId>com.lagou</groupId>
<artifactId>ssm_dao</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
第三步:创建TestService接口和实现类
public interface TestService {
public List<Test> findAllTest();
}
@Service
public class TestServiceImpl implements TestService {
@Autowired
private TestMapper testMapper;
@Override
public List<Test> findAllTest() {
List<Test> allTest = testMapper.findAllTest();
return allTest;
}
}
第四步:创建spring配置文件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/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--配置IOC相关操作:开启注解扫描-->
<context:component-scan base-package="com.lagou.service"></context:component-scan>
<import resource="classpath:applicationContext_dao.xml"/>
</beans>
⑥子工程ssm_web构建
第一步:创建maven_web工程,注意打包方式为war
第二步:配置maven_web工程的pom.xml文件
<dependencies>
<dependency>
<groupId>com.lagou</groupId>
<artifactId>ssm_service</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
第三步:创建Controller
@RestController
@RequestMapping("/test")
public class TestController {
@Autowired
private TestService testService;
@RequestMapping("/findAllTest")
public List<Test> findAllTest(){
List<Test> allTest = testService.findAllTest();
return allTest;
}
}
第四步: 创建springmvc配置文件springmvc.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/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--1.组件扫描:只扫描controller-->
<context:component-scan base-package="com.lagou.controller"></context:component-scan>
<!--2.mvc注解增强:处理器映射器及处理器适配器-->
<mvc:annotation-driven></mvc:annotation-driven>
<!--3.视图解析器-->
<!-- <bean id="resourceViewResolve" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".html"></property>
</bean>-->
<!--4.放行静态资源-->
<mvc:default-servlet-handler></mvc:default-servlet-handler>
</beans>
第五步:编写applicationContext.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/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--引入:applicationContext_service.xml-->
<import resource="classpath:applicationContext_service.xml"/>
</beans>
第六步:配置web.xml
<!--前端控制器-->
<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>
<!--中文乱码过滤器:解决post方式提交的乱码-->
<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.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>
3.拉勾教育后台管理系统研发
3.1 课程管理模块功能分析
在本次的项目中,首先先来完成拉勾教育后台管理系统的 课程管理模块, 课程管理模块包含了多条件查询、 图片上传、 新建&修改课程、课程状态管理、课程内容展示、回显章节对应的课程信息、新建&修改章节信息、修改章节状态、 新建&修改课时信息等接口的编写
3.1.1 课程管理
- 实现以下功能:
- 多条件查询
- 图片上传
- 新建课程信息
- 回显课程信息
- 修改课程信息
- 课程状态管理
- 课程内容展示
- 回显章节对应的课程信息
- 新建&修改章节信息
- 修改章节状态
- 新建课时信息
3.2 课程管理模块表设计
3.2.1 创建数据库及表
在资料中找到 ssm_lagou_edu.sql,使用SQLYog 执行SQL脚本 ,导入表结构及表信息
3.2.2 表关系介绍
1.ER图
2.数据实体描述
2.1 课程表
3.3 课程管理模块接口实现
多条件课程列表查询
需求分析
根据课程名称及课程状态进行多条件查询
查看接口文档,进行编码
查看接口文档
实体类:Course
//主键
private int id;
//课程名称
private String courseName;
//课程一句话简介
private String brief;
//原价
private double price;
//原价标签
private String priceTag;
//优惠价
private double discounts;
//优惠价标签
private String discountsTag;
//课程内容markdown
private String courseDescriptionMarkDown;
//课程描述
private String courseDescription;
//课程分享图片url
private 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;
// getter/setter....
ResponseResult
public class ResponseResult {
private Boolean success;
private Integer state;
private String message;
private Object content;
public ResponseResult() {
}
public ResponseResult(Boolean success, Integer state, String message, Object
content) {
this.success = success;
this.state = state;
this.message = message;
this.content = content;
}
//getter/setter..
}
实体类:CourseVo(View Object表现层对象:主要用于表现层来接收参数的)
public class CourseVO {
/**
* 课程名称
* */
private String courseName;
/**
* 课程状态
* */
private Integer status;
// getter/setter....
}
Dao层:CourseMapper
public interface CourseMapper {
/**
* 多条件课程列表查询
*/
public List<Course> findCourseByConditioin(CourseVo courseVo);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lagou.dao.CourseMapper">
<!-- 多条件课程列表查询 -->
<select id="findCourseByConditioin"
parameterType="com.lagou.domain.CourseVO" resultType="com.lagou.domain.Course">
SELECT
id,
course_name,
price,
sort_num,
STATUS
FROM
course
<where>
<if test="true">
and is_del != 1
</if>
<if test="courseName != null and courseName != ''">
and course_name like concat('%',#{courseName},'%')
</if>
<if test="status != null and status !=''">
and status = #{status}
</if>
</where>
</select>
Service层:CourseService
public interface CourseService {
/**
* 多条件查询课程列表
* */
public List<Course> findCourseByConditioin(CourseVO courseVO);
}
@Service
public class CourseServiceImpl implements CourseService {
@Autowired
private CourseMapper courseMapper;
@Override
public List<Course> findCourseByConditioin(CourseVO courseVO) {
List<Course> courseList = courseMapper.findCourseByConditioin(courseVO);
return courseList;
}
Web层:CourseController
@RestController
@RequestMapping("/course")
public class CourseController {
@Autowired
private CourseService courseService;
/**
* 查询课程信息&条件查询 接口
* */
@RequestMapping("/findCourseByConditioin")
public ResponseResult findCourseByConditioin(@RequestBody CourseVO courseVO)
{
List<Course> courseList = courseService.findCourseByConditioin(courseVO);
ResponseResult result = new ResponseResult(true,200,"响应成功",courseList);
return result;
}
Postman测试接口
课程图片上传
需求分析:
需求:在新增课程页面需要进行图片上传,并回显图片信息
查看接口文档,进行编码
查看接口文档
springmvc.xml
<!--5.配置文件解析器-->
<!-- 此处id为固定写法,不能随便取名-->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="1048576"></property>
</bean>
Web层:CourseController
/**
* 图片上传接口
* */
@RequestMapping("/courseUpload")
public ResponseResult fileUpload(@RequestParam("file")MultipartFile file,
HttpServletRequest request){
try {
//1.判断文件是否为空
if(file.isEmpty()){
throw new RuntimeException();
}
//2.获取项目部署路径
// D:\apache-tomcat-8.5.56\webapps\ssm_web\
String realPath = request.getServletContext().getRealPath("/");
// D:\apache-tomcat-8.5.56\webapps\
String webappsPath =
realPath.substring(0,realPath.indexOf("ssm_web"));
//3.获取原文件名
String fileName = file.getOriginalFilename();
//4.新文件名
String newFileName = System.currentTimeMillis() +
fileName.substring(fileName.lastIndexOf("."));
//5.上传文件
String uploadPath = webappsPath+"upload\\";
File filePath = new File(uploadPath,newFileName);
//如果目录不存在就创建目录
if(!filePath.getParentFile().exists()){
filePath.getParentFile().mkdirs();
System.out.println("创建目录: " + filePath);
}
file.transferTo(filePath);
//6.将文件名和文件路径返回
Map<String,String> map = new HashMap<>();
map.put("fileName",newFileName);
map.put("filePath",LOCAL_URL+"/upload/"+newFileName);
ResponseResult result = new ResponseResult(true,200,"响应成功",map);
return result;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
Postman测试接口
新建课程信息
需求分析:
填写好新增课程信息后,点击保存,将表单信息保存到数据库中
查看接口文档,进行编码
查看接口文档
Dao层:CourseMapper
public interface CourseMapper {
/**
* 保存课程信息
*/
public int saveCourse(Course course);
/**
* 保存讲师信息
* */
public void saveTeacher(Teacher teacher);
}
CourseMapper.xml
<!-- 保存课程信息 -->
<insert id="saveCourse" parameterType="com.lagou.domain.Course" >
INSERT INTO course(
course_name,
brief,
preview_first_field,
preview_second_field,
course_img_url,
course_list_img,
sort_num,
price,
discounts,
sales,
discounts_tag,
course_description_mark_down,
create_time,
update_time
) VALUES(#{courseName},#{brief},#{previewFirstField},#{previewSecondField},#{courseImgUrl},
#{courseListImg},#{sortNum},#{price},#{discounts},#{sales},#{discountsTag},#{courseDescriptionMarkDown},
#{createTime},#{updateTime});
<selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id">
SELECT LAST_INSERT_ID();
</selectKey>
</insert>
<!-- 保存讲师信息 -->
<insert id="saveTeacher" parameterType="com.lagou.domain.Teacher">
INSERT INTO teacher(
course_id,
teacher_name,
POSITION,
description,
create_time,
update_time
) VALUES(#{courseId},#{teacherName},#{position},#{description},#
{createTime},#{updateTime});
</insert>
Service层:CourseService
public interface CourseService {
/**
* 保存课程信息
* */
public void saveCourseOrTeacher(CourseVO courseVO);
}
@Service
public class CourseServiceImpl implements CourseService {
@Autowired
private CourseMapper courseMapper;
@Override
public void saveCourseOrTeacher(CourseVO courseVO) {
try {
//封装课程信息
Course course = new Course();
BeanUtils.copyProperties(course,courseVO);
//补全信息
Date date = new Date();
course.setCreateTime(date);
course.setUpdateTime(date);
//保存课程
courseMapper.saveCourse(course);
//获取新插入数据的id
int id = course.getId();
//封装讲师信息
Teacher teacher = new Teacher();
BeanUtils.copyProperties(teacher,courseVO);
//补全信息
teacher.setCourseId(id);
teacher.setCreateTime(date);
teacher.setUpdateTime(date);
//保存讲师信息
courseMapper.saveTeacher(teacher);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Web层:CourseController
@RestController
@RequestMapping("/course")
public class CourseController {
@Autowired
private CourseService courseService;
/**
* 保存&修改课程信息接口
* */
@RequestMapping("/saveOrUpdateCourse")
public ResponseResult saveOrUpdateCourse(@RequestBody CourseVO courseVO){
try {
if(courseVO.getId() == null){
courseService.saveCourseOrTeacher(courseVO);
ResponseResult result = new ResponseResult(true,200,"响应成
功",null);
return result;
}else{
courseService.updateCourseOrTeacher(courseVO);
ResponseResult result = new ResponseResult(true,200,"响应成
功",null);
return result;
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
Postman测试接口
回显课程信息
需求分析:
点击编辑按钮,回显课程信息
查看接口文档,进行编码
查看接口文档
Dao层:CourseMapper
public interface CourseMapper {
/**
* 根据id 获取课程信息
* */
public CourseVO findCourseById(int id);
}
CourseMapper.xml
<!-- 根据id查询 -->
<select id="findCourseById" parameterType="int"
resultType="com.lagou.domain.CourseVO">
SELECT
course_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_down
FROM course LEFT JOIN teacher ON course.id = teacher.course_id
WHERE course.id = #{id}
</select>
Service层:CourseService
public interface CourseService {
/**
* 根据id获取课程信息
* */
public CourseVO findCourseById(int id);
}
@Service
public class CourseServiceImpl implements CourseService {
@Autowired
private CourseMapper courseMapper;
@Override
public CourseVO findCourseById(int id) {
return courseMapper.findCourseById(id);
}
}
Web层:CourseController
@RestController
@RequestMapping("/course")
public class CourseController {
@Autowired
private CourseService courseService;
/**
* 根据id获取课程信息
* */
@RequestMapping("/findCourseById")
public ResponseResult findCourseById(@RequestParam int id) {
try {
CourseVO courseVO = courseService.findCourseById(id);
ResponseResult result = new ResponseResult(true,200,"响应成功",courseVO);
return result;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
Postman测试接口
修改课程信息
需求分析:
点击保存按钮,将修改后的课程信息保存到数据库中
查看接口文档,进行编码
查看接口文档
Dao层:CourseMapper
public interface CourseMapper {
/**
* 修改课程信息
* */
public void updateCourse(Course course);
/**
* 修改讲师信息
* */
public void updateTeacher(Teacher teacher);
}
CourseMapper.xml
<!-- 修改课程信息 -->
<update id="updateCourse" parameterType="com.lagou.domain.Course">
UPDATE course
<trim prefix="SET" suffixOverrides=",">
<if test="courseName != null and courseName != ''">
course_name = #{courseName},
</if>
<if test="brief != null and brief != ''">
brief=#{brief},
</if>
<if test="previewFirstField != null and previewFirstField != ''">
preview_first_field=#{previewFirstField},
</if>
<if test="previewSecondField != null and previewSecondField != ''">
preview_second_field=#{previewSecondField},
</if>
<if test="courseImgUrl != null and courseImgUrl != ''">
course_img_url=#{courseImgUrl},
</if>
<if test="courseListImg != null and courseListImg != ''">
course_list_img=#{courseListImg},
</if>
<if test="sortNum != null and sortNum != ''">
sort_num=#{sortNum},
</if>
<if test="price != null and price != ''">
price=#{price},
</if>
<if test="discounts != null and discounts != ''">
discounts=#{discounts},
</if>
<if test="sales != null and sales != '' or sales==0">
sales=#{sales},
</if>
<if test="discountsTag != null and discountsTag != ''">
discounts_tag=#{discountsTag},
</if>
<if test="courseDescriptionMarkDown != null 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="com.lagou.domain.Teacher">
UPDATE teacher
<trim prefix="SET" suffixOverrides=",">
<if test="teacherName != null and teacherName != ''">
teacher_name = #{teacherName},
</if>
<if test="position != null and position != ''">
position = #{position},
</if>
<if test="description != null and description != ''">
description = #{description},
</if>
<if test="updateTime != null">
update_time=#{updateTime}
</if>
</trim>
<where>
<if test="courseId != null and courseId != '' ">
course_id = #{courseId}
</if>
</where>
</update>
Service层:CourseService
public interface CourseService {
/**
* 修改课程信息
* */
public void updateCourseOrTeacher(CourseVO courseVO);
}
@Service
public class CourseServiceImpl implements CourseService {
@Autowired
private CourseMapper courseMapper;
@Override
public void updateCourseOrTeacher(CourseVO courseVO) {
try {
//封装课程信息
Course course = new Course();
BeanUtils.copyProperties(course,courseVO);
//补全信息
Date date = new Date();
course.setUpdateTime(date);
//更新课程
courseMapper.updateCourse(course);
//封装讲师信息
Teacher teacher = new Teacher();
BeanUtils.copyProperties(teacher,courseVO);
//补全信息
teacher.setCourseId(course.getId());
teacher.setUpdateTime(date);
//更新讲师信息
courseMapper.updateTeacher(teacher);
} catch (Exception e) {
e.printStackTrace();
}
}
Web层:CourseController
@RestController
@RequestMapping("/course")
public class CourseController {
@Autowired
private CourseService courseService;
/**
* 保存&修改课程信息接口
* */
@RequestMapping("/saveOrUpdateCourse")
public ResponseResult saveOrUpdateCourse(@RequestBody CourseVO courseVO){
try {
if(courseVO.getId() == null){
courseService.saveCourseOrTeacher(courseVO);
ResponseResult result = new ResponseResult(true,200,"响应成
功",null);
return result;
}else{
courseService.updateCourseOrTeacher(courseVO);
ResponseResult result = new ResponseResult(true,200,"响应成
功",null);
return result;
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
Postman测试接口
课程状态管理
需求分析:
在课程列表展示页面中,可以通过点击 上架/下架按钮,修改课程状态
查看接口文档,进行编码
查看接口文档
Dao层:CourseMapper
public interface CourseMapper {
/**
* 修改课程状态
* */
public void updateCourseStatus(Course course);
}
CourseMapper.xml
<!-- 修改课程状态 -->
<update id="updateCourseStatus" parameterType="com.lagou.domain.Course">
UPDATE course SET STATUS = #{status} ,update_time = #{updateTime} WHERE
id = #{id}
</update>
Service层:CourseService
/**
* 修改课程状态
* */
public void updateCourseStatus(int id,int status);
@Override
public void updateCourseStatus(int id,int status) {
try {
//封装数据
Course course = new Course();
course.setStatus(status);
course.setId(id);
course.setUpdateTime(new Date());
//调用Dao
courseMapper.updateCourseStatus(course);
} catch (Exception e) {
e.printStackTrace();
}
}
Web层:CourseController
/**
* 修改课程状态
* */
@RequestMapping("/updateCourseStatus")
public ResponseResult updateCourseStatus(@RequestParam int id,@RequestParam
int status){
try {
//执行修改操作
courseService.updateCourseStatus(id, status);
//保存修改后的状态,并返回
Map<String,Integer> map = new HashMap<>();
map.put("status",status);
ResponseResult result = new ResponseResult(true,200,"响应成功",map);
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
Postman测试接口
课程内容展示
需求分析:
需求:点击内容管理,展示课程对应的课程内容(课程内容包含了章节和课时)
查看接口文档,进行编码:
查看接口文档:
CourseSection
/**
* 章节类
* */
public class CourseSection {
//id
private Integer id;
//课程id
private 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;
public List<CourseLesson> getLessonList() {
return lessonList;
}
public void setLessonList(List<CourseLesson> lessonList) {
this.lessonList = lessonList;
}
Dao层:CourseContentMapper
public interface CourseContentMapper {
/**
* 查询课程下的章节与课时信息
* */
public List<CourseSection> findSectionAndLessonByCourseId(int courseId);
}
<!-- 根据课程ID 查询课程内容(章节与课时) -->
<select id="findSectionAndLessonByCourseId" parameterType="int"
resultMap="BaseResultMap">
SELECT
cs.*,
<include refid="lesson_column_list"/>
FROM course_section cs
LEFT JOIN course_lesson cl ON cs.id = cl.section_id
WHERE cs.course_id = #{courseId} ORDER BY cs.order_num ;
</select>
<!-- 一对多配置,一个章节下有多个课时 -->
<resultMap id="BaseResultMap" type="com.lagou.domain.CourseSection">
<result property="id" column="id"></result>
<result property="courseId" column="course_id"></result>
<result property="sectionName" column="section_name"></result>
<result property="description" column="description"></result>
<result property="orderNum" column="order_num"></result>
<result property="status" column="status"></result>
<!-- 使用 collection,配置一对多关系 -->
<collection property="lessonList" resultMap="lessionListResultMap"/>
</resultMap>
<resultMap id="lessionListResultMap" type="com.lagou.domain.CourseLesson">
<id property="id" column="lessonId"></id>
<result property="courseId" column="course_id"></result>
<result property="sectionId" column="section_id"></result>
<result property="theme" column="theme"></result>
<result property="duration" column="duration"></result>
<result property="isFree" column="is_free"></result>
<result property="orderNum" column="order_num"></result>
<result property="status" column="status"></result>
</resultMap>
<!-- 课时表字段信息 -->
<sql id="lesson_column_list">
cl.id as lessonId,
cl.course_id,
cl.section_id,
cl.theme,
cl.duration,
cl.is_free,
cl.order_num,
cl.status
</sql>
Service层:CourseContentService
public interface CourseContentService {
public List<CourseSection> findSectionAndLessonByCourseId(int courseId);
}
@Service
public class CourseContentServiceImpl implements CourseContentService {
@Autowired
private CourseContentMapper contentMapper;
@Override
public List<CourseSection> findSectionAndLessonByCourseId(int courseId) {
List<CourseSection> sectionList =
contentMapper.findSectionAndLessonByCourseId(courseId);
return sectionList;
}
}
Web层:CourseContentController
@RestController
@RequestMapping("/courseContent")
public class CourseContentController {
@Autowired
private CourseContentService contentService;
/**
* 查询课程内容
* */
@RequestMapping("/findSectionAndLesson")
public ResponseResult findSectionAndLessonByCourseId(@RequestParam int
courseId){
try {
//调用service
List<CourseSection> sectionList =
contentService.findSectionAndLessonByCourseId(courseId);
//封装数据并返回
ResponseResult result = new ResponseResult(true,200,"响应成
功",sectionList);
return result;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
Postman测试接口
回显章节对应的课程信息
需求分析:
需求:在课程内容界面回显课程信息
查看接口文档,进行编码:
查看接口文档:
Dao层:CourseContentMapper
public interface CourseContentMapper {
/**
* 回显章节对应的课程信息
* */
public Course findCourseByCourseId(int courseId);
}
<!-- 回显课程信息 -->
<select id="findCourseByCourseId" parameterType="int"
resultType="com.lagou.domain.Course">
SELECT id,course_name FROM course WHERE id = #{courseId}
</select>
Service层:CourseContentService
public interface CourseContentService {
public Course findCourseByCourseId(int courseId);
}
@Service
public class CourseContentServiceImpl implements CourseContentService {
@Autowired
private CourseContentMapper contentMapper;
@Override
public Course findCourseByCourseId(int courseId) {
Course course = contentMapper.findCourseByCourseId(courseId);
return course;
}
}
Web层:CourseContentController
@RestController
@RequestMapping("/courseContent")
public class CourseContentController {
@Autowired
private CourseContentService contentService;
/**
* 回显章节对应的课程信息
* */
@RequestMapping("/findCourseByCourseId")
public ResponseResult findCourseByCourseId(@RequestParam int courseId){
try {
//调用service
Course course = contentService.findCourseByCourseId(courseId);
ResponseResult result = new ResponseResult(true,200,"响应成
功",course);
return result;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
Postman测试接口
新建章节信息
需求分析:
在课程内容展示页面中,可以通过点击添加阶段按钮,添加章节信息
查看接口文档,进行编码
查看接口文档
Dao层:CourseContentMapper
/**
* 保存章节
* */
public void saveSection(CourseSection section);
<!-- 保存章节 -->
<insert id="saveSection" parameterType="com.lagou.domain.CourseSection">
INSERT INTO course_section(
course_id,
section_name,
description,
order_num,
STATUS,
create_time,
update_time
)VALUES(#{courseId},#{sectionName},#{description},#{orderNum},
#{status},#{createTime},#{updateTime});
</insert>
Service层:CourseContentService
public void saveSection(CourseSection section);
@Override
public void saveSection(CourseSection section) {
//补全信息
Date date = new Date();
section.setCreateTime(date);
section.setUpdateTime(date);
contentMapper.saveSection(section);
}
Web层:CourseContentController
@RequestMapping("/saveOrUpdateSection")
public ResponseResult saveOrUpdateSection(@RequestBody CourseSection
section) {
try {
contentService.saveSection(section);
return new ResponseResult(true,200,"响应成功",null);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
Postman测试接口
修改章节信息
需求分析:
点击确定按钮,将修改后的章节信息保存到数据库中
查看接口文档,进行编码
查看接口文档
Dao层:CourseContentMapper
/**
* 修改章节
* */
public void updateSection(CourseSection section);
<!-- 修改章节 -->
<update id="updateSection" parameterType="com.lagou.domain.CourseSection">
UPDATE course_section
<trim prefix="SET" suffixOverrides=",">
<if test="sectionName != null and sectionName != ''">
section_name = #{sectionName},
</if>
<if test="description != null and description != ''">
description = #{description},
</if>
<if test="orderNum != null and orderNum != '' or orderNum == 0">
order_num = #{orderNum},
</if>
<if test="updateTime != null">
update_time=#{updateTime}
</if>
</trim>
<where>
<if test="id != null and id != '' ">id = #{id}</if>
</where>
</update>
Service层:CourseContentService
public void updateSection(CourseSection section);
@Override
public void updateSection(CourseSection section) {
//补全信息
Date date = new Date();
section.setUpdateTime(date);
contentMapper.updateSection(section);
}
Web层:CourseContentController
/**
* 保存&修改章节信息
*/
@RequestMapping("/saveOrUpdateSection")
public ResponseResult saveOrUpdateSection(@RequestBody CourseSection
section) {
try {
//判断携带id是修改操作否则是插入操作
if(section.getId() == null){
contentService.saveSection(section);
return new ResponseResult(true,200,"响应成功",null);
}else{
contentService.updateSection(section);
return new ResponseResult(true,200,"响应成功",null);
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
Postman测试接口
修改章节状态
需求分析:
需求:点击修改章节状态按钮,将当前章节信息的状态进行修改
查看接口文档,进行编码
查看接口文档
Dao层:CourseContentMapper
/**
* 修改章节状态
* */
public void updateSectionStatus(CourseSection section);
CourseContentMapper.xml
<!-- 修改章节状态 -->
<update id="updateSectionStatus"
parameterType="com.lagou.domain.CourseSection">
UPDATE course_section set
status = #{status},
update_time = #{updateTime}
WHERE id = #{id}
</update>
Service层:CourseContentService
public void updateSectionStatus(int id,int status);
@Override
public void updateSectionStatus(int id,int status) {
//封装数据
CourseSection section = new CourseSection();
section.setId(id);
section.setStatus(status);
section.setUpdateTime(new Date());
contentMapper.updateSectionStatus(section);
}
Web层:CourseContentController
/**
* 修改章节状态
* 状态,0:隐藏;1:待更新;2:已发布
* */
@RequestMapping("/updateSectionStatus")
public ResponseResult updateSectionStatus(@RequestParam int id,@RequestParam
int status){
try {
contentService.updateSectionStatus(id,status);
//封装最新的状态信息
Map<String,Integer> map = new HashMap<>();
map.put("status",status);
ResponseResult result = new ResponseResult(true,200,"响应成功",map);
return result;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
Postman测试接口
新建课时信息(自行完成)
需求分析:
需求:点击添加阶段按钮,将弹出页面填写的章节信息保存到数据库中
查看接口文档,进行编码
查看接口文档
Dao层:CourseContentMapper
/**
* 保存课时
* */
public void saveLesson(CourseLesson lesson);
<!-- 添加课时 -->
<insert id="saveLesson" parameterType="com.lagou.domain.CourseLesson">
INSERT INTO course_lesson (
id,course_id,
section_id,
theme,
duration,
is_free,
order_num,
create_time,
update_time
)VALUES(#{id},#{courseId},#{sectionId},#{theme},#{duration},#{isFree},
#{orderNum},#{createTime},#{updateTime});
</insert>
Service层:CourseContentService
public void saveLesson(CourseLesson lesson);
@Override
public void saveLesson(CourseLesson lesson) {
//补全信息
Date date = new Date();
lesson.setCreateTime(date);
lesson.setUpdateTime(date);
contentMapper.saveLesson(lesson);
}
Web层:CourseContentController
/**
* 保存&修改课时
* */
@RequestMapping("/saveOrUpdateLesson")
public ResponseResult saveOrUpdateLesson(@RequestBody CourseLesson lesson){
try {
if(lesson.getId() == null){
contentService.saveLesson(lesson);
return new ResponseResult(true,200,"响应成功",null);
}else{
contentService.updateLesson(lesson);
return new ResponseResult(true,200,"响应成功",null);
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
Postman测试接口
任务二:广告模块
一 广告模块功能分析
在任务二中,首先先来完成拉勾教育后台管理系统的 广告管理模块, 广告模块包含了广告位列表查询、添加&修改广告位、回显广告位名称、广告分页查询、图片上传接口、新建&修改广告、回显广告信息、广告状态上下线等接口的编写
1.1 课程管理
- 实现以下功能:
- 广告位列表查询
- 添加&修改广告位
- 回显广告位名称
- 广告分页查询
- 图片上传接口
- 新建&修改广告接口
- 回显广告信息
- 广告状态上下线
二 广告管理模块表设计
2.1 创建数据库及表
在资料中找到 ssm_lagou_edu.sql,使用SQLYog 执行SQL脚本 ,导入表结构及表信息
2.2 表关系介绍
1.ER图
2.数据实体描述
2.1 广告位表
2.2 广告表
三 广告管理模块接口实现
1.广告位列表查询
1.1 需求分析
需求:点击广告列表按钮进行广告列表展示
1.2 查看接口文档,进行编码
查看接口文档
实体类:PromotionSpace
public class PromotionSpace {
private Integer id;
private String name;
private String spaceKey;
private Date createTime;
private Date updateTime;
private Integer isDel;
@Override
public String toString() {
return "PromotionSpace{" +
"id=" + id +
", name='" + name + '\'' +
", spaceKey='" + spaceKey + '\'' +
", createTime=" + createTime +
", updateTime=" + updateTime +
", isDel=" + isDel +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSpaceKey() {
return spaceKey;
}
public void setSpaceKey(String spaceKey) {
this.spaceKey = spaceKey;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public Integer getIsDel() {
return isDel;
}
public void setIsDel(Integer isDel) {
this.isDel = isDel;
}
Dao层:PromotionSpaceMapper
public interface PromotionSpaceMapper {
/*
获取所有的广告位
*/
public List<PromotionSpace> findAllPromotionSpace();
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lagou.dao.PromotionSpaceMapper">
<select id="findAllPromotionSpace"
resultType="com.lagou.domain.PromotionSpace">
select * from promotion_space
</select>
</mapper>
Service层:PromotionSpaceService
public interface PromotionSpaceService {
/*
获取所有的广告位
*/
public List<PromotionSpace> findAllPromotionSpace();
}
@Service
public class PromotionSpaceServiceImpl implements PromotionSpaceService {
@Autowired
private PromotionSpaceMapper promotionSpaceMapper;
@Override
public List<PromotionSpace> findAllPromotionSpace() {
List<PromotionSpace> allPromotionSpace =
promotionSpaceMapper.findAllPromotionSpace();
return allPromotionSpace;
}
}
Web层:PromotionSpaceController
@RestController
@RequestMapping("/PromotionSpace")
public class PromotionSpaceController {
@Autowired
private PromotionSpaceService promotionSpaceService;
/*
查询所有广告位列表
*/
@RequestMapping("/findAllPromotionSpace")
public ResponseResult findAllPromotionSpace(){
List<PromotionSpace> allPromotionSpace =
promotionSpaceService.findAllPromotionSpace();
ResponseResult responseResult = new ResponseResult(true,200,"响应成
功",allPromotionSpace);
return responseResult;
}
}
Postman测试接口
2.添加&修改广告位
1.1 需求分析
添加:点击广告列表按钮进行广告列表展示
修改:页面回显基础上,点击提交按钮 真正进行数据修改
2.2 查看接口文档,进行编码
查看接口文档
Dao层:PromotionSpaceMapper
public interface PromotionSpaceMapper {
/*
添加广告位
*/
public void savePromotionSpace(PromotionSpace promotionSpace);
/**
* 修改广告位
* */
public void updatePromotionSpace(PromotionSpace promotionSpace);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lagou.dao.PromotionSpaceMapper">
<insert id="savePromotionSpace"
parameterType="com.lagou.domain.PromotionSpace">
insert into promotion_space values(null,#{name},#{spaceKey},#
{createTime},#{updateTime},#{isDel})
</insert>
<update id="updatePromotionSpace"
parameterType="com.lagou.domain.PromotionSpace">
UPDATE promotion_space SET NAME = #{name},updateTime = #{updateTime}
where id = #{id}
</update>
</mapper>
Service层:PromotionSpaceService
public interface PromotionSpaceService {
void savePromotionSpace(PromotionSpace promotionSpace);
void updatePromotionSpace(PromotionSpace promotionSpace);
}
@Service
public class PromotionSpaceServiceImpl implements PromotionSpaceService {
@Autowired
private PromotionSpaceMapper promotionSpaceMapper;
@Override
public void savePromotionSpace(PromotionSpace promotionSpace) {
// 封装PromotionSpace
UUID uuid = UUID.randomUUID();
promotionSpace.setSpaceKey(uuid.toString());
promotionSpace.setCreateTime(new Date());
promotionSpace.setUpdateTime(new Date());
promotionSpace.setIsDel(0);
promotionSpaceMapper.savePromotionSpace(promotionSpace);
}
@Override
public void updatePromotionSpace(PromotionSpace promotionSpace) {
promotionSpace.setUpdateTime(new Date());
promotionSpaceMapper.updatePromotionSpace(promotionSpace);
}
}
Web层:PromotionSpaceController
@RestController
@RequestMapping("/PromotionSpace")
public class PromotionSpaceController {
@Autowired
private PromotionSpaceService promotionSpaceService;
/*
添加&修改广告位
*/
@RequestMapping("/saveOrUpdatePromotionSpace")
public ResponseResult savePromotionSpace(@RequestBody PromotionSpace
promotionSpace){
try {
if(promotionSpace.getId() == null){
//新增
promotionSpaceService.savePromotionSpace(promotionSpace);
ResponseResult responseResult = new ResponseResult(true,200,"响应
成功","");
return responseResult;
}else{
//修改
promotionSpaceService.updatePromotionSpace(promotionSpace);
ResponseResult responseResult = new ResponseResult(true,200,"响应
成功","");
return responseResult;
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
Postman测试接口
3.回显广告位名称
3.1 需求分析
需求:点击编辑按钮,进行广告位信息回显
3.2 查看接口文档,进行编码
查看接口文档
Dao层:PromotionSpaceMapper
public interface PromotionSpaceMapper {
/**
* 根据id 查询广告位信息
* */
PromotionSpace findPromotionSpaceById(int id);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lagou.dao.PromotionSpaceMapper">
<select id="findPromotionSpaceById" parameterType="int"
resultType="com.lagou.domain.PromotionSpace">
SELECT id,NAME FROM promotion_space WHERE id = #{id};
</select>
</mapper>
Service层:PromotionSpaceService
public interface PromotionSpaceService {
PromotionSpace findPromotionSpaceById(int id);
}
@Service
public class PromotionSpaceServiceImpl implements PromotionSpaceService {
@Autowired
private PromotionSpaceMapper promotionSpaceMapper;
@Override
public PromotionSpace findPromotionSpaceById(int id) {
PromotionSpace promotionSpace =
promotionSpaceMapper.findPromotionSpaceById(id);
return promotionSpace;
}
}
Web层:PromotionSpaceController
@RestController
@RequestMapping("/PromotionSpace")
public class PromotionSpaceController {
@Autowired
private PromotionSpaceService promotionSpaceService;
/**
* 根据id查询 广告位信息
* */
@RequestMapping("/findPromotionSpaceById")
public ResponseResult findPromotionSpaceById(@RequestParam int id){
PromotionSpace promotionSpace =
promotionSpaceService.findPromotionSpaceById(id);
ResponseResult result = new ResponseResult(true,200,"响应成
功",promotionSpace);
return result;
}
}
4.广告分页查询
4.1 需求分析
需求:点击广告列表,对广告信息进行分页列表展示
4.2 查看接口文档,进行编码
查看接口文档
实体类:PromotionAd
public class PromotionAd {
// 标识
private Integer id;
// 广告名
private String name;
// 广告位id
private Integer spaceId;
// 精确搜索关键词
private String keyword;
// 静态广告的内容
private String htmlContent;
// 文字一
private String text;
// 链接一
private String link;
// 开始时间
private Date startTime;
// 结束时间
private Date endTime;
private Integer status;
private Date createTime;
private Date updateTime;
// 优先级
private Integer priority;
private String img;
getter/setter..
}
PromotionAdVo
public class PromotionAdVo {
private Integer currentPage = 1;
private Integer pageSize = 10;
public Integer getCurrentPage() {
return currentPage;
}
public void setCurrentPage(Integer currentPage) {
this.currentPage = currentPage;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
}
Dao层:PromotionAdMapper
public interface PromotionAdMapper {
/*
分页获取所有的广告列表
*/
public List<PromotionAd> findAllAdByPage();
}
<mapper namespace="com.lagou.dao.PromotionAdMapper">
<resultMap id="ad_space" type="com.lagou.domain.PromotionAd">
<id property="id" column="id"></id>
<result property="name" column="name"/>
<result property="spaceId" column="spaceId"/>
<result property="keyword" column="keyword"/>
<result property="htmlContent" column="htmlContent"/>
<result property="text" column="text"/>
<result property="link" column="link"/>
<result property="startTime" column="startTime"/>
<result property="endTime" column="endTime"/>
<result property="createTime" column="createTime"/>
<result property="updateTime" column="updateTime"/>
<result property="status" column="status"/>
<result property="priority" column="priority"/>
<result property="img" column="img"/>
<association property="promotionSpace"
select="com.lagou.dao.PromotionSpaceMapper.findPromotionSpaceById"
column="spaceId" javaType="com.lagou.domain.PromotionSpace"></association>
</resultMap>
<!--分页查询广告信息-->
<select id="findAllPromotionAdByPage" resultMap="ad_space">
select * from promotion_ad
</select>
</mapper>
Service层:PromotionAdService
applicationContext.xml
<!--2.sqlSessionFactory-->
<bean id="sqlSessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="typeAliasesPackage" value="com.lagou.domain"/>
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageHelper">
<property name="properties">
<value>helperDialect=mysql</value>
</property>
</bean>
</array>
</property>
<!--引入加载mybatis核心配置文件-->
<property name="configLocation" value="classpath:sqlMapConfig.xml">
</property>
</bean>
public interface PromotionAdService {
/*
分页获取所有的广告列表
*/
public PageInfo findAllAdByPage(PromotionAdVo adVo);
}
@Service
public class PromotionAdServiceImpl implements PromotionAdService {
@Autowired
private PromotionAdMapper adMapper;
@Override
public PageInfo findAllAdByPage(PromotionAdVo adVo) {
PageHelper.startPage(adVo.getCurrentPage(),adVo.getPageSize());
List<PromotionAd> allAd = adMapper.findAllAdByPage();
PageInfo<PromotionAd> adPageInfo = new PageInfo<>(allAd);
return adPageInfo;
}
}
Web层:PromotionAdController
@RestController
@RequestMapping("/PromotionAd")
public class PromotionAdController {
@Autowired
private PromotionAdService adService;
/*
分页查询所有广告信息
*/
@RequestMapping("/findAllPromotionAd")
public ResponseResult findAllAdByPage(PromotionAdVo adVo) {
PageInfo allAdByPage = adService.findAllAdByPage(adVo);
ResponseResult responseResult = new ResponseResult(true, 200, "响应成功",
allAdByPage);
return responseResult;
}
}
Postman测试接口
5.图片上传接口
5.1 需求分析
需求:添加广告页面,点击上传按钮,需完成图片上传
5.2 查看接口文档,进行编码
查看接口文档
Web层:PromotionAdController
@RestController
@RequestMapping("/PromotionSpace")
public class PromotionSpaceController {
@Autowired
private PromotionSpaceService promotionSpaceService;
/*
文件上传
*/
@RequestMapping("/PromotionAdUpload")
public ResponseResult fileupload(@RequestParam("file") MultipartFile file,
HttpServletRequest request) throws IOException {
try {
//1.判断文件是否为空
if (file.isEmpty()) {
throw new RuntimeException();
}
//2.获取项目部署路径
String realPath = request.getServletContext().getRealPath("/");
String webappsPath = realPath.substring(0,
realPath.indexOf("ssm_web"));
//3.获取原文件名
String fileName = file.getOriginalFilename();
//4.新文件名
String newFileName = System.currentTimeMillis() +
fileName.substring(fileName.lastIndexOf("."));
//5.上传文件
String uploadPath = webappsPath + "upload\\";
File filePath = new File(uploadPath, newFileName);
//如果目录不存在就创建目录
if (!filePath.getParentFile().exists()) {
filePath.getParentFile().mkdirs();
System.out.println("创建目录: " + filePath);
}
file.transferTo(filePath);
//6.将文件名和文件路径返回
Map<String, String> map = new HashMap<>();
map.put("fileName", newFileName);
map.put("filePath", LOCAL_URL + "/upload/" + newFileName);
ResponseResult result = new ResponseResult(true, 200, "响应成功",
map);
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
Postman测试接口
6.新建&修改广告(自行完成)
6.1 需求分析
新建需求:点击提交按钮,将页面内容保存到数据库
修改需求:点击编辑按钮,由前端实现数据回显,在回显页面进行数据修改,将修改后值更新到数据库中
6.2 查看接口文档,进行编码
查看接口文档
Dao层:PromotionAdMapper
public interface PromotionAdMapper {
void savePromotionAd(PromotionAd promotionAd);
void updatePromotionAd(PromotionAd promotionAd);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lagou.dao.PromotionAdMapper">
<!--添加广告-->
<insert id="savePromotionAd" parameterType="com.lagou.domain.PromotionAd" >
INSERT INTO promotion_ad VALUES(NULL,#{name},#{spaceId},#{keyword},#{htmlContent},#{text},#{link},
#{startTime},#{endTime},#{createTime},#{updateTime},#{status},#{priority},#{img});
</insert>
<!--更新广告-->
<update id="updatePromotionAd" parameterType="com.lagou.domain.PromotionAd"
>
update promotion_ad
<trim prefix="SET" suffixOverrides=",">
<if test="name != null and name != ''">
name = #{name},
</if>
<if test="spaceId != null and spaceId != ''">
spaceId = #{spaceId},
</if>
<if test="link != null">
link=#{link},
</if>
<if test="status != null and status != '' or status == 0">
status=#{status},
</if>
<if test="img != null">
img=#{img},
</if>
<if test="text != null">
text=#{text},
</if>
<if test="startTime != null">
startTime=#{startTime},
</if>
<if test="endTime != null">
endTime=#{endTime},
</if>
<if test="updateTime != null">
updateTime=#{updateTime},
</if>
</trim>
<where>
<if test="id != null and id != '' ">id = #{id}</if>
</where>
</update>
</mapper>
Service层:PromotionAdService
public interface PromotionAdService {
void savePromotionAd(PromotionAd promotionAd);
void updatePromotionAd(PromotionAd promotionAd);
}
@Service
public class PromotionAdServiceImpl implements PromotionAdService {
@Autowired
private PromotionAdMapper adMapper;
@Override
public void savePromotionAd(PromotionAd promotionAd) {
adMapper.savePromotionAd(promotionAd);
}
@Override
public void updatePromotionAd(PromotionAd promotionAd) {
adMapper.updatePromotionAd(promotionAd);
}
}
Web层:PromotionAdController
@RestController
@RequestMapping("/PromotionAd")
public class PromotionAdController {
@Autowired
private PromotionAdService adService;
/*
新增或更新广告位置
*/
@RequestMapping("/saveOrUpdatePromotionAd")
public ResponseResult saveOrUpdatePromotionAd(@RequestBody PromotionAd
promotionAd) {
try {
if (promotionAd.getId() == null) {
Date date = new Date();
promotionAd.setCreateTime(date);
promotionAd.setUpdateTime(date);
adService.savePromotionAd(promotionAd);
ResponseResult result = new ResponseResult(true, 200, "响应成功",
null);
return result;
} else {
Date date = new Date();
promotionAd.setUpdateTime(date);
adService.updatePromotionAd(promotionAd);
ResponseResult result = new ResponseResult(true, 200, "响应成功",
null);
return result;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
Postman测试接口
7.回显广告信息(自行完成)
7.1 需求分析
需求:点击编辑按钮,进行广告位名称回显
7.2 查看接口文档,进行编码
查看接口文档
Dao层:PromotionAdMapper
public interface PromotionAdMapper {
/**
* 根据id查询广告信息
* */
PromotionAd findPromotionAdById(int id);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lagou.dao.PromotionAdMapper">
<!-- 根据id查询广告信息 -->
<select id="findPromotionAdById" parameterType="int"
resultType="com.lagou.domain.PromotionAd">
SELECT
id,
NAME,
spaceId,
startTime,
endTime,
STATUS,
img,
link,
TEXT
FROM promotion_ad WHERE id = #{id}
</select>
</mapper>
Service层:PromotionAdService
public interface PromotionAdService {
/*
回显广告信息
*/
PromotionAd findPromotionAdById(int id);
}
@Service
public class PromotionSpaceServiceImpl implements PromotionSpaceService {
@Autowired
private PromotionAdMapper adMapper;
@Override
public PromotionAd findPromotionAdById(int id) {
PromotionAd promotionAd = adMapper.findPromotionAdById(id);
return promotionAd;
}
}
Web层:PromotionAdController
@RestController
@RequestMapping("/PromotionAd")
public class PromotionAdController {
@Autowired
private PromotionAdService adService;
/**
* 根据id回显 广告数据
* */
@RequestMapping("/findPromotionAdById")
public ResponseResult findPromotionAdById(@RequestParam int id){
try {
PromotionAd promotionAd = adService.findPromotionAdById(id);
ResponseResult result = new ResponseResult(true,200,"响应成
功",promotionAd);
return result;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
Postman测试接口
8.广告状态上下线
8.1 需求分析
需求:点击按钮,实现状态的动态上下线
8.2 查看接口文档,进行编码
查看接口文档
Dao层:PromotionSpaceMapper
public interface PromotionAdMapper {
void updatePromotionAdStatus(PromotionAd promotionAd);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lagou.dao.PromotionAdMapper">
<!--void updatePromotionAdStatus(PromotionAd promotionAd);-->
<update id="updatePromotionAdStatus" parameterType="com.soldier.domian.PromotionAd">
UPDATE promotion_ad SET STATUS = #{status} ,updatetime = #{updateTime} WHERE id = #{id}
</update>
</mapper>
Service层:PromotionAdService
public interface PromotionSpaceService {
void updatePromotionAdStatus(int id, int status);
}
@Service
public class PromotionSpaceServiceImpl implements PromotionSpaceService {
@Autowired
private PromotionAdMapper adMapper;
@Override
public void updatePromotionAdStatus(int id, int status) {
PromotionAd promotionAd = new PromotionAd();
promotionAd.setId(id);
promotionAd.setStatus(status);
promotionAd.setUpdateTime(new Date());
adMapper.updatePromotionAdStatus(promotionAd);
}
}
Web层:PromotionAdController
@RestController
@RequestMapping("/PromotionAd")
public class PromotionAdController {
@Autowired
private PromotionAdService adService;
/*
广告位置上下线
*/
@RequestMapping("/updatePromotionAdStatus")
public ResponseResult updateCourseStatus(@RequestParam int id, @RequestParam
int status) {
try {
//执行修改操作
if (status == 1) {
adService.updatePromotionAdStatus(id, status);
} else {
adService.updatePromotionAdStatus(id, 0);
}
//保存修改后的状态,并返回
Map<String, Integer> map = new HashMap<>();
map.put("status", status);
ResponseResult result = new ResponseResult(true, 200, "响应成功",
map);
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
Postman测试接口
任务三:用户模块
一 用户模块功能分析
在任务二中,再来完成拉勾教育后台管理系统的用户管理模块, 广告管理模块包含了用户分页&条件查询、用户状态设置,(登陆、权限控制)等接口的编写
1.1 用户模块
- 实现以下功能:
- 登陆(权限模块)
- 权限控制(权限模块)
- 用户分页&条件查询
- 用户状态设置
- 分配角色(权限模块)
二 用户管理模块表设计
2.1 创建数据库及表
在资料中找到 ssm_lagou_edu.sql,使用SQLYog 执行SQL脚本 ,导入表结构及表信息
2.2 表关系介绍
1.ER图
三 用户管理模块接口实现
1.用户分页&条件查询
1.1 需求分析
需求:实现多条件分页组合查询
2.2 查看接口文档,进行编码
查看接口文档
UserVo
public class UserVo {
private Integer currentPage;
private Integer pageSize;
private String username;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date startCreateTime;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date endCreateTime;
public Integer getCurrentPage() {
return currentPage;
}
public void setCurrentPage(Integer currentPage) {
this.currentPage = currentPage;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getStartCreateTime() {
return startCreateTime;
}
public void setStartCreateTime(Date startCreateTime) {
this.startCreateTime = startCreateTime;
}
public Date getEndCreateTime() {
return endCreateTime;
}
public void setEndCreateTime(Date endCreateTime) {
this.endCreateTime = endCreateTime;
}
}
Dao层:UserMapper
public interface UserMapper {
/*
查询所有用户
*/
public List<User> findAllUserByPage(UserVo userVo);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lagou.dao.UserMapper">
<!--查询所有用户-->
<select id="findAllUserByPage" resultType="com.lagou.domain.User">
SELECT
id,
NAME,
portrait,
phone,
PASSWORD,
STATUS,
create_time
FROM USER
<where>
<if test="true">
and is_del != 1
</if>
<if test="username != null">
and name = #{username}
</if>
<if test="startCreateTime != null and endCreateTime != null">
and create_time BETWEEN #{startCreateTime} AND #{endCreateTime}
</if>
</where>
</select>
</mapper>
Service层:UserService
public interface UserService {
/*
查询所有用户
*/
public PageInfo findAllUserByPage(UserVo userVo);
}
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public PageInfo findAllUserByPage(UserVo userVo) {
// 使用pageHelper
PageHelper.startPage(userVo.getCurrentPage(),userVo.getPageSize());
List<User> allUser = userMapper.findAllUser(userVo);
PageInfo<User> pageInfo = new PageInfo<User>(allUser);
System.out.println("总条数:"+pageInfo.getTotal());
System.out.println("总页数:"+pageInfo.getPages());
System.out.println("当前页:"+pageInfo.getPageNum());
System.out.println("每页显示长度:"+pageInfo.getPageSize());
System.out.println("是否第一页:"+pageInfo.isIsFirstPage());
System.out.println("是否最后一页:"+pageInfo.isIsLastPage());
return pageInfo;
}
}
Web层:UserController
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/findAllUserByPage")
public ResponseResult findAllUserByPage(@RequestBody UserVo userVo){
PageInfo pageInfo = userService.findAllUserByPage(userVo);
ResponseResult responseResult = new ResponseResult(true,200,"响应成功",pageInfo);
List<User> list = pageInfo.getList();
System.out.println(list);
return responseResult;
}
}
Postman测试接口
2.用户状态设置(自行完成)
2.1 需求分析
点击禁用,实现用户的状态变更
用户状态:ENABLE能登录,DISABLE不能登录
2.2 查看接口文档,进行编码
查看接口文档
Dao层:UserMapper
public interface UserMapper {
/**
* 修改用户状态
* */
public void updateUserStatus(@Param("id") int id,@Param("status") String
status);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lagou.dao.UserMapper">
<!-- 修改用户状态 -->
<update id="updateUserStatus">
UPDATE USER SET STATUS = #{status} where id = #{id};
</update>
</mapper>
Service层:UserService
public interface UserService {
/*
* 修改用户状态
* */
public void updateUserStatus(int id, String status);
}
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public void updateUserStatus(int id, String status) {
userMapper.updateUserStatus(id,status);
}
}
Web层:UserController
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
/**
* 修改用户状态
* ENABLE能登录,DISABLE不能登录
* */
@RequestMapping("/updateUserStatus")
public ResponseResult updateUserStatus(@RequestParam int id ,@RequestParam
String status){
if("ENABLE".equalsIgnoreCase(status)){
status = "DISABLE";
}else{
status = "ENABLE";
}
userService.updateUserStatus(id,status);
ResponseResult responseResult = new ResponseResult(true,200,"响应成
功",status);
return responseResult;
}
}
Postman测试接口
任务四:权限模块
一 权限概念介绍
权限:权利(能做的)和限制(不能做的),在权限范围内做好自己的事情,不该看的不看,不该做的不做
认证: 验证用户名密码是否正确的过程
授权: 对用户所能访问的资源进行控制(动态显示菜单、url级别的权限控制)
为什么要实现权限系统
首先系统需要进行登陆才能访问
其次不同登陆用户要有不同的权利,而且要有不同的菜单(例如财务经理针对系统中财务相关模块进行操作,人事经理针对系统中人事模块进行操作)
权限控制基本原理
1.ACL(Access Control Lists,缩写ACL)
ACL是最早也是最基本的一种访问控制机制,它的原理非常简单:每一项资源,都配有一个列表,这个列表记录的就是哪些用户可以对这项资源执行CRUD中的那些操作。当系统试图访问这项资源时,会首先检查这个列表中是否有关于当前用户的访问权限,从而确定当前用户可否执行相应的操作。总得来说,ACL是一种面向资源的访问控制模型,它的机制是围绕“资源”展开的。
2.基于角色的访问控制RBAC(Role-Based Access Control)
RBAC是把用户按角色进行归类,通过用户的角色来确定用户能否针对某项资源进行某项操作。
RBAC相对于ACL最大的优势就是它简化了用户与权限的管理,通过对用户进行分类,使得角色与权限关联起来,而用户与权限变成了间接关联。RBAC模型使得访问控制,特别是对用户的授权管理变得非常简单和易于维护,因此有广泛的应用
规则一:每个登陆的用户,可以有多个角色;
规则二:每个角色又可以拥有多个权限(包含菜单和资源);
二 权限模块功能分析
权限模块主要细分为角色模块、菜单模块、资源模块,将针对细分的三个模块进行具体功能实现,同时会完成用户登陆、用户关联角色及动态菜单显示
2.1 权限模块管理
- 实现以下功能:
- 角色列表&条件查询(角色模块)
- 分配菜单(角色模块)
- 删除角色(角色模块)
- 菜单列表查询(菜单模块)
- 查询菜单信息回显(菜单模块)
- 资源分页&多条件查询(资源模块)
- 用户登陆(用户模块)
- 动态菜单展示(权限模块)
- 用户关联角色(用户模块)
三 权限管理模块表设计
3.1 创建数据库及表
在资料中找到 ssm_lagou_edu.sql,使用SQLYog 执行SQL脚本 ,导入表结构及表信息
3.2 表关系介绍
1.ER图
2.数据实体描述
2.1 菜单表(menu)
2.2 资源类表(resource_category)
2.3 资源表(resource)
2.4 角色表(roles)
2.5 用户-角色关系表(user_role_relation)
2.6 角色-菜单关系表(role_menu_relation)
2.7 角色-资源关系表(role_resource_relation)
四 权限管理(角色模块)接口实现
1.角色列表查询&条件查询
1.1 需求分析
需求:点击角色列表按钮进行角色列表展示
1.2 查看接口文档,进行编码
查看接口文档
实体类:Role
public class Role {
private Integer id;
private String code;
private String name;
private String description;
private Date createdTime;
private Date updatedTime;
private String createdBy;
private String updatedBy;
//getter/setter...
}
Dao层:RoleMapper
public interface RoleMapper {
/*
查询角色列表(条件)
*/
public List<Role> findAllRole(Role role);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lagou.dao.RoleMapper">
<!--查询所有角色(条件)-->
<select id="findAllRole" resultType="com.lagou.domain.Role">
SELECT
id,
CODE,
NAME,
description,
created_time,
updated_time,
created_by,
updated_by
FROM roles
<where>
<if test="name != null and name != ''">
and name = #{name}
</if>
</where>
</select>
</mapper>
Service层:RoleService
public interface RoleService {
public List<Role> findAllRole(Role role);
}
@Service
public class RoleServiceImpl implements RoleService {
@Autowired
private RoleMapper roleMapper;
@Override
public List<Role> findAllRole(Role role) {
List<Role> allRole = roleMapper.findAllRole(role);
return allRole;
}
}
Web层:RoleController
@RestController
@RequestMapping("/role")
public class RoleController {
@Autowired
private RoleService roleService;
@RequestMapping("/findAllRole")
public ResponseResult findAllUserByPage(@RequestBody Role role){
List<Role> allRole = roleService.findAllRole(role);
ResponseResult responseResult = new ResponseResult(true,200,"响应成
功",allRole);
return responseResult;
}
}
Postman测试接口
2.分配菜单
2.1 需求分析
需求:点击分配菜单,回显可选择菜单信息,并回显选中状态
2.2 接口1 查询所有菜单列表
查看接口文档
Dao层:MenuMapper
public interface MenuMapper {
/**
* 查询全部的父子菜单信息
* */
public List<Menu> findSubMenuListByPid(int pid);
}
<!-- 一对多: 查找子孙菜单 -->
<select id="findSubMenuListByPid" resultMap="MenuResult">
select * from menu where parent_id = #{pid}
</select>
<!-- 根据pid 查询所有子分类集合 -->
<resultMap id="MenuResult" type="com.lagou.domain.Menu">
<id column="id" property="id"></id>
<result column="href" property="href"></result>
<result column="icon" property="icon"></result>
<result column="name" property="name"></result>
<result column="parent_id" property="parentId"></result>
<result column="description" property="description"></result>
<result column="orderNum" property="order_num"></result>
<result column="shown" property="shown"></result>
<result column="created_time" property="createdTime"></result>
<result column="updated_time" property="updatedTime"></result>
<result column="created_by" property="createdBy"></result>
<result column="updated_by" property="updatedBy"></result>
<collection property="subMenuList" ofType="com.lagou.domain.Menu"
select="findSubMenuListByPid" column="id" ></collection>
</resultMap>
Service层:MenuService
public interface MenuService {
public List<Menu> findSubMenuListByPid(int pid);
}
@Service
public class MenuServiceImpl implements MenuService {
@Autowired
private MenuMapper menuMapper;
@Override
public List<Menu> findSubMenuListByPid(int pid) {
List<Menu> menuList = menuMapper.findSubMenuListByPid(pid);
return menuList;
}
}
Web层:RoleController
@RestController
@RequestMapping("/role")
public class RoleController {
@Autowired
private MenuService menuService;
/*
查询所有菜单信息
*/
@RequestMapping("/findAllMenu")
public ResponseResult findAllMenu(){
//-1 表示查询所有菜单数据
List<Menu> menuList = menuService.findSubMenuListByPid(-1);
Map<String,Object> map = new HashMap<>();
map.put("parentMenuList",menuList);
ResponseResult result = new ResponseResult(true,200,"响应成功",map);
return result;
}
}
Postman测试接口
2.3 接口2 根据角色ID查询关联菜单ID
Dao层:RoleMapperr
public interface RoleMapper {
/*
根据角色ID查询菜单信息
*/
List<String> findMenuByRoleId(Integer roleId);
}
<mapper namespace="com.lagou.dao.RoleMapper">
<!-- List<String> findMenuByRoleId(Integer roleId);-->
<select id="findMenuByRoleId" parameterType="int" resultType="string">
SELECT m.ìd`FROM roles r LEFT JOIN role_menu_relation rm ON r.id =
rm.`role_id`LEFT JOIN menu m ON rm.`menu_id` = m.ìd` WHERE r.id = #{id}
</select>
Service层:RoleService
public interface RoleService {
/**
* 根据ID查询角色关联菜单
* */
List<String> findMenuByRoleId(Integer roleId);
}
@Service
public class RoleServiceImpl implements RoleService {
@Autowired
private RoleMapper roleMapper;
@Override
public List<String> findMenuByRoleId(Integer roleId) {
List<String> list = roleMapper.findMenuByRoleId(roleId);
return list;
}
}
Web层:RoleController
/**
* 查询角色关联菜单列表ID
* */
@RequestMapping("/findMenuByRoleId")
public ResponseResult findMenuByRoleId(Integer roleId){
List<String> menuList = roleService.findMenuByRoleId(roleId);
ResponseResult result = new ResponseResult(true,200,"响应成功",menuList);
return result;
}
Postman测试接口
2.4 接口3 为角色分配菜单列表
Dao层:RoleMapper
public interface RoleMapper {
/*
角色菜单关联
*/
void RoleContextMenu(Role_menu_relation role_menu_relation);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lagou.dao.RoleMapper">
<!--删除角色菜单关联信息-->
<delete id="deleteRoleContextMenu" parameterType="int">
delete from role_menu_relation where role_id = #{id}
</delete>
<!--角色菜单关联-->
<insert id="RoleContextMenu"
parameterType="com.lagou.domain.Role_menu_relation">
insert into role_menu_relation values(null,#{menuId},#{roleId},#
{createdTime},#{updatedTime},#{createdBy},#{updatedby})
</insert>
</mapper>
Service层:RoleService
public interface RoleService {
void RoleContextMenu(RoleMenuVo roleMenuVo);
}
@Service
public class RoleServiceImpl implements RoleService {
@Override
public void RoleContextMenu(RoleMenuVo roleMenuVo) {
// 清空中间表
roleMapper.deleteRoleContextMenu(roleMenuVo.getRoleId());
for (Integer mid : roleMenuVo.getMenuIdList()) {
Role_menu_relation role_menu_relation = new Role_menu_relation();
role_menu_relation.setRoleId(roleMenuVo.getRoleId());
role_menu_relation.setMenuId(mid);
role_menu_relation.setCreatedTime(new Date());
role_menu_relation.setUpdatedTime(new Date());
role_menu_relation.setCreatedBy("system");
role_menu_relation.setUpdatedby("system");
roleMapper.RoleContextMenu(role_menu_relation);
}
}
}
Web层:RoleController
@RestController
@RequestMapping("/role")
public class RoleController {
@Autowired
private RoleService roleService;
/*
用户关联菜单 {roleId: 4, menuIdList: [19, 20, 7, 8, 9, 15, 16, 17, 18]}
*/
@RequestMapping("/RoleContextMenu")
public ResponseResult RoleContextMenu(@RequestBody RoleMenuVo roleMenuVo){
roleService.RoleContextMenu(roleMenuVo);
ResponseResult result = new ResponseResult(true,200,"响应成功","");
return result;
}
}
Postman测试接口
3.删除角色
3.1 需求分析
需求:点击删除按钮,将选中的角色信息删除
3.2 查看接口文档,进行编码
查看接口文档
Dao层:RoleMapper
public interface RoleMapper {
/*
删除角色
*/
void deleteRole(Integer id);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lagou.dao.RoleMapper">
<delete id="deleteRole" parameterType="int">
delete from roles where id = #{id}
</delete>
</mapper>
Service层:RoleService
public interface RoleService {
void deleteRole(Integer id);
}
@Service
public class RoleServiceImpl implements RoleService {
@Autowired
private RoleMapper roleMapper;
@Override
public void deleteRole(Integer id) {
// 清空中间表
roleMapper.deleteRoleContextMenu(id);
roleMapper.deleteRole(id);
}
}
Web层:RoleController
@RestController
@RequestMapping("/role")
public class RoleController {
@Autowired
private RoleService roleService;
/**
* 删除角色
* */
@RequestMapping("/deleteRole")
public ResponseResult deleteRole(Integer id){
roleService.deleteRole(id);
ResponseResult responseResult = new ResponseResult(true,200,"响应成
功","");
return responseResult;
}
}
Postman测试接口
五 权限管理(菜单模块)接口实现
1.菜单列表查询
1.1 需求分析
需求:点击菜单列表,对菜单信息进行列表展示
1.2 查看接口文档,进行编码
查看接口文档
实体类:Menu
public class Menu {
//主键id
private Integer id;
//父菜单id
private int parentId;
//菜单路径
private String href;
//菜单图标
private String icon;
//菜单名称
private String name;
//描述
private String description;
//排序号
private int orderNum;
//是否展示
private int shown;
//菜单层级,从0开始
private int level;
//创建时间
private Date createdTime;
//更新时间
private Date updatedTime;
//创建人
private String createdBy;
//更新人
private String updatedBy;
// getter/setter..
}
Dao层:MenuMapper
public interface MenuMapper {
/**
* 查询菜单列表
* */
public List<Menu> findAllMenu();
}
<mapper namespace="com.lagou.dao.MenuMapper">
<!-- 查询菜单列表 -->
<select id="findAllMenu" resultType="com.lagou.domain.Menu">
SELECT
id,
parent_id,
href,
icon,
NAME,
description,
order_num,
shown,
LEVEL,
created_time,
updated_time,
created_by,
updated_by
FROM menu
</select>
</mapper>
Service层:MenuService
public interface MenuService {
public List<Menu> findAllMenu();
}
@Service
public class MenuServiceImpl implements MenuService {
@Autowired
private MenuMapper menuMapper;
@Override
public List<Menu> findAllMenu() {
List<Menu> list = menuMapper.findAllMenu();
return list;
}
Web层:MenuController
@RestController
@RequestMapping("/menu")
public class MenuController {
@Autowired
private MenuService menuService;
/**
* 查询菜单列表信息
* */
@RequestMapping("/findAllMenu")
public ResponseResult findAllMenu(){
List<Menu> list = menuService.findAllMenu();
ResponseResult result = new ResponseResult(true,200,"响应成功",list);
return result;
}
}
Postman测试接口
2.查询菜单信息(回显)
2.1 需求分析
需求:点击添加菜单按钮,跳转到添加菜单页面,回显当前添加菜单可以选择的上级菜单信息
2.2 查看接口文档,进行编码
查看接口文档
Dao层:MenuMapper
public interface MenuMapper {
/**
* 查询全部的父子菜单信息
* */
public List<Menu> findSubMenuListByPid(int pid);
}
<mapper namespace="com.lagou.dao.MenuMapper">
<!-- 一对多: 查找子孙菜单 -->
<select id="findSubMenuListByPid" resultMap="MenuResult">
select * from menu where parent_id = #{pid}
</select>
<!-- 根据pid 查询所有子分类集合 -->
<resultMap id="MenuResult" type="com.lagou.domain.Menu">
<id column="id" property="id"></id>
<result column="href" property="href"></result>
<result column="icon" property="icon"></result>
<result column="name" property="name"></result>
<result column="parent_id" property="parentId"></result>
<result column="description" property="description"></result>
<result column="orderNum" property="order_num"></result>
<result column="shown" property="shown"></result>
<result column="created_time" property="createdTime"></result>
<result column="updated_time" property="updatedTime"></result>
<result column="created_by" property="createdBy"></result>
<result column="updated_by" property="updatedBy"></result>
<collection property="subMenuList" ofType="com.lagou.domain.Menu"
select="findSubMenuListByPid" column="id" ></collection>
</resultMap>
</mapper>
Service层:MenuService
public interface MenuService {
public List<Menu> findSubMenuListByPid(int pid);
}
@Service
public class MenuServiceImpl implements MenuService {
@Autowired
private MenuMapper menuMapper;
@Override
public List<Menu> findSubMenuListByPid(int pid) {
List<Menu> menuList = menuMapper.findSubMenuListByPid(pid);
return menuList;
}
}
Web层:MenuController
@RestController
@RequestMapping("/menu")
public class MenuController {
@Autowired
private MenuService menuService;
/**
* 回显菜单信息(包括父子菜单的全部信息)
* */
@RequestMapping("/findMenuInfoById")
public ResponseResult findMenuInfoById(@RequestParam int id){
if(id == -1){
//添加操作 回显不需要查询 menu信息
List<Menu> menuList = menuService.findSubMenuListByPid(-1);
//封装数据
Map<String,Object> map = new HashMap<>();
map.put("menuInfo",null);
map.put("parentMenuList",menuList);
ResponseResult result = new ResponseResult(true,200,"响应成功",map);
return result;
}else{
//修改操作 回显
Menu menu = menuService.findMenuById(id);
List<Menu> menuList = menuService.findSubMenuListByPid(-1);
Map<String,Object> map = new HashMap<>();
map.put("menuInfo",menu);
map.put("parentMenuList",menuList);
ResponseResult result = new ResponseResult(true,200,"响应成功",map);
return result;
}
}
}
Postman测试接口
六 权限管理(资源模块)接口实现
1.资源分页&多条件查询
1.1 需求分析
需求:资源列表及多条件组合查询
1.2 查看接口文档,进行编码
查看接口文档
Dao层:ResourceMapper
public interface ResourceMapper {
public List<Resource> findAllResource(ResourceVo resourceVo);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lagou.dao.ResourceMapper">
<!--查询所有资源-->
<select id="findAllResource" resultType="com.lagou.domain.Resource">
select * from resource
<where>
<if test="name != null">
and name like concat('%',#{name},'%')
</if>
<if test="url != null">
and url = url
</if>
<if test="categoryId != null">
and category_id = #{categoryId}
</if>
</where>
</select>
</mapper>
Service层:ResourceService
public interface ResourceService {
public PageInfo<Resource> findAllResource(ResourceVo resourceVo);
}
@Service
public class ResourceServiceImpl implements ResourceService {
@Autowired
private ResourceMapper resourceMapper;
@Override
public PageInfo<Resource> findAllResource(ResourceVo resourceVo) {
PageHelper.startPage(resourceVo.getCurrentPage(),resourceVo.getPageSize());
List<Resource> allResource = resourceMapper.findAllResource(resourceVo);
PageInfo<Resource> adPageInfo = new PageInfo<Resource>(allResource);
return adPageInfo;
}
Web层:ResourceController
@RestController
@RequestMapping("/resource")
public class ResourceController {
@Autowired
private ResourceService resourceService;
/**
* 分页与条件查询
* */
@RequestMapping("/findAllResource")
public ResponseResult findAllResource(@RequestBody ResourceVo resourceVo){
PageInfo<Resource> allResource =
resourceService.findAllResource(resourceVo);
ResponseResult responseResult = new ResponseResult(true,200,"响应成
功",allResource);
return responseResult;
}
}
Postman测试接口
七 登陆及动态菜单展示
1.登陆
1.1 需求分析
需求:输入用户名密码,点击登陆按钮,进行用户登陆
加密算法MD5介绍
1、什么是MD5
MD5加密全程是Message-Digest Algoorithm 5(信息-摘要算法),它对信息进行摘要采集,再通过一定的位运算,最终获取加密后的MD5字符串。
2、MD5有哪些特点
MD5加密的特点主要有以下几点:
1、针对不同长度待加密的数据、字符串等等,其都可以返回一个固定长度的MD5加密字符串。(通常32位的16进制字符串)
2、其加密过程几乎不可逆,除非维护一个庞大的Key-Value数据库来进行碰撞破解,否则几乎无法解开。
3、运算简便,且可实现方式多样,通过一定的处理方式也可以避免碰撞算法的破解。(加盐:随机字符串)
4、对于一个固定的字符串。数字等等,MD5加密后的字符串是固定的,也就是说不管MD5加密多少次,都是同样的结果。
3、Java代码中如何使用MD5
(1)添加依赖
<!--MD5依赖-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.3</version>
</dependency>
(2)添加工具类
public class Md5 {
public final static String md5key = "Ms2";
/**
* MD5方法
* @param text 明文
* @param key 密钥
* @return 密文
* @throws Exception
*/
public static String md5(String text, String key) throws Exception {
//加密后的字符串
String encodeStr= DigestUtils.md5Hex(text+key);
System.out.println("MD5加密后的字符串为:encodeStr="+encodeStr);
return encodeStr;
}
/**
* MD5验证方法
* @param text 明文
* @param key 密钥
* @param md5 密文
* @return true/false
* @throws Exception
*/
public static boolean verify(String text, String key, String md5) throws
Exception {
//根据传入的密钥进行验证
String md5Text = md5(text, key);
if(md5Text.equalsIgnoreCase(md5))
{
System.out.println("MD5验证通过");
return true;
}
return false;
}
public static void main(String[] args) throws Exception {
// 注册 用户名:tom 密码 123456
// 添加用户的时候,要进行加密
String lagou = Md5.md5("123456", "lagou");
System.out.println(lagou);
// 登陆 用户名 tom 123456 select * from user where username = tom and
password = 123456
// 1.根据用户名进行查询 f00485441dfb815c75a13f3c3389c0b9
boolean verify = Md5.verify("123456", "lagou",
"f00485441dfb815c75a13f3c3389c0b9");
System.out.println(verify);
}
}
1.2 查看接口文档,进行编码
查看接口文档
Dao层:UserMapper
public interface UserMapper {
/*
用户登陆
*/
public User login(User user);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lagou.dao.UserMapper">
<!-- 用户登陆 -->
<select id="login" parameterType="com.lagou.domain.User"
resultType="com.lagou.domain.User">
select * from user where phone = #{phone}
</select>
</mapper>
Service层:UserService
public interface UserService {
/*
用户登录
*/
public User login(User user);
}
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
/**
* 用户登录
* */
@Override
public User login(User user) throws Exception {
User user2 = userMapper.login(user);
if(user2 != null &&
Md5.verify(user.getPassword(),"lagou",user2.getPassword())){
return user2;
}else {
return null;
}
}
}
Web层:UserControlle
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
/**
* 用户登录
* */
@RequestMapping("/login")
public ResponseResult login(User user, HttpServletRequest request) throws
Exception {
User login = userService.login(user);
ResponseResult result = null;
if(login !=null ){
//保存access_token
Map<String,Object> map = new HashMap<>();
String access_token = UUID.randomUUID().toString();
map.put("access_token", access_token);
map.put("user_id",login.getId());
HttpSession session = request.getSession();
session.setAttribute("user_id",login.getId());
session.setAttribute("access_token",access_token);
result = new ResponseResult(true,1,"响应成功",map);
}else{
result = new ResponseResult(true,1,"用户名密码错误",null);
}
return result;
}
}
Postman测试接口
2.分配角色(回显)
2.1 需求分析
需求:点击分配角色,将该用户所具有的角色信息进行回显
2.2 查看接口文档,进行编码
查看接口文档
Dao层:UserMapper
public interface UserMapper {
/**
* 根据ID查询用户当前角色
* */
public List<Role> findUserRelationRoleById(int id);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lagou.dao.UserMapper">
<!-- 根据ID查询用户当前角色 -->
<select id="findUserRelationRoleById" resultType="com.lagou.domain.Role"
parameterType="int">
SELECT
r.id,
r.code,
r.name,
r.description
FROM roles r INNER JOIN user_role_relation ur
ON r.ìd` = ur.`role_idÌNNER JOIN USER u ON ur.ùser_id` = u.ìd`
WHERE u.ìd` = #{id}
</select>
</mapper>
Service层:UserService
public interface UserService {
/**
* 获取用户拥有的角色
* */
public List<Role> findUserRelationRoleById(int id) ;
}
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
/**
* 获取用户拥有的角色
* */
@Override
public List<Role> findUserRelationRoleById(int id) {
List<Role> roleList = userMapper.findUserRelationRoleById(id);
return roleList;
}
}
Web层:UserController
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
/*
获取用户拥有的角色
*/
@RequestMapping("/findUserRoleById")
public ResponseResult findUserRoleById(int id){
List<Role> roleList = userService.findUserRelationRoleById(id);
return new ResponseResult(true,200,"分配角色回显成功",roleList);
}
}
Postman测试接口
3分配角色
3.1 需求分析
需求:点击确定按钮,真正实现用户角色关联
3.2 查看接口文档,进行编码
查看接口文档
Dao层:UserMapper
public interface UserMapper {
/*
根据用户ID清空中间表
*/
void deleteUserContextRole(Integer userId);
/*
分配角色
*/
void userContextRole(User_Role_relation user_role_relation);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lagou.dao.UserMapper">
<!-- 根据userid清空中间表关联关系 void deleteUserContextRole(Integer
userId);-->
<delete id="deleteUserContextRole" parameterType="int">
delete from user_role_relation where user_id = #{userid}
</delete>
<!--用户角色关联 void userContextRole(Integer userId, Integer roleid);-->
<insert id="userContextRole"
parameterType="com.lagou.domain.User_Role_relation">
insert into user_role_relation values(null,#{userId},#{roleId},#{createdTime},#{updatedTime},
#{createdBy},#{updatedby})
</insert>
</mapper>
Service层:UserService
public interface UserService {
/*
用户关联角色
*/
void userContextRole(UserVo userVo);
}
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
/*
用户关联角色
*/
@Override
public void userContextRole(UserVo userVo) {
// 根据用户ID清空中间表的关联关系
userMapper.deleteUserContextRole(userVo.getUserId());
// 向中间表添加记录
for (Integer roleid : userVo.getRoleIdList()) {
User_Role_relation user_role_relation = new User_Role_relation();
user_role_relation.setUserId(userVo.getUserId());
user_role_relation.setRoleId(roleid);
Date date = new Date();
user_role_relation.setCreatedTime(date);
user_role_relation.setUpdatedTime(date);
user_role_relation.setCreatedBy("system");
user_role_relation.setUpdatedby("system");
userMapper.userContextRole(user_role_relation);
}
}
}
Web层:UserController
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
/*
分配角色
*/
@RequestMapping("/userContextRole")
public ResponseResult userContextRole(@RequestBody UserVo userVo){
userService.userContextRole(userVo);
return new ResponseResult(true,200,"分配角色成功",null);
}
}
Postman测试接口
4.动态菜单显示
4.1 需求分析
需求:登陆成功后,根据用户所拥有的权限信息,进行菜单列表动态展示
4.2 查看接口文档,进行编码
查看接口文档
Dao层:UserMapper
public interface UserMapper {
/**
* 根据ID查询用户当前角色
* */
public List<Role> findUserRelationRoleById(int id);
/**
* 根据角色id,查询角色拥有的顶级菜单信息
* */
public List<Menu> findParentMenuByRoleId(List<Integer> ids);
/**
* 根据PID 查询子菜单信息
* */
public List<Menu> findSubMenuByPid(int pid);
/**
* 获取用户拥有的资源权限信息
* */
public List<Resource> findResourceByRoleId(List<Integer> ids);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lagou.dao.UserMapper">
<!-- 根据ID查询用户当前角色 -->
<select id="findUserRelationRoleById" resultType="com.lagou.domain.Role"
parameterType="int">
SELECT
r.id,
r.code,
r.name,
r.description
FROM roles r INNER JOIN user_role_relation ur
ON r.ìd` = ur.`role_idÌNNER JOIN USER u ON ur.ùser_id` = u.ìd`
WHERE u.ìd` = #{id}
</select>
<!-- 根据角色id,查询角色拥有的顶级菜单信息 -->
<select id="findParentMenuByRoleId" parameterType="java.util.List" resultType="com.lagou.domain.Menu">
SELECT
DISTINCT m.*
FROM roles r INNER JOIN role_menu_relation rm ON r.ìd` = rm.role_id
INNER JOIN menu m ON rm.menu_id = m.id
WHERE m.parent_id = -1 AND r.id IN
<foreach collection="list" item="item" open="(" separator="," close=")">
#{item}
</foreach>
GROUP BY m.id
</select>
<!-- 根据PID 查找子菜单 -->
<select id="findSubMenuByPid" resultType="com.lagou.domain.Menu">
select * from menu where parent_id = #{pid}
</select>
<!-- 获取用户拥有的资源权限 -->
<select id="findResourceByRoleId" parameterType="java.util.List" resultType="com.lagou.domain.Resource">
SELECT
DISTINCT rc.*
FROM roles r INNER JOIN role_resource_relation rrr ON r.ìd` = rrr.`role_id`
INNER JOIN resource rc ON rrr.`resource_id` = rc.ìd` WHERE r.id IN
<foreach item="item" index="index" collection="list" open="(" separator="," close=")">
#{item}
</foreach>
GROUP BY rc.id;
</select>
</mapper>
Service层:UserService
public interface UserService {
/*
* 获取用户权限
* */
ResponseResult getUserPermissions(Integer id);
}
@Service
public class UserServiceImpl implements PromotionSpaceService {
@Autowired
private UserMapper userMapper;
@Override
public ResponseResult getUserPermissions(Integer id) {
//1.获取当前用户拥有的角色
List<Role> roleList = userMapper.findUserRelationRoleById(id);
//2.获取角色ID,保存到 list
List<Integer> list = new ArrayList<>();
for (Role role : roleList) {
list.add(role.getId());
}
//3.根据角色id查询 父菜单
List<Menu> parentMenu = userMapper.findParentMenuByRoleId(list);
//4.封装父菜单下的子菜单
for (Menu menu : parentMenu) {
List<Menu> subMenu = userMapper.findSubMenuByPid(menu.getId());
menu.setSubMenuList(subMenu);
}
//5.获取资源权限
List<Resource> resourceList = userMapper.findResourceByRoleId(list);
//6.封装数据
Map<String,Object> map = new HashMap<>();
map.put("menuList",parentMenu); //menuList: 菜单权限数据
map.put("resourceList",resourceList);//resourceList: 资源权限数据
ResponseResult result = new ResponseResult(true,200,"响应成功",map);
return result;
}
}
Web层:UserController
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
/**
* 获取用户权限
* */
@RequestMapping("/getUserPermissions")
public ResponseResult getUserPermissions(HttpServletRequest request){
//获取请求头中的 token
String token = request.getHeader("Authorization");
//获取session中的access_token
HttpSession session = request.getSession();
String access_token = (String)session.getAttribute("access_token");
//判断
if(token.equals(access_token)){
int user_id = (Integer)session.getAttribute("user_id");
ResponseResult result = userService.getUserPermissions(user_id);
return result;
}else{
ResponseResult result = new ResponseResult(false,400,"获取失败","");
return result;
}
}
}
Postman测试接口
本文来自博客园,作者:寒露凝珠,转载请注明原文链接:https://www.cnblogs.com/china-soldier/p/15674576.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现