(一)在线教育网站搭建-后端讲师管理模块

SpringBoot,Mybatis-Plus

1. edu_teacher表设计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
create database online default character set utf8;

use online;

drop table if exists edu_teacher;

create table edu_teacher(
id char(19) not null comment '讲师ID',
name varchar(20) not null comment '讲师姓名',
intro varchar(255) not null comment '讲师资历',
career text comment '讲师简介',
level int(10) unsigned not null comment '头衔 1高级讲师 2首席讲师',
avatar varchar(255) default null comment '讲师头像',
sort int(10) unsigned not null default 0 comment '排序',
is_deleted tinyint(1) unsigned not null default 0 comment '逻辑删除 1 表示删除,0 表示未删除',
gmt_create datetime not null comment '创建时间',
gmt_modified datetime not null comment '更新时间',
primary key(id),
key idx_name(name)
)

select * from edu_teacher;

2. 《阿里巴巴Java开发手册》五、MySQL数据库

1、库名与应用名称尽量一致

2、表名、字段名必须使用小写字母或数字,禁止出现数字开头

3、表名不使用复数名词

4、表的命名最好是加上“业务名称_表的作用”。如,edu_teacher

5、表必备三字段:id, gmt_create, gmt_modified

​ id 必为主键,类型为 bigint unsigned、单表时自增、步长为 1。

(如果使用分库分表集群部署,则id类型为verchar,非自增,业务中使用分布式id生成器)

​ gmt_create, gmt_modified 的类型均为 datetime 类型,前者现在时表示主动创建,后者过去分词表示被 动更新。

6、单表行数超过 500 万行或者单表容量超过 2GB,才推荐进行分库分表。 说明:如果预计三年后的数据量根本达不到这个级别,请不要在创建表时就分库分表。

7、表达是与否概念的字段,必须使用 is_xxx 的方式命名,数据类型是 unsigned tinyint (1 表示是,0 表示否)。

说明:任何字段如果为非负数,必须是 unsigned。

注意:POJO 类中的任何布尔类型的变量,都不要加 is 前缀。数据库表示是与否的值,使用 tinyint 类型,坚持 is_xxx 的 命名方式是为了明确其取值含义与取值范围。

正例:表达逻辑删除的字段名 is_deleted,1 表示删除,0 表示未删除。

8、小数类型为 decimal,禁止使用 float 和 double。 说明:float 和 double 在存储的时候,存在精度损失的问题,很可能在值的比较时,得到不 正确的结果。如果存储的数据范围超过 decimal 的范围,建议将数据拆成整数和小数分开存储。

9、如果存储的字符串长度几乎相等,使用 char 定长字符串类型。

10、varchar 是可变长字符串,不预先分配存储空间,长度不要超过 5000,如果存储长度大于此值,定义字段类型为 text,独立出来一张表,用主键来对应,避免影响其它字段索 引效率。

11、唯一索引名为 uk_字段名;普通索引名则为 idx_字段名。

说明:uk_ 即 unique key;idx_ 即 index 的简称

12、不得使用外键与级联,一切外键概念必须在应用层解决。外键与级联更新适用于单机低并发,不适合分布式、高并发集群;级联更新是强阻塞,存在数据库更新风暴的风险;外键影响数据库的插入速度。

3. Maven-pom父项目

新建SpringBoot项目 pom.xml 中项目打包方式写为pom

1
<packaging>pom</packaging>

3.1. 添加properties-规定jar版本

1
2
3
4
5
6
7
<properties>
<java.version>1.8</java.version>
<mybatis-plus.version>3.3.1.tmp</mybatis-plus.version>
<mybatis.generator.version>3.3.1.tmp</mybatis.generator.version>
<velocity.version>2.2</velocity.version>
<swagger.version>2.7.0</swagger.version>
</properties>

3.2. 配置dependencyManagement

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<dependencyManagement>
<dependencies>
<!-- mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>

<!-- mybatis-plus代码生成器 模版引擎依赖-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>${velocity.version}</version>
</dependency>

<!--swagger 用于生成、描述、调用和可视化 RESTful 风格的 Web 服务-->
<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>
</dependencies>
</dependencyManagement>

3.3. 配置dependencies

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>

<!--测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
</dependencies>

4. Module-子项目-Common

新建module- Maven项目

4.1. 添加lombok依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<dependencies>
<!-- 简化实体类 get/set方法-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
</dependency>
</dependencies>

4.2. 统一返回数据格式

1
2
3
4
5
6
{
"success":布尔 //响应是否成功
"code":数字 //响应码
"message":字符串 //返回消息
"data":HashMap //返回数据,键值对
}

4.3. ResultCode.java

java包下新建ResultCode接口

1
2
3
4
5
6
7
8
9
10
11
package com.online.edu.common;

public interface ResultCode {

//成功
int SUCCESS = 20000;
//失败
int ERROR = 20001;
//无权限
int AUTH = 30000;
}

4.4. R.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package com.online.edu.common;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.util.HashMap;
import java.util.Map;

@Data
@ApiModel(value = "全局统一返回结果")
public class R {

@ApiModelProperty(value = "是否成功")
private Boolean success;

@ApiModelProperty(value = "返回码")
private Integer code;

@ApiModelProperty(value = "返回消息")
private String message;

@ApiModelProperty(value = "返回数据")
private Map<String,Object> data = new HashMap<>();

public static R ok(){
R r = new R();
r.setSuccess(true);
r.setCode(ResultCode.SUCCESS);
r.setMessage("操作成功");
return r;
}
public static R error(){
R r = new R();
r.setSuccess(false);
r.setCode(ResultCode.ERROR);
r.setMessage("操作失败");
return r;
}

//链式编程
public R success(Boolean success){
this.setSuccess(success);
return this;
}

public R message(String message){
this.setMessage(message);
return this;
}

public R code(Integer code){
this.setCode(code);
return this;
}

public R data(Map<String,Object> map){
this.setData(map);
return this;
}

public R data(String key,Object value){
this.data.put(key,value);
return this;
}

}

5. Module-子项目-eduservice

同一个文件夹下新建Module Maven项目

5.1. 添加Maven依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<!-- 简化实体类 get/set方法-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>

<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>

<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>

<!-- mybatis-plus代码生成器 模版引擎依赖-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
</dependency>

<!-- 代码生成器 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
</dependency>

<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
</dependency>

<!--开发者工具-热部署 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>

<!-- 新建educommon依赖 -->
<dependency>
<groupId>com.online.edu</groupId>
<artifactId>educommon</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>

5.2. 新建主配置类

1
2
3
4
5
6
7
8
9
10
11
12
13
package com.online.edu.eduservice;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class EduServiceApplication {

public static void main(String[] args) {
SpringApplication.run(EduServiceApplication.class,args);
}
}

5.3. 新建application.properties

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#服务端口号
server.port=8080

#服务名
spring.application.name=online-edu

#开发环境 dev,test,prod
spring.profiles.active=dev

#mysql数据库连接
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://192.168.0.112:3306/online
spring.datasource.username=root
spring.datasource.password=123456

#数据源类型 Hikari是Spring Boot 2.0之后默认连接池,比druid更快的数据库连接池
#spring.datasource.type=com.zaxxer.hikari.util.DriverDataSource

#mybatis日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

5.4. 代码生成器CodeGenerator

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package com.online.edu.eduservice;


import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class CodeGenerator {

@Test
public void run() {

// 代码生成器
AutoGenerator mpg = new AutoGenerator();

// 全局配置
GlobalConfig gc = new GlobalConfig();
//项目根路径
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath + "/src/main/java");

gc.setAuthor("Wang T");

//生成后是否打开资源管理器
gc.setOpen(false);

//重新生成时文件是否覆盖
gc.setFileOverride(false);

//去掉Service接口的首字母I
gc.setServiceName("%sService");
//主键生成策略 -- 默认为雪花算法
gc.setIdType(IdType.ASSIGN_ID);

//定义生成的实体类中日期类型
gc.setDateType(DateType.ONLY_DATE);

//开启Swagger2
gc.setSwagger2(true);

mpg.setGlobalConfig(gc);


// 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://192.168.0.112:3306/online?useUnicode=true&useSSL=false&characterEncoding=utf8");
// dsc.setSchemaName("public");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("123456");
mpg.setDataSource(dsc);

// 包配置
PackageConfig pc = new PackageConfig();

pc.setModuleName("eduservice");
pc.setParent("com.online.edu");

pc.setController("controller");
pc.setService("service");
pc.setEntity("entity");
pc.setMapper("mapper");

mpg.setPackageInfo(pc);

// 策略配置
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);
//restful api风格控制器
strategy.setRestControllerStyle(true);
//url中驼峰转连字符
strategy.setControllerMappingHyphenStyle(true);

mpg.setStrategy(strategy);

mpg.execute();
}
}

5.4.1. 自动生成

5.4.2. EduTeacher

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package com.online.edu.eduservice.entity;

import com.baomidou.mybatisplus.annotation.*;

import java.util.Date;

import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

/**
* <p>
*
* </p>
*
* @author Wang T
* @since 2019-09-22
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="EduTeacher对象", description="")
public class EduTeacher implements Serializable {

private static final long serialVersionUID=1L;

@ApiModelProperty(value = "讲师ID")
@TableId(value = "id", type = IdType.ASSIGN_ID)
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;

@TableLogic
@ApiModelProperty(value = "逻辑删除 1 表示删除,0 表示未删除")
@TableField(fill = FieldFill.INSERT)
private Boolean isDeleted;

@ApiModelProperty(value = "创建时间")
@TableField(fill = FieldFill.INSERT)
private Date gmtCreate;

@ApiModelProperty(value = "更新时间")
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date gmtModified;
}

5.4.3. EduTeacherMapper

1
2
3
public interface EduTeacherMapper extends BaseMapper<EduTeacher> {

}

5.4.4. EduTeacherService

1
2
3
public interface EduTeacherService extends IService<EduTeacher> {

}

5.4.5. ServiceImpl

1
2
3
4
5
public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
protected Log log = LogFactory.getLog(this.getClass());
@Autowired
protected M baseMapper;
}

5.4.6. EduTeacherServiceImpl

说明service中已注入mapper

1
2
3
4
@Service
public class EduTeacherServiceImpl extends ServiceImpl<EduTeacherMapper, EduTeacher> implements EduTeacherService {

}

5.5. 自动填充-MetaObjectHandler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.online.edu.eduservice.handler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
public class myMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject,"gmtCreate", Date.class,new Date());
this.strictInsertFill(metaObject,"gmtModified", Date.class,new Date());
this.strictInsertFill(metaObject,"isDeleted",Boolean.class,false);
}

@Override
public void updateFill(MetaObject metaObject) {
this.strictUpdateFill(metaObject,"gmtModified", Date.class,new Date());
}
}

5.6. 自定义配置类-EduTeacherConfigurer

用于扫描mapper包

1
2
3
4
5
6
7
8
9
10
11
12
package com.online.edu.eduservice.config;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@EnableTransactionManagement
@Configuration
@MapperScan("com.online.edu.eduservice.mapper")
public class EduTeacherConfigurer {

}

5.7. 配置全局时间格式

1
2
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8

5.8. 测试CRUD操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package com.online.edu.eduservice.controller;


import com.online.edu.eduservice.entity.EduTeacher;
import com.online.edu.eduservice.service.EduTeacherService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
* <p>
* 前端控制器
* </p>
*
* @author Wang T
* @since 2019-09-09
*/
@RestController
@RequestMapping("/eduservice/edu-teacher")
public class EduTeacherController {

@Autowired
EduTeacherService eduTeacherService;

@PutMapping("/insert")
public boolean insertTeacher(){
EduTeacher teacher = new EduTeacher();
teacher.setName("严蔚敏");
teacher.setIntro("毕业于清华大学,数据结构与算法分析书作者");
teacher.setCareer("具备深厚的算法分析功底,教学经验丰富");
teacher.setLevel(2);

boolean flag=eduTeacherService.save(teacher);
return flag;
}

@GetMapping("/list")
public List<EduTeacher> selectAll(){
return eduTeacherService.list(null);
}

@ApiOperation(value = "根据ID删除讲师")
@DeleteMapping("/delete/{id}")
public boolean deletebyId(@PathVariable String id){
boolean flag = eduTeacherService.removeById(id);
return flag;
}

@PostMapping("/update")
public boolean updateTeacher(){

EduTeacher teacher = new EduTeacher();
teacher.setName("张宇");
teacher.setId("1233363623183699969");
teacher.setIntro("数一讲师");
boolean flag = eduTeacherService.updateById(teacher);
return flag;
}
}

5.9. 自动填充时间

新建handler.EduTeacherHandler并@Component(注册)到容器中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.online.edu.eduservice.handler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
public class EduTeacherHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject,"gmtCreate", Date.class,new Date());
this.strictInsertFill(metaObject,"gmtModified", Date.class,new Date());
this.strictInsertFill(metaObject,"isDeleted",Boolean.class,false);
}

@Override
public void updateFill(MetaObject metaObject) {

this.strictUpdateFill(metaObject,"gmtModified",Date.class,new Date());
}
}

5.10. 自动生成Api文档–Swagger2

新建配置类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.online.edu.eduservice.config;

import com.google.common.base.Predicates;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
public class Swagger2Config {

@Bean
public Docket webApiConfig(){
return new Docket(DocumentationType.SWAGGER_2)
.groupName("webApi")
.apiInfo(webApiInfo())
.select()
.build();
}


public ApiInfo webApiInfo(){

return new ApiInfoBuilder()
.title("网站-讲师管理API文档")
.description("本文档描述了课程中心微服务接口定义")
.version("1.0")
.contact(new Contact("Wang T","https://www.runaccpeted.com","1@qq.com"))
.build();
}
}

访问

http://localhost:8080/swagger-ui.html

5.11. 统一返回数据

返回数据采用educomm包中的R类

1
2
3
4
5
6
@ApiOperation(value = "所有讲师列表")
@GetMapping("/list")
public R selectAll(){
List<EduTeacher> teachers =eduTeacherService.list(null);
return R.ok().data("items,teachers);
}

5.12. 分页查询

1
2
3
4
5
6
7
8
9
10
11
//分页
@GetMapping("/pageList/{current}/{size}")
public R getPageTeacherList(@PathVariable Long current,@PathVariable Long size){
Page<EduTeacher> page = new Page<>(current,size);
eduTeacherService.page(page, null);
//当前页数据
List<EduTeacher> records = page.getRecords();
//所有记录数
Long total = page.getTotal();
return R.ok().data("total",total).data("p"+current,records);
}

5.12.1. 注册分页需要的PaginationInterceptor Bean

就放在配置类中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.online.edu.eduservice.config;

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@EnableTransactionManagement
@Configuration
@MapperScan("com.online.edu.eduservice.mapper")
public class EduTeacherConfigurer {

@Bean
public PaginationInterceptor paginationInterceptor(){
return new PaginationInterceptor();
}
}

5.13. 多条件查询

5.13.1. 查询字段打包QueryTeacher

将要查询的字段包装建一个类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.online.edu.eduservice.entity.query;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

@Data
@ApiModel("查询封装对象")
public class QueryTeacher {
@ApiModelProperty(value = "讲师")
private String name;
@ApiModelProperty(value = "讲师头衔")
private String level;
@ApiModelProperty(value = "开课时间")
private String begin;
@ApiModelProperty(value = "下播时间")
private String end;
}

5.13.2. 条件分页-service层

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package com.online.edu.eduservice.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.online.edu.eduservice.entity.EduTeacher;
import com.online.edu.eduservice.entity.query.QueryTeacher;
import com.online.edu.eduservice.mapper.EduTeacherMapper;
import com.online.edu.eduservice.service.EduTeacherService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

@Service
public class EduTeacherServiceImpl extends ServiceImpl<EduTeacherMapper, EduTeacher> implements EduTeacherService {

//条件分页
@Override
public void pageListCondition(Page<EduTeacher> pageTeacher, QueryTeacher queryTeacher) {
//查询条件为空
if(queryTeacher == null){
baseMapper.selectPage(pageTeacher,null);
return;
}
//查询条件可能为单个或多个
String name = queryTeacher.getName();
String level = queryTeacher.getLevel();
String begin = queryTeacher.getBegin();
String end = queryTeacher.getEnd();

QueryWrapper<EduTeacher> wrapper = new QueryWrapper<>();
if(!StringUtils.isEmpty(name)){
wrapper.like("name",name);
}
if (!StringUtils.isEmpty(level)){
wrapper.eq("level",level);
}
//>=时间
if (!StringUtils.isEmpty(begin)){
wrapper.ge("gmt_create",begin);
}
//<=时间
if (!StringUtils.isEmpty(end)){
wrapper.le("gmt_create",end);
}
baseMapper.selectPage(pageTeacher,wrapper);
}
}

5.13.3. controller层

1
2
3
4
5
6
7
8
//多条件查询
@GetMapping("/moreCondtionPageList/{current}/{size}")
public R MoreCondtionPageList(@PathVariable Long current, @PathVariable Long size, QueryTeacher queryTeacher){
Page<EduTeacher> pageTeacher = new Page<>(current,size);
eduTeacherService.pageListCondition(pageTeacher,queryTeacher);
List<EduTeacher> teachers = pageTeacher.getRecords();
return R.ok().data("items",teachers);
}

5.13.4. 在swagger-ui上查询

sql语句

1
2
3
==>  Preparing: SELECT id,name,intro,career,level,avatar,sort,is_deleted,gmt_create,gmt_modified FROM edu_teacher WHERE is_deleted=0 AND (level = ? AND gmt_create >= ? AND gmt_create <= ?) LIMIT ?,? 
==> Parameters: 2(String), 2018-03-30 17:15:57(String), 2019-02-22 23:37:44(String), 0(Long), 3(Long)
<== Total: 3

5.13.5. 将QueryTeacher直接封装为json

@RequestBody(required = false) 直接包装为json传输,请求方式必须改为Post

1
2
3
4
5
6
7
8
9
10
11
12
//多条件查询
@ApiOperation("多条件查询讲师列表")
@PostMapping("/moreCondtionPageList/{current}/{size}")
public R MoreCondtionPageList(
@ApiParam(value = "当前页") @PathVariable Long current,
@ApiParam(value = "页内记录数") @PathVariable Long size,
@RequestBody(required = false) QueryTeacher queryTeacher){
Page<EduTeacher> pageTeacher = new Page<>(current,size);
eduTeacherService.pageListCondition(pageTeacher,queryTeacher);
List<EduTeacher> teachers = pageTeacher.getRecords();
return R.ok().data("items",teachers);
}

查询

sql语句

1
2
==>  Preparing: SELECT id,name,intro,career,level,avatar,sort,is_deleted,gmt_create,gmt_modified FROM edu_teacher WHERE is_deleted=0 AND (name LIKE ?) LIMIT ?,? 
==> Parameters: %刘%(String), 0(Long), 5(Long)

5.14. 添加和修改讲师

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@ApiOperation(value = "添加新的讲师")
@PostMapping("/insertTeacher")
public R insertTeacher(@ApiParam(value = "讲师信息")@RequestBody EduTeacher eduTeacher){
boolean flag=eduTeacherService.save(eduTeacher);
if (flag){
return R.ok();
}else{
return R.error();
}
}

@ApiOperation("根据id查询讲师信息")
@GetMapping("/selectTeacher/{id}")
public R selectById(@ApiParam("讲师ID") @PathVariable String id){
EduTeacher teacher = eduTeacherService.getById(id);
return R.ok().data("items",teacher);
}

@ApiOperation("更新讲师信息")
@PostMapping("/updateTeacher/{id}")
public R updateTeacher(@ApiParam(value = "讲师ID") @PathVariable String id,
@ApiParam(value = "讲师信息")@RequestBody EduTeacher eduTeacher ){

boolean flag = eduTeacherService.updateById(eduTeacher);
if (flag){
return R.ok();
}else{
return R.error();
}
}

5.15. 最终CRUD

5.16. 统一异常处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.online.edu.eduservice.exception;

import com.online.edu.common.R;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class GlobalExceptionHandler {

//针对所有异常
@ExceptionHandler(Exception.class)
public R error(Exception e){
e.printStackTrace();
return R.error().message("出现了异常 "+e.getMessage());
}

//特定异常
@ExceptionHandler(HttpMessageNotReadableException.class)
public R error(HttpMessageNotReadableException e){
return R.error().message("出现了特定异常 "+e.getMessage());
}
}

5.17. 自定义异常

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.online.edu.eduservice.exception;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor //无参构造器
@AllArgsConstructor //有参构造器
public class EduException extends RuntimeException{

//状态码
private Integer code;

//异常信息
private String message;
}

5.17.1. 处理自定义异常

1
2
3
4
5
//自定义异常
@ExceptionHandler(EduException.class)
public R error(EduException e){
return R.error().message(e.getMessage()).code(e.getCode());
}

5.17.2. 处理异常

1
2
3
4
5
try{
int a =3/0;
}catch(Exception e){
throw new EduException(20000,"执行自定义异常");
}

5.18. logback日志

5.18.1. 日志级别

ALL OFF DEBUG INFO WARN ERROR FATAL

5.18.2. logback-spring.xml

logback-spring.xml放到resources文件夹下

springboot可以自动识别并运行,生成log文件,默认的日志级别为INFO

本文结束  感谢您的阅读

Gitalking ...