基于SpringCloudalibaba+SSM+Mybatisplus实现在线教育讲师管理后端
🔎这里是陶然同学,关注我学习Java不迷路
👍如果对你有帮助,给博主一个免费的点赞以示鼓励
欢迎各位🔎点赞👍评论收藏⭐️
👀专栏介绍
Java目前主要更新项目,一起学习一起进步。
👀本期介绍
基于SpringCloudalibaba+SSM+Mybatisplus实现在线教育讲师管理后端
资料获取
链接:https://pan.baidu.com/s/12tchZo7zwmvMqWBNY9BLog
提取码:8888
文章目录
在线教育-传智在线
课程目标
1)传智在线项目简介
2)环境搭建【重点】
3)实现讲师CRUD【重点】
1.传智在线项目介绍
-
传智在线,是一个B2C模式的职业技能在线教育系统,分为前台用户系统和后台运营平台。
1.1功能简介
-
做的什么模块?
-
整个项目分为两大部分:前台部分、后台部分
-
前台部分:为用户使用部分,可以进行视频的购买与学习。
-
后台部分:为管理操作部分,进行视频上传与维护。
-
本课程主要完成的是
后台部分
。
-
-
用到什么技术?
-
后端:SpringCloud alibaba+SSM+mybatis-plus+swagger-ui+POI+Redis + JavaMail +.....
-
前端:Vue全家桶:Vue+Vue-Router+Vuex+SPA + element ui admin
-
-
解决什么问题?
1.2系统模块
1.3系统架构
-
前后端分离开发:
-
解耦
-
后端和前端完全分离,并且后台接口可以供给多端使用!(APP,微信,PC,WAP)(Restful风格的接口可以给任何应用去使用)
-
-
架构设计需要考虑的几个方面:
-
性能:主要考虑访问频率,每个用户每天的访问次数。项目初始阶段用户的访问量并不大,如果考虑做运营推广,可能会迎来服务器访问量骤增,因此要考虑分布式部署,引入缓存
-
可扩展性:系统功能会随着用户量的增加以及多变的互联网用户需求不断地扩展,因此考虑到系统的可扩展性的要求需要使用
微服务
架构,引入消息中间件 -
高可用:系统一旦宕机,将会带来不可挽回的损失,因此必须做负载均衡,甚至是异地多活这类复杂的方案。如果数据丢失,修复将会非常麻烦,只能靠人工逐条修复,这个很难接受,因此需要考虑存储高可靠。我们需要考虑多种异常情况:机器故障、机房故障,针对机器故障,我们需要设计 MySQL 同机房主备方案;针对机房故障,我们需要设计 MySQL 跨机房同步方案。
-
安全性:系统的信息有一定的隐私性,例如用户的个人身份信息,不包含强隐私(例如玉照、情感)的信息,因此使用账号密码管理、数据库访问权限控制即可。
-
成本:视频类网站的主要成本在于服务器成本、流量成本、存储成本、流媒体研发成本,中小型公司可以考虑使用云服务器和云服务。
-
2.数据库设计
2.1 数据库
数据库名称 | 描述 |
---|---|
zx_edu_teacher | 老师相关数据库 |
zx_edu_course | 课程相关数据库 |
zx_edu_user | 用户相关数据库 |
zx_edu_vod | 视频vod相关数据库 |
2.2 数据表
本章使用到了老师表:edu_teacher
3.创建项目
3.1 项目架构
3.2 创建父工程zx-parent
-
第一步:创建 zx-parent31项目
-
第二步:配置 pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.czxy.zx</groupId> <artifactId>zx-parent31</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <modules> <module>zx-gateway31</module> <module>zx-domain31</module> <module>zx-common31</module> <module>zx-service-teacher31</module> </modules> <!-- 1 确定spring boot的版本--> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.5.RELEASE</version> </parent> <!--2 确定版本--> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> <spring-cloud-release.version>Hoxton.SR3</spring-cloud-release.version> <nacos.version>1.1.0</nacos.version> <alibaba.cloud.version>2.2.1.RELEASE</alibaba.cloud.version> <mysql.version>5.1.32</mysql.version> <mybatis.plus.version>3.4.0</mybatis.plus.version> <druid.starter.version>1.1.9</druid.starter.version> <jwt.jjwt.version>0.9.0</jwt.jjwt.version> <jwt.joda.version>2.9.7</jwt.joda.version> <swagger.version>2.7.0</swagger.version> <swagger.anno.version>1.5.13</swagger.anno.version> <beanutils.version>1.9.3</beanutils.version> <aliyun.sdk.core.version>3.3.1</aliyun.sdk.core.version> <aliyun.sdk.dysmsapi.version>1.0.0</aliyun.sdk.dysmsapi.version> <fastjson.version>1.2.9</fastjson.version> <zx.version>1.0-SNAPSHOT</zx.version> </properties> <!-- 3 锁定版本--> <dependencyManagement> <dependencies> <!-- sprig cloud--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud-release.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!--nacos --> <dependency> <groupId>com.alibaba.nacos</groupId> <artifactId>nacos-client</artifactId> <version>${nacos.version}</version> </dependency> <!--nacos cloud 发现 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>${alibaba.cloud.version}</version> </dependency> <!--nacos cloud 配置 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <version>${alibaba.cloud.version}</version> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-sentinel --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <version>${alibaba.cloud.version}</version> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-seata</artifactId> <version>${alibaba.cloud.version}</version> </dependency> <!-- mybatis plus--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>${mybatis.plus.version}</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-annotation</artifactId> <version>${mybatis.plus.version}</version> </dependency> <!-- mysql驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version> </dependency> <!-- druid启动器 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>${druid.starter.version}</version> </dependency> <!--swagger2--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>${swagger.version}</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>${swagger.version}</version> </dependency> <dependency> <groupId>io.swagger</groupId> <artifactId>swagger-annotations</artifactId> <version>${swagger.anno.version}</version> </dependency> <!--jwt--> <!--JavaBean工具类,用于JavaBean数据封装--> <dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-beanutils</artifactId> <version>${beanutils.version}</version> </dependency> <!--jwt工具--> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>${jwt.jjwt.version}</version> </dependency> <!--joda 时间工具类 --> <dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> <version>${jwt.joda.version}</version> </dependency> <!--短信--> <dependency> <groupId>com.aliyuncs</groupId> <artifactId>aliyun-java-sdk-core</artifactId> <version>${aliyun.sdk.core.version}</version> </dependency> <dependency> <groupId>com.aliyuncs.dysmsapi</groupId> <artifactId>aliyun-java-sdk-dysmsapi</artifactId> <version>${aliyun.sdk.dysmsapi.version}</version> </dependency> <!--fastjson--> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>${fastjson.version}</version> </dependency> <!--自定义项目 zx.version--> <dependency> <groupId>com.czxy.zx</groupId> <artifactId>zx-common31</artifactId> <version>${zx.version}</version> </dependency> <dependency> <groupId>com.czxy.zx</groupId> <artifactId>zx-domain31</artifactId> <version>${zx.version}</version> </dependency> </dependencies> </dependencyManagement> </project>
3.3 创建zx-common
第一步:创建项目
第二步:配置pom.xml文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>zx-parent31</artifactId> <groupId>com.czxy.zx</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>zx-common31</artifactId> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--lombok , @Data 等--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <!--swagger2--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> </dependency> <!--jwt工具--> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> </dependency> <!--joda 时间工具类 --> <dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> </dependency> <!--JavaBean工具类,用于JavaBean数据封装--> <dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-beanutils</artifactId> </dependency> <!-- vod相关 --> <dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-core</artifactId> <version>4.5.1</version> </dependency> <dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> <version>3.10.2</version> </dependency> <dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-vod</artifactId> <version>2.15.11</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.28</version> </dependency> <dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>20170516</version> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.2</version> </dependency> <dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-sdk-vod-upload</artifactId> <version>1.4.13</version> </dependency> </dependencies> </project>
-
第三步:拷贝工具类
3.4 创建zx-domain
-
第一步:创建模块
-
第二步:配置pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>zx-parent31</artifactId> <groupId>com.czxy.zx</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>zx-domain31</artifactId> <dependencies> <!--lombok , @Data 等--> <dependency> <groupId>io.swagger</groupId> <artifactId>swagger-annotations</artifactId> <version>1.5.13</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <!--jackson , @JsonFormat--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-json</artifactId> </dependency> <!--mybatis-plus , @TableName @TableId 等 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-annotation</artifactId> </dependency> </dependencies> </project>
-
步骤三:创建domain目录
3.5 创建zx-gateway
-
第一步:创建模块
-
第二步:配置pom.xml文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>zx-parent31</artifactId> <groupId>com.czxy.zx</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>zx-gateway31</artifactId> <dependencies> <!-- 网关 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <!-- nacos 服务发现 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> </dependencies> </project>
-
第三步:创建 application.yml 核心配置文件
#端口号 server: port: 10010 spring: application: name: zx-gateway servlet: multipart: max-file-size: 2MB #上传文件的大小 cloud: nacos: discovery: server-addr: 127.0.0.1:8848 #nacos服务地址 gateway: discovery: locator: enabled: true #开启服务注册和发现的功能,自动创建router以服务名开头的请求路径转发到对应的服务 lowerCaseServiceId: true #将请求路径上的服务名配置为小写 sc: jwt: secret: sc@Login(Auth}*^31)&czxy% # 登录校验的密钥 pubKeyPath: D:/rsa/rsa.pub # 公钥地址 priKeyPath: D:/rsa/rsa.pri # 私钥地址 expire: 360 # 过期时间,单位分钟 filter: allowPaths: - swagger - /api-docs
-
步骤四:拷贝跨域配置类
-
步骤五:编写启动类
package com.czxy.zx; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; /** * @author 桐叔 * @email liangtong@itcast.cn */ @SpringBootApplication @EnableDiscoveryClient public class GatewayApplication { public static void main(String[] args) { SpringApplication.run(GatewayApplication.class, args); } }
3.6 创建zx-service-teacher模块
第一步:创建模块
第二步:配置 pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>zx-parent31</artifactId> <groupId>com.czxy.zx</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>zx-service-teacher31</artifactId> <dependencies> <!--web起步依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- nacos 客户端 --> <dependency> <groupId>com.alibaba.nacos</groupId> <artifactId>nacos-client</artifactId> </dependency> <!-- nacos 服务发现 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--swagger2--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> </dependency> <!-- feign 远程调用 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!--测试--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> <!-- mybatis plus--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>${mybatis.plus.version}</version> </dependency> <!-- mysql驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!--自定义项目--> <dependency> <groupId>com.czxy.zx</groupId> <artifactId>zx-common31</artifactId> </dependency> <dependency> <groupId>com.czxy.zx</groupId> <artifactId>zx-domain31</artifactId> </dependency> <!-- redis 启动器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- JavaMail 启动器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> <!-- MQ 启动器 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> <!-- fastjson --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> </dependency> <!--开发者工具--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> </dependencies> </project>
第三步: 创建application.yml文件
# 服务端口号 server: port: 9000 # 服务名 spring: application: name: teacher-service datasource: driverClassName: com.mysql.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/zx_edu_teacher?useUnicode=true&characterEncoding=utf8 username: root password: 1234 druid: #druid 连接池配置 initial-size: 1 #初始化连接池大小 min-idle: 1 #最小连接数 max-active: 20 #最大连接数 test-on-borrow: true #获取连接时候验证,会影响性能 cloud: nacos: discovery: server-addr: 127.0.0.1:8848 #nacos服务地址 redis: database: 0 #数据库索引,取值0-15,表示16个库可选择 host: 127.0.0.1 #服务器地址 port: 6379 #服务器连接端口号 mail: host: smtp.126.com #发送邮件服务器 username: itcast_lt@126.com #账号 password: 1qaz2wsx #密码 default-encoding: UTF-8 #默认编码时 rabbitmq: host: 127.0.0.1 port: 5672 username: guest passowrd: guest virtualHost: / devtools: restart: enabled: true #设置开启热部署 additional-paths: src/main/java #重启目录 exclude: WEB-INF/** freemarker: cache: false #页面不加载缓存,修改即时生效 #开启log4j打印SQL语句 logging: level: com: czxy: zx: teacher: mapper: debug # mp日志打印 mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
第四步:启动类
package com.czxy.zx; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; /** * @author 桐叔 * @email liangtong@itcast.cn */ @SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class TeacherServiceApplication { public static void main(String[] args) { SpringApplication.run(TeacherServiceApplication.class,args); } }
4.实现讲师列表接口
4.1 pojo
-
在zx-domain中创建实体类EduTeacher
package com.czxy.zx.domain; import com.baomidou.mybatisplus.annotation.*; import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.util.Date; /** * */ @Data//lombok注解 @ApiModel(value = "EduTeacher对象",description = "讲师")//swagger注解 public class EduTeacher { @TableId(value = "id",type = IdType.AUTO)//mybatis-plus的注解 @ApiModelProperty(value = "讲师ID")//swagger注解 private String id; @ApiModelProperty(value = "讲师姓名") private String name; @ApiModelProperty(value = "讲师资历,一句话说明讲师") private String intro; @ApiModelProperty(value = "讲师简介") private String career; @ApiModelProperty(value = "头衔 1高级讲师 2首席讲师") private Integer level; @ApiModelProperty(value = "讲师头像") private String avatar; @ApiModelProperty(value = "讲师排序") private Integer sort; @ApiModelProperty(value = "逻辑删除 1已删除, 0未删除") @TableField(value = "is_deleted",fill = FieldFill.INSERT) @TableLogic//逻辑删除 private Integer isDeleted; @ApiModelProperty(value = "创建时间") @TableField(value = "gmt_create",fill = FieldFill.INSERT) @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") private Date gmtCreate; @ApiModelProperty(value = "更新时间") @TableField(value = "gmt_modified",fill = FieldFill.INSERT_UPDATE) @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") private Date gmtModified; }
4.2 mapper
package com.czxy.zx.teacher.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.czxy.zx.domain.EduTeacher; import org.apache.ibatis.annotations.Mapper; /** * */ @Mapper public interface EduTeacherMapper extends BaseMapper<EduTeacher> { }
4.3 service
-
接口
package com.czxy.zx.teacher.service; import com.baomidou.mybatisplus.extension.service.IService; import com.czxy.zx.domain.EduTeacher; /** * @author 桐叔 * @email liangtong@itcast.cn */ public interface EduTeacherService extends IService<EduTeacher> { }
-
实现类
package com.czxy.zx.teacher.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.czxy.zx.domain.EduTeacher; import com.czxy.zx.teacher.mapper.EduTeacherMapper; import com.czxy.zx.teacher.service.EduTeacherService; import org.springframework.stereotype.Service; /** * @author 桐叔 * @email liangtong@itcast.cn */ @Service public class EduTeacherServiceImpl extends ServiceImpl<EduTeacherMapper, EduTeacher> implements EduTeacherService { }
4.4 Controller
TeacherController
package com.czxy.zx.teacher.controller; import com.czxy.zx.domain.EduTeacher; import com.czxy.zx.teacher.service.EduTeacherService; import com.czxy.zx.vo.BaseResult; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import java.util.List; /** * @author 桐叔 * @email liangtong@itcast.cn */ @RestController @RequestMapping("/teacher") public class EduTeacherController { @Resource private EduTeacherService eduTeacherService; @GetMapping private BaseResult<List<EduTeacher>> getTeacherList(){ List<EduTeacher> list = eduTeacherService.list(null); return BaseResult.ok("查询成功", list); } }
4.5 拷贝配置类
4.6 处理Swagger接口
-
修改controller
package com.czxy.zx.teacher.controller; import com.czxy.zx.domain.EduTeacher; import com.czxy.zx.teacher.service.EduTeacherService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.util.List; /** * @author 桐叔 * @email liangtong@itcast.cn */ @RestController @RequestMapping("/teacher") @Api(tags = "老师接口", description = "老师接口描述,完成增删改查操作") public class EduTeacherController { @Resource private EduTeacherService eduTeacherService; @ApiOperation(value = "查询所有老师") @GetMapping private BaseResult<List<EduTeacher>> getTeacherList(){ List<EduTeacher> list = eduTeacherService.list(null); return BaseResult.ok("查询成功", list); } }
4.7 测试
http://localhost:9000/swagger-ui.html
5.讲师逻辑删除
5.1 在Controller中添加删除方法
@ApiOperation(value = "根据ID删除讲师") @ApiImplicitParams(value = { // @ApiImplicitParam(name = "id", value = "讲师ID", required = true,paramType = "path")//方式一 }) @DeleteMapping("/{id}") public boolean removeById( @ApiParam(name = "id", value = "讲师ID", required = true)//方式二 @PathVariable("id") String id){ return eduTeacherService.removeById(id); }
5.2 在EduTeacher.java文件中
@ApiModelProperty(value = "逻辑删除 1(true)已删除, 0(false)未删除") @TableLogic @TableField(fill = FieldFill.INSERT, value = "is_deleted") private Boolean isDeleted;
5.3 完善:配置Handler
-
创建 com.czxy.zx.teacher.handler.TeacherMetaObjectHandler.java
package com.czxy.zx.teacher.handler; import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import org.apache.ibatis.reflection.MetaObject; import org.springframework.stereotype.Component; /** * @author 桐叔 * @email liangtong@itcast.cn */ @Component public class TeacherMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { // 添加时,填充的内容 // this.setFieldValByName("字段名", 字段值 , metaObject); this.setFieldValByName("isDeleted",0 , metaObject); } @Override public void updateFill(MetaObject metaObject) { // 修改时,填充的内容 } }
5.4 完善:配置application.yaml文件
-
配置指定删除和不删除的状态
mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: db-config: logic-delete-value: 1 logic-not-delete-value: 0
5.5 讲师逻辑删除测试
ok
6.分页和条件查询
6.1 基本查询
6.1.1 创建 vo
package com.czxy.zx.teacher.vo; import lombok.Data; /** * @author 桐叔 * @email liangtong@itcast.cn */ @Data public class TeacherVo { }
6.1.2 controller
@ApiOperation(value = "所有老师:条件 + 分页") @ApiImplicitParams({ @ApiImplicitParam(name = "size",value = "每页个数",required = true,paramType = "path", dataType = "int"), @ApiImplicitParam(name = "current",value = "当前页",required = true,paramType = "path", dataType = "int") }) @PostMapping("/condition/{size}/{current}") public BaseResult<Page<EduTeacher>> condition( @PathVariable("size") Integer size, @PathVariable("current") Integer current, @RequestBody TeacherVo teacherVo ){ Page<EduTeacher> page = eduTeacherService.condition(size,current,teacherVo); return BaseResult.ok("查询成功", page); }
6.1.3 service
-
接口
package com.czxy.zx.teacher.service; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import com.czxy.zx.domain.EduTeacher; import com.czxy.zx.teacher.vo.TeacherVo; /** * @author 桐叔 * @email liangtong@itcast.cn */ public interface EduTeacherService extends IService<EduTeacher> { /** * 条件分页查询 * @param size * @param current * @param teacherVo * @return */ Page<EduTeacher> condition(Integer size, Integer current, TeacherVo teacherVo); }
-
实现类
package com.czxy.zx.teacher.service.impl; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.czxy.zx.domain.EduTeacher; import com.czxy.zx.teacher.mapper.EduTeacherMapper; import com.czxy.zx.teacher.service.EduTeacherService; import com.czxy.zx.teacher.vo.TeacherVo; import org.springframework.stereotype.Service; /** * @author 桐叔 * @email liangtong@itcast.cn */ @Service public class EduTeacherServiceImpl extends ServiceImpl<EduTeacherMapper, EduTeacher> implements EduTeacherService { @Override public Page<EduTeacher> condition(Integer size, Integer current, TeacherVo teacherVo) { return null; } }
6.2 分页
-
修改service,完成分页查询
package com.czxy.zx.teacher.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.czxy.zx.domain.EduTeacher; import com.czxy.zx.teacher.mapper.EduTeacherMapper; import com.czxy.zx.teacher.service.EduTeacherService; import com.czxy.zx.teacher.vo.TeacherVo; import org.springframework.stereotype.Service; /** * @author 桐叔 * @email liangtong@itcast.cn */ @Service public class EduTeacherServiceImpl extends ServiceImpl<EduTeacherMapper, EduTeacher> implements EduTeacherService { @Override public Page<EduTeacher> condition(Integer size, Integer current, TeacherVo teacherVo) { //1 条件查询 QueryWrapper<EduTeacher> queryWrapper = new QueryWrapper<>(); //2 分页条件 Page<EduTeacher> page = new Page<>(current,size); //3 查询 this.baseMapper.selectPage(page, queryWrapper); //4 关联查询 //5 返回 return page; } }
6.3 条件查询
-
需求:
-
根据讲师姓名模糊查询
-
根据讲师头衔精准查询
-
根据时间范围查询(开始时间、结束时间)
-
-
完善vo
package com.czxy.zx.teacher.vo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; /** * @author 桐叔 * @email liangtong@itcast.cn */ @Data @ApiModel(value = "封装了Teacher条件查询的参数") public class TeacherVo { @ApiModelProperty(value = "讲师姓名,模糊查询") private String name; @ApiModelProperty(value = "讲师头衔:1 高级讲师 2 首席讲师") private String level; @ApiModelProperty(value = "查询开始时间",example = "2020-02-01 10:12:30") private String beginDate; @ApiModelProperty(value = "查询截止时间",example = "2020-02-01 10:12:30") private String endDate; }
-
完善service
package com.czxy.zx.teacher.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.czxy.zx.domain.EduTeacher; import com.czxy.zx.teacher.mapper.EduTeacherMapper; import com.czxy.zx.teacher.service.EduTeacherService; import com.czxy.zx.teacher.vo.TeacherVo; import org.apache.commons.lang.StringUtils; import org.springframework.stereotype.Service; /** * @author 桐叔 * @email liangtong@itcast.cn */ @Service public class EduTeacherServiceImpl extends ServiceImpl<EduTeacherMapper, EduTeacher> implements EduTeacherService { @Override public Page<EduTeacher> condition(Integer size, Integer current, TeacherVo teacherVo) { //1 条件查询 QueryWrapper<EduTeacher> queryWrapper = new QueryWrapper<>(); queryWrapper.like(StringUtils.isNotBlank(teacherVo.getName()), "name", teacherVo.getName()); queryWrapper.eq(StringUtils.isNotBlank(teacherVo.getLevel()), "level", teacherVo.getLevel()); queryWrapper.ge(StringUtils.isNotBlank(teacherVo.getBeginDate()), "gmt_create", teacherVo.getBeginDate()); queryWrapper.le(StringUtils.isNotBlank(teacherVo.getEndDate()), "gmt_create", teacherVo.getEndDate()); //2 分页条件 Page<EduTeacher> page = new Page<>(current,size); //3 查询 this.baseMapper.selectPage(page, queryWrapper); //4 关联查询 //5 返回 return page; } }
6.4 测试
ok
7.讲师新增和修改
7.1 新增
在Controller中编写代码
@ApiOperation(value = "新增讲师") @PostMapping public BaseResult save( @ApiParam(name = "teacher", value = "讲师对象", required = true) @RequestBody EduTeacher teacher){ boolean save = eduTeacherService.save(teacher); if(save) { return BaseResult.ok("添加成功"); } return BaseResult.error("添加失败"); }
7.2 根据id查询
@ApiOperation(value = "根据ID查询讲师") @GetMapping("{id}") public BaseResult getById( @ApiParam(name = "id", value = "讲师ID", required = true) @PathVariable String id){ EduTeacher teacher = eduTeacherService.getById(id); return BaseResult.ok("查询成功", teacher); }
7.3 根据id修改
@ApiOperation(value = "根据ID修改讲师") @PutMapping public BaseResult updateById( @ApiParam(name = "teacher", value = "讲师对象", required = true) @RequestBody EduTeacher teacher){ boolean update = eduTeacherService.updateById(teacher); if(update) { return BaseResult.ok("更新成功"); } return BaseResult.error("更新失败"); }
7.4 批量删除
/** * 批量删除 * @return */ @PostMapping("/batchDelete") public BaseResult batchDelete(@RequestBody List<Integer> ids) { boolean result = eduTeacherService.removeByIds(ids); if(result) { return BaseResult.ok("批量删除成功"); } return BaseResult.error("批量删除失败"); }
7.5 修改处理类:自动填充
package com.czxy.zx.teacher.handler; import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import org.apache.ibatis.reflection.MetaObject; import org.springframework.stereotype.Component; import java.util.Date; /** * @author 桐叔 * @email liangtong@itcast.cn */ @Component public class TeacherMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { // 给javabean默认值 // 1 逻辑删除的默认值 this.setFieldValByName("isDeleted", 0 , metaObject); // 2 创建、修改时间 this.setFieldValByName("gmtCreate", new Date(), metaObject); this.setFieldValByName("gmtModified", new Date(), metaObject); } @Override public void updateFill(MetaObject metaObject) { // 2 修改时间 this.setFieldValByName("gmtModified", new Date(), metaObject); } }
8.统一异常处理
8.1 测试系统对错误的响应
-
在更新操作中,应该输入
{}
填写更新数据,如果填写成[]
,程序将抛出异常。
8.2 全局异常处理
-
我们想让异常结果也统一,并且在集中的地方处理系统的异常信息,那么需要统一异常处理。
-
spring mvc 提供
@ControllerAdvice
就可以完成此需求。 -
@ControllerAdvice
是对Controller进行增强的注解,主要作用有三个:-
全局异常处理(*)
-
全局数据绑定
-
全局数据预处理
-
-
zx-common中创建统一异常处理类:
package com.czxy.zx.exception; import com.czxy.zx.vo.BaseResult; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; /** * @author 桐叔 * @email liangtong@itcast.cn */ @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class)//拦截什么异常 @ResponseBody public BaseResult error(Exception e){ e.printStackTrace(); return BaseResult.error("系统错误"); } }
-
注意:启动类的位置
-
启动类必须放在
com.czxy.zx
包下面才可以加载到com.czxy.zx.exception
包下面的内容 -
如果放在
com.czxy.zx.teacher
下面,将无法加载到com.czxy.zx.exception
包下面的内容
-
-
测试,返回统一错误结果
8.3 特殊异常配置
如果是除数为0的异常;那么需要如下配置,精确匹配异常:
package com.czxy.zx.exception; import com.czxy.zx.vo.BaseResult; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; /** * @author 桐叔 * @email liangtong@itcast.cn */ @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class)//拦截什么异常 @ResponseBody public BaseResult error(Exception e){ e.printStackTrace(); return BaseResult.error("系统错误"); } @ExceptionHandler(ArithmeticException.class) @ResponseBody public BaseResult error(ArithmeticException e){ e.printStackTrace(); return BaseResult.error("除数不能为0"); } }
8.4 自定义异常
8.4.1 EduException通用异常类
-
在zx-common中创建Exception的异常类
package com.czxy.zx.exception; import io.swagger.annotations.ApiModel; /** * @author 桐叔 * @email liangtong@itcast.cn */ @ApiModel(value = "自定义异常") public class EduException extends RuntimeException { public EduException(String message) { super(message); } public EduException(String message, Throwable cause) { super(message, cause); } public EduException(Throwable cause) { super(cause); } protected EduException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); } }
8.4.2 创建捕获自定义异常类
-
在 GlobalExceptionHandler类中添加自定义处理方法
@ExceptionHandler(EduException.class) @ResponseBody public BaseResult error(EduException e){ e.printStackTrace(); if(e.getMessage() == null) { return BaseResult.error("空指针异常"); } return BaseResult.error(e.getMessage()); }
-
测试:在业务中需要的位置抛出EduException,举例子在查询列表中出错:
@ApiOperation(value = "查询所有老师") @GetMapping private BaseResult<List<EduTeacher>> getTeacherList(){ List<EduTeacher> list = eduTeacherService.list(null); //测试自定义异常 if(list.size() > 0) { throw new EduException("数据异常"); } return BaseResult.ok("查询成功", list); }
8.4.3 异常工具类
-
编写 ExceptionUtils 类,方便异常的抛出
package com.czxy.zx.exception; /** * @author 桐叔 * @email liangtong@itcast.cn */ public class ExceptionUtils { /** * 抛出异常 * @param message */ public static void cast(String message) { throw new EduException(message); } }
-
测试:
@ApiOperation(value = "查询所有老师") @GetMapping private BaseResult<List<EduTeacher>> getTeacherList(){ List<EduTeacher> list = eduTeacherService.list(null); //测试自定义异常 if(list.size() > 0) { //throw new EduException("数据异常"); ExceptionUtils.cast("数据异常"); } return BaseResult.ok("查询成功", list); }
9.附:创建MP代码生成器
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.4.0</version> </dependency> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-engine-core</artifactId> <version>2.0</version> </dependency>
在test/java目录下创建包com.zx.edu,创建代码生成器:CodeGenerator.java
package com.zx; import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.generator.AutoGenerator; import com.baomidou.mybatisplus.generator.config.DataSourceConfig; import com.baomidou.mybatisplus.generator.config.GlobalConfig; import com.baomidou.mybatisplus.generator.config.PackageConfig; import com.baomidou.mybatisplus.generator.config.StrategyConfig; import com.baomidou.mybatisplus.generator.config.rules.DateType; import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; import org.junit.Test; public class CodeGenerator { @Test public void run() { // 1、创建代码生成器 AutoGenerator mpg = new AutoGenerator(); // 2、全局配置 GlobalConfig gc = new GlobalConfig(); String projectPath = System.getProperty("user.dir"); //有的电脑系统,如果代码发现生成有问题,projectPath直接写成项目名称 //gc.setOutputDir("edu_eduservice" + "/src/main/java"); gc.setOutputDir(projectPath + "/src/main/java"); gc.setAuthor("lt"); gc.setOpen(false); //生成后是否打开资源管理器 gc.setFileOverride(false); //重新生成时文件是否覆盖 //IUserServcie gc.setServiceName("%sService"); //去掉Service接口的首字母I gc.setIdType(IdType.ID_WORKER_STR); //主键策略 gc.setDateType(DateType.ONLY_DATE);//定义生成的实体类中日期类型 gc.setSwagger2(true);//开启Swagger2模式 mpg.setGlobalConfig(gc); // 3、数据源配置 DataSourceConfig dsc = new DataSourceConfig(); dsc.setUrl("jdbc:mysql://localhost:3306/zx_edu_teacher"); dsc.setDriverName("com.mysql.jdbc.Driver"); dsc.setUsername("root"); dsc.setPassword("1234"); dsc.setDbType(DbType.MYSQL); mpg.setDataSource(dsc); // 4、包配置 PackageConfig pc = new PackageConfig(); pc.setModuleName("teacher"); //模块名 pc.setParent("com.zx"); pc.setController("controller"); pc.setEntity("entity"); pc.setService("service"); pc.setMapper("mapper"); mpg.setPackageInfo(pc); // 5、策略配置 StrategyConfig strategy = new StrategyConfig(); strategy.setInclude("edu_teacher");//表名称 strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略 strategy.setTablePrefix(pc.getModuleName() + "_"); //生成实体时去掉表前缀 strategy.setColumnNaming(NamingStrategy.underline_to_camel);//数据库表字段映射到实体的命名策略 strategy.setEntityLombokModel(true); // lombok 模型 @Accessors(chain = true) setter链式操作 strategy.setRestControllerStyle(true); //restful api风格控制器 strategy.setControllerMappingHyphenStyle(true); //url中驼峰转连字符 mpg.setStrategy(strategy); // 6、执行 mpg.execute(); } }
执行代码生成器方法
说明:
XxxServiceImpl 继承了 ServiceImpl 类,并且MP为我们注入了 XxxMapper
这样可以使用 service 层默认为我们提供的很多方法,当然也可以调用我们自己在 dao 层编写的方法。