微服务项目实战技术点汇总:“尚硅谷的谷粒在线教育” 一、教师管理模块

一、创建数据库和表(我们这里只使用edu_teacher表)

CREATE DATABASE `gulischool` CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';

# Host: localhost  (Version 5.7.19)
# Date: 2019-11-18 15:49:32
# Generator: MySQL-Front 6.1  (Build 1.26)


#
# Structure for table "edu_chapter"
#
use `gulischool`;


CREATE TABLE `edu_chapter` (
  `id` char(19) NOT NULL COMMENT '章节ID',
  `course_id` char(19) NOT NULL COMMENT '课程ID',
  `title` varchar(50) NOT NULL COMMENT '章节名称',
  `sort` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '显示排序',
  `gmt_create` datetime NOT NULL COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`),
  KEY `idx_course_id` (`course_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=COMPACT COMMENT='课程';

#
# Data for table "edu_chapter"
#

INSERT INTO `edu_chapter` VALUES ('1','14','第一章:HTML',0,'2019-01-01 12:27:40','2019-01-01 12:55:30'),('1181729226915577857','18','第七章:I/O流',70,'2019-10-09 08:32:58','2019-10-09 08:33:20'),('1192252428399751169','1192252213659774977','第一章节',0,'2019-11-07 09:28:25','2019-11-07 09:28:25'),('15','18','第一章:Java入门',0,'2019-01-01 12:27:40','2019-10-09 09:13:19'),('3','14','第二章:CSS',0,'2019-01-01 12:55:35','2019-01-01 12:27:40'),('32','18','第二章:控制台输入和输出',0,'2019-01-01 12:27:40','2019-01-01 12:27:40'),('44','18','第三章:控制流',0,'2019-01-01 12:27:40','2019-01-01 12:27:40'),('48','18','第四章:类的定义',0,'2019-01-01 12:27:40','2019-01-01 12:27:40'),('63','18','第五章:数组',0,'2019-01-01 12:27:40','2019-01-01 12:27:40'),('64','18','第六章:继承',61,'2019-01-01 12:27:40','2019-10-09 08:32:47');

#
# Structure for table "edu_comment"
#

CREATE TABLE `edu_comment` (
  `id` char(19) NOT NULL COMMENT '讲师ID',
  `course_id` varchar(19) NOT NULL DEFAULT '' COMMENT '课程id',
  `teacher_id` char(19) NOT NULL DEFAULT '' COMMENT '讲师id',
  `member_id` varchar(19) NOT NULL DEFAULT '' COMMENT '会员id',
  `nickname` varchar(50) DEFAULT NULL COMMENT '会员昵称',
  `avatar` varchar(255) DEFAULT NULL COMMENT '会员头像',
  `content` varchar(500) DEFAULT NULL COMMENT '评论内容',
  `is_deleted` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '逻辑删除 1(true)已删除, 0(false)未删除',
  `gmt_create` datetime NOT NULL COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`),
  KEY `idx_course_id` (`course_id`),
  KEY `idx_teacher_id` (`teacher_id`),
  KEY `idx_member_id` (`member_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='评论';

#
# Data for table "edu_comment"
#

INSERT INTO `edu_comment` VALUES ('1194499162790211585','1192252213659774977','1189389726308478977','1','小三123','http://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83eoj0hHXhgJNOTSOFsS4uZs8x1ConecaVOB8eIl115xmJZcT4oCicvia7wMEufibKtTLqiaJeanU2Lpg3w/132','课程很好',0,'2019-11-13 14:16:08','2019-11-13 14:16:08'),('1194898406466420738','1192252213659774977','1189389726308478977','1','小三123','http://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83eoj0hHXhgJNOTSOFsS4uZs8x1ConecaVOB8eIl115xmJZcT4oCicvia7wMEufibKtTLqiaJeanU2Lpg3w/132','11',0,'2019-11-14 16:42:35','2019-11-14 16:42:35'),('1194898484388200450','1192252213659774977','1189389726308478977','1','小三123','http://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83eoj0hHXhgJNOTSOFsS4uZs8x1ConecaVOB8eIl115xmJZcT4oCicvia7wMEufibKtTLqiaJeanU2Lpg3w/132','111',0,'2019-11-14 16:42:53','2019-11-14 16:42:53'),('1195251020861317122','1192252213659774977','1189389726308478977','1',NULL,NULL,'2233',0,'2019-11-15 16:03:45','2019-11-15 16:03:45'),('1195251382720700418','1192252213659774977','1189389726308478977','1',NULL,NULL,'4455',0,'2019-11-15 16:05:11','2019-11-15 16:05:11'),('1195252819177570306','1192252213659774977','1189389726308478977','1','小三1231','http://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83eoj0hHXhgJNOTSOFsS4uZs8x1ConecaVOB8eIl115xmJZcT4oCicvia7wMEufibKtTLqiaJeanU2Lpg3w/132','55',0,'2019-11-15 16:10:53','2019-11-15 16:10:53'),('1195252899448160258','1192252213659774977','1189389726308478977','1','小三1231','http://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83eoj0hHXhgJNOTSOFsS4uZs8x1ConecaVOB8eIl115xmJZcT4oCicvia7wMEufibKtTLqiaJeanU2Lpg3w/132','55',0,'2019-11-15 16:11:13','2019-11-15 16:11:13'),('1195252920587452417','1192252213659774977','1189389726308478977','1','小三1231','http://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83eoj0hHXhgJNOTSOFsS4uZs8x1ConecaVOB8eIl115xmJZcT4oCicvia7wMEufibKtTLqiaJeanU2Lpg3w/132','223344',0,'2019-11-15 16:11:18','2019-11-15 16:11:18'),('1195262128095559681','14','1189389726308478977','1','小三1231','http://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83eoj0hHXhgJNOTSOFsS4uZs8x1ConecaVOB8eIl115xmJZcT4oCicvia7wMEufibKtTLqiaJeanU2Lpg3w/132','11',0,'2019-11-15 16:47:53','2019-11-15 16:47:53'),('1196264505170767874','1192252213659774977','1189389726308478977','1','小三1231','http://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83eoj0hHXhgJNOTSOFsS4uZs8x1ConecaVOB8eIl115xmJZcT4oCicvia7wMEufibKtTLqiaJeanU2Lpg3w/132','666666',0,'2019-11-18 11:10:58','2019-11-18 11:10:58');

#
# Structure for table "edu_course"
#

CREATE TABLE `edu_course` (
  `id` char(19) NOT NULL COMMENT '课程ID',
  `teacher_id` char(19) NOT NULL COMMENT '课程讲师ID',
  `subject_id` char(19) NOT NULL COMMENT '课程专业ID',
  `subject_parent_id` char(19) NOT NULL COMMENT '课程专业父级ID',
  `title` varchar(50) NOT NULL COMMENT '课程标题',
  `price` decimal(10,2) unsigned NOT NULL DEFAULT '0.00' COMMENT '课程销售价格,设置为0则可免费观看',
  `lesson_num` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '总课时',
  `cover` varchar(255) CHARACTER SET utf8 NOT NULL COMMENT '课程封面图片路径',
  `buy_count` bigint(10) unsigned NOT NULL DEFAULT '0' COMMENT '销售数量',
  `view_count` bigint(10) unsigned NOT NULL DEFAULT '0' COMMENT '浏览数量',
  `version` bigint(20) unsigned NOT NULL DEFAULT '1' COMMENT '乐观锁',
  `status` varchar(10) NOT NULL DEFAULT 'Draft' COMMENT '课程状态 Draft未发布  Normal已发布',
  `is_deleted` tinyint(3) DEFAULT NULL COMMENT '逻辑删除 1(true)已删除, 0(false)未删除',
  `gmt_create` datetime NOT NULL COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`),
  KEY `idx_title` (`title`),
  KEY `idx_subject_id` (`subject_id`),
  KEY `idx_teacher_id` (`teacher_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=COMPACT COMMENT='课程';

#
# Data for table "edu_course"
#

INSERT INTO `edu_course` VALUES ('1192252213659774977','1189389726308478977','1178214681139539969','1178214681118568449','java基础课程:test',0.01,2,'https://guli-file-190513.oss-cn-beijing.aliyuncs.com/cover/default.gif',4,387,1,'Normal',0,'2019-11-07 09:27:33','2019-11-18 13:35:03'),('14','1189389726308478977','1101348944971091969','1101348944920760321','XHTML CSS2 JS整站制作教程课程学习',0.00,3,'http://guli-file.oss-cn-beijing.aliyuncs.com/cover/2019/03/13/d0086eb0-f2dc-45f7-bba1-744d95e5be0f.jpg',3,44,15,'Normal',0,'2018-04-02 18:33:34','2019-11-16 21:21:45'),('15','1189389726308478977','1101348944971091969','1101348944920760321','HTML5入门课程学习',0.00,23,'http://guli-file.oss-cn-beijing.aliyuncs.com/cover/2019/03/13/22997b8e-3606-4d2e-9b4f-09f48418b6e4.jpg',0,51,17,'Normal',0,'2018-04-02 18:34:32','2019-11-12 10:19:20'),('18','1189389726308478977','1178214681139539969','1178214681118568449','Java精品课程',0.01,20,'http://guli-file.oss-cn-beijing.aliyuncs.com/cover/2019/03/06/866e9aca-b530-4f71-a690-72d4a4bfd1e7.jpg',151,737,6,'Normal',0,'2018-04-02 21:28:46','2019-11-18 11:14:52');

#
# Structure for table "edu_course_collect"
#

CREATE TABLE `edu_course_collect` (
  `id` char(19) NOT NULL COMMENT '收藏ID',
  `course_id` char(19) NOT NULL COMMENT '课程讲师ID',
  `member_id` char(19) NOT NULL DEFAULT '' COMMENT '课程专业ID',
  `is_deleted` tinyint(3) NOT NULL DEFAULT '0' COMMENT '逻辑删除 1(true)已删除, 0(false)未删除',
  `gmt_create` datetime NOT NULL COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=COMPACT COMMENT='课程收藏';

#
# Data for table "edu_course_collect"
#

INSERT INTO `edu_course_collect` VALUES ('1196269345666019330','1192252213659774977','1',1,'2019-11-18 11:30:12','2019-11-18 11:30:12');

#
# Structure for table "edu_course_description"
#

CREATE TABLE `edu_course_description` (
  `id` char(19) NOT NULL COMMENT '课程ID',
  `description` text COMMENT '课程简介',
  `gmt_create` datetime NOT NULL COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='课程简介';

#
# Data for table "edu_course_description"
#

INSERT INTO `edu_course_description` VALUES ('1104870479077879809','<p>11</p>','2019-03-11 06:23:44','2019-03-11 06:23:44'),('1192252213659774977','<p>测试</p>','2019-11-07 09:27:33','2019-11-13 16:21:28'),('14','','2019-03-13 06:04:43','2019-03-13 06:05:33'),('15','','2019-03-13 06:03:33','2019-03-13 06:04:22'),('18','<p>本套Java视频完全针对零基础学员,课堂实录,自发布以来,好评如潮!Java视频中注重与学生互动,讲授幽默诙谐、细致入微,覆盖Java基础所有核心知识点,同类Java视频中也是代码量大、案例多、实战性强的。同时,本Java视频教程注重技术原理剖析,深入JDK源码,辅以代码实战贯穿始终,用实践驱动理论,并辅以必要的代码练习。</p>\n<p>------------------------------------</p>\n<p>视频特点:</p>\n<p>通过学习本Java视频教程,大家能够真正将Java基础知识学以致用、活学活用,构架Java编程思想,牢牢掌握\"源码级\"的Javase核心技术,并为后续JavaWeb等技术的学习奠定扎实基础。<br /><br />1.通俗易懂,细致入微:每个知识点高屋建瓴,深入浅出,简洁明了的说明问题<br />2.具实战性:全程真正代码实战,涵盖上百个企业应用案例及练习<br />3.深入:源码分析,更有 Java 反射、动态代理的实际应用等<br />4.登录尚硅谷官网,技术讲师免费在线答疑</p>','2019-03-06 18:06:36','2019-10-30 19:58:36');

#
# Structure for table "edu_subject"
#

CREATE TABLE `edu_subject` (
  `id` char(19) NOT NULL COMMENT '课程类别ID',
  `title` varchar(10) NOT NULL COMMENT '类别名称',
  `parent_id` char(19) NOT NULL DEFAULT '0' COMMENT '父ID',
  `sort` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '排序字段',
  `gmt_create` datetime NOT NULL COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`),
  KEY `idx_parent_id` (`parent_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=COMPACT COMMENT='课程科目';

#
# Data for table "edu_subject"
#

INSERT INTO `edu_subject` VALUES ('1178214681118568449','后端开发','0',1,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681139539969','Java','1178214681118568449',1,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681181483010','前端开发','0',3,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681210843137','JavaScript','1178214681181483010',4,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681231814658','云计算','0',5,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681252786178','Docker','1178214681231814658',5,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681294729217','Linux','1178214681231814658',6,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681324089345','系统/运维','0',7,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681353449473','Linux','1178214681324089345',7,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681382809602','Windows','1178214681324089345',8,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681399586817','数据库','0',9,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681428946945','MySQL','1178214681399586817',9,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681454112770','MongoDB','1178214681399586817',10,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681483472898','大数据','0',11,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681504444418','Hadoop','1178214681483472898',11,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681529610242','Spark','1178214681483472898',12,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681554776066','人工智能','0',13,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681584136193','Python','1178214681554776066',13,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681613496321','编程语言','0',14,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178214681626079234','Java','1178214681613496321',14,'2019-09-29 15:47:25','2019-09-29 15:47:25'),('1178585108407984130','Python','1178214681118568449',2,'2019-09-30 16:19:22','2019-09-30 16:19:22'),('1178585108454121473','HTML/CSS','1178214681181483010',3,'2019-09-30 16:19:22','2019-09-30 16:19:22');

#
# Structure for table "edu_teacher"
#

CREATE TABLE `edu_teacher` (
  `id` char(19) NOT NULL COMMENT '讲师ID',
  `name` varchar(20) NOT NULL COMMENT '讲师姓名',
  `intro` varchar(500) NOT NULL DEFAULT '' COMMENT '讲师简介',
  `career` varchar(500) DEFAULT NULL 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(true)已删除, 0(false)未删除',
  `gmt_create` datetime NOT NULL COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='讲师';

#
# Data for table "edu_teacher"
#

INSERT INTO `edu_teacher` VALUES ('1','张三','近年主持国家自然科学基金(6项)、江苏省重大科技成果转化项目(5项)、江苏省产学研前瞻性联合研究项目(3项)、省工业科技支撑、省高技术、省自然科学基金等省部级及其企业的主要科研项目40多个,多个项目在企业成功转化,产生了较好的经济、社会和环境效益。积极开展产学研科技合作,并与省内16家企业建立了江苏省研究生工作站,其中6家为江苏省优秀研究生工作站','高级',1,'https://guli-file-190513.oss-cn-beijing.aliyuncs.com/avatar/default.jpg',0,0,'2019-10-30 14:18:46','2019-11-12 13:36:36'),('1189389726308478977','晴天','高级讲师简介','高级讲师资历',2,'https://online-teach-file.oss-cn-beijing.aliyuncs.com/teacher/2019/10/30/de47ee9b-7fec-43c5-8173-13c5f7f689b2.png',1,0,'2019-10-30 11:53:03','2019-10-30 11:53:03'),('1189390295668469762','李刚','高级讲师简介','高级讲师',2,'https://online-teach-file.oss-cn-beijing.aliyuncs.com/teacher/2019/10/30/b8aa36a2-db50-4eca-a6e3-cc6e608355e0.png',2,0,'2019-10-30 11:55:19','2019-11-12 13:37:52'),('1189426437876985857','王二','高级讲师简介','高级讲师',1,'https://online-teach-file.oss-cn-beijing.aliyuncs.com/teacher/2019/11/08/e44a2e92-2421-4ea3-bb49-46f2ec96ef88.png',0,0,'2019-10-30 14:18:56','2019-11-12 13:37:35'),('1189426464967995393','王五','高级讲师简介','高级讲师',1,'https://online-teach-file.oss-cn-beijing.aliyuncs.com/teacher/2019/10/30/65423f14-49a9-4092-baf5-6d0ef9686a85.png',0,0,'2019-10-30 14:19:02','2019-11-12 13:37:18'),('1192249914833055746','李四','高级讲师简介','高级讲师',1,'https://online-teach-file.oss-cn-beijing.aliyuncs.com/teacher/2019/11/07/91871e25-fd83-4af6-845f-ea8d471d825d.png',0,0,'2019-11-07 09:18:25','2019-11-12 13:37:01'),('1192327476087115778','1222-12-12','1111','11',1,'https://online-teach-file.oss-cn-beijing.aliyuncs.com/teacher/2019/11/08/5805c6cd-c8ad-4a77-aafd-d2e083bfd8a4.png',0,1,'2019-11-07 14:26:37','2019-11-11 16:26:26'),('1195337453429129218','test','sdfsdf','sdfdf',1,'https://guli-file-190513.oss-cn-beijing.aliyuncs.com/avatar/default.jpg',0,1,'2019-11-15 21:47:12','2019-11-15 21:47:27');

#
# Structure for table "edu_video"
#

CREATE TABLE `edu_video` (
  `id` char(19) NOT NULL COMMENT '视频ID',
  `course_id` char(19) NOT NULL COMMENT '课程ID',
  `chapter_id` char(19) NOT NULL COMMENT '章节ID',
  `title` varchar(50) NOT NULL COMMENT '节点名称',
  `video_source_id` varchar(100) DEFAULT NULL COMMENT '云端视频资源',
  `video_original_name` varchar(100) DEFAULT NULL COMMENT '原始文件名称',
  `sort` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '排序字段',
  `play_count` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '播放次数',
  `is_free` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '是否可以试听:0收费 1免费',
  `duration` float NOT NULL DEFAULT '0' COMMENT '视频时长(秒)',
  `status` varchar(20) NOT NULL DEFAULT 'Empty' COMMENT 'Empty未上传 Transcoding转码中  Normal正常',
  `size` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '视频源文件大小(字节)',
  `version` bigint(20) unsigned NOT NULL DEFAULT '1' COMMENT '乐观锁',
  `gmt_create` datetime NOT NULL COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`),
  KEY `idx_course_id` (`course_id`),
  KEY `idx_chapter_id` (`chapter_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=COMPACT COMMENT='课程视频';

#
# Data for table "edu_video"
#

INSERT INTO `edu_video` VALUES ('1182499307429339137','18','32','第一节','','',0,0,0,0,'',0,1,'2019-10-11 11:32:59','2019-10-11 11:57:38'),('1185312444399071234','14','1','12','','',0,0,0,0,'Empty',0,1,'2019-10-19 05:51:23','2019-10-19 05:51:33'),('1189434737808990210','18','44','测试','','',1,0,0,0,'Empty',0,1,'2019-10-30 14:51:55','2019-10-30 14:51:55'),('1189471423678939138','18','1181729226915577857','test','2b887dc9584d4dc68908780ec57cd3b9','视频',1,0,0,0,'Empty',0,1,'2019-10-30 17:17:41','2019-10-30 17:17:41'),('1189476403626409986','18','1181729226915577857','22','5155c73dc112475cbbddccf4723f7cef','视频.mp4',0,0,0,0,'Empty',0,1,'2019-10-30 17:37:29','2019-10-30 17:37:29'),('1192252824606289921','1192252213659774977','1192252428399751169','第一课时','756cf06db9cb4f30be85a9758b19c645','eae2b847ef8503b81f5d5593d769dde2.mp4',0,0,0,0,'Empty',0,1,'2019-11-07 09:29:59','2019-11-07 09:29:59'),('1192628092797730818','1192252213659774977','1192252428399751169','第二课时','2a02d726622f4c7089d44cb993c531e1','eae2b847ef8503b81f5d5593d769dde2.mp4',0,0,1,0,'Empty',0,1,'2019-11-08 10:21:10','2019-11-08 10:21:22'),('1192632495013380097','1192252213659774977','1192252428399751169','第三课时','4e560c892fdf4fa2b42e0671aa42fa9d','eae2b847ef8503b81f5d5593d769dde2.mp4',0,0,1,0,'Empty',0,1,'2019-11-08 10:38:40','2019-11-08 10:38:40'),('1194117638832111617','1192252213659774977','1192252428399751169','第四课时','4e560c892fdf4fa2b42e0671aa42fa9d','eae2b847ef8503b81f5d5593d769dde2.mp4',0,0,0,0,'Empty',0,1,'2019-11-12 13:00:05','2019-11-12 13:00:05'),('1196263770832023554','1192252213659774977','1192252428399751169','第五课时','27d21158b0834cb5a8d50710937de330','eae2b847ef8503b81f5d5593d769dde2.mp4',5,0,0,0,'Empty',0,1,'2019-11-18 11:08:03','2019-11-18 11:08:03'),('17','18','15','第一节:Java简介','196116a6fee742e1ba9f6c18f65bd8c1','1',1,1000,1,100,'Draft',0,1,'2019-01-01 13:08:57','2019-10-11 11:26:39'),('18','18','15','第二节:表达式和赋值语句','2d99b08ca0214909899910c9ba042d47','7 - How Do I Find Time for My ',2,999,1,100,'Draft',0,1,'2019-01-01 13:09:02','2019-03-08 03:30:27'),('19','18','15','第三节:String类','51120d59ddfd424cb5ab08b44fc8b23a','eae2b847ef8503b81f5d5593d769dde2.mp4',3,888,0,100,'Draft',0,1,'2019-01-01 13:09:05','2019-11-12 12:50:45'),('20','18','15','第四节:程序风格','2a38988892d84df598752226c50f3fa3','00-day10总结.avi',4,666,0,100,'Draft',0,1,'2019-01-01 13:09:05','2019-10-11 09:20:09');

二、环境搭建

项目结构介绍

gulishool:在线教学根目录(父工程),管理四个子模块:

    canal-client:canal数据库表同步模块(统计同步数据)

    common:公共模块父节点

        common-util:工具类模块,所有模块都可以依赖于它

        service-base:service服务的base包,包含service服务的公共配置类,所有service模块依赖于它

        spring-security:认证与授权模块,需要认证授权的service服务依赖于它

    infrastructure:基础服务模块父节点

        api-gateway:api网关服务

    service:api接口服务父节点

		service-acl:用户权限管理api接口服务(用户管理、角色管理和权限管理等)
		
		service-cms:cms api接口服务
		
		service-edu:教学相关api接口服务
		
		service-msm:短信api接口服务
		
		service-order:订单相关api接口服务
		
		service-oss:阿里云oss api接口服务
		
		service-statistics:统计报表api接口服务
		
		service-ucenter:会员api接口服务
		
		service-vod:视频点播api接口服务

1、父工程

1、创建总工程(父工程)(spring boot工程,用来存储依赖)
在这里插入图片描述

2、配置pom.xml文件

 <!--spring boot 父依赖-->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.6.RELEASE</version>
</parent>

<!--打包方式为pom-->
<packaging>pom</packaging>

<!--依赖-->
<dependencies>
    <!--spring boot web-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>2.2.6.RELEASE</version>
    </dependency>
    <!--spring boot test-->
	 <dependency>
	     <groupId>org.springframework.boot</groupId>
	     <artifactId>spring-boot-starter-test</artifactId>
	     <version>2.2.6.RELEASE</version>
	     <scope>test</scope>
	 </dependency>
    <!--lombook-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.12</version>
        <scope>provided</scope>
    </dependency>
</dependencies>
<!--管理依赖-->
<dependencyManagement>
    <dependencies>
        <!--spring cloud-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Hoxton.SR4</version>
            <type>pom</type>
            <scope>import</scope>
            <!--注意这里使用<scope>import</scope>是为了预防jar包依赖引用
            import只能用于<dependencyManagement>中并且设置<type>pom</type>的依赖中。
            可以使子模块不使用父模块的引用jar包
            如果不设置此项,就会报错(你可以注释掉试试),因为子模块在引用某些jar包时,会引用父模块中的jar包
            从而jar包冲突-->
        </dependency>
    </dependencies>
</dependencyManagement>

2、子模块service,当做api接口服务父节点

1、创建子模块service(一个普通的maven工程)在这里插入图片描述

2、引入依赖

 <!--mybatis plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.1</version>
        </dependency>
        <!--mybatis plus 代码生成器-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.3.1</version>
        </dependency>
        <!--添加 模板引擎 依赖,MyBatis-Plus 支持 Velocity(默认):这是代码生成器需要的依赖-->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.2</version>
        </dependency>
        <!--代码生成器需要的依赖,swagger,处理ApiModel-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

3、创建service的子模块service-edu微服务

1、创建maven模块在这里插入图片描述

4、配置application.yml文件

server:
  port: 8001 #微服务端口号为8001
spring:
  application:
    name: service-dev #服务名
  profiles:
    active: dev #环境设置 dev表示构建阶段,test表示测试阶段,prod表示发布阶段
  datasource: #数据源
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/gulischool?serverTimeZone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true
    username: root
    password: 123456
  jackson: #我们的时区是东八区,应该加8个小时,时区显示格式也需要改成我们想要的
   	date-format: yyyy-MM-DD HH:mm:ss
    time-zone: GMT+8

如果你之后报错,提示time_zone时区错误,请对数据库作如下设置

show variables like "%time_zone%";
set time_zone = '+8:00';
set global time_zone = '+8:00';
flush privileges;
以上是临时修改时区,重启后既重置
如果想永久修改时区,可以到你的mysql安装目录下,将my.ini中time_zone修改
如果你的版本是8.0以上,执行set persist time_zone='+8:00';命令即可

三、实现查询操作

1、使用mp(mybatis plus)的代码生成器,生成Controller,service,mapper等代码

创建一个类,然后填入如下内容:请根据我的注释改你的内容,比如包名,生成的表等等,每个人都不一样

package com.yzpnb.gennerator;

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;

/**
 * @author
 * @since 2018/12/13
 */
public class CodeGenerator {

    @Test
    public void run() {

        // 1、创建代码生成器
        AutoGenerator mpg = new AutoGenerator();

        // 2、全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir("D:\\IdeaProjects\\gulischool\\service\\service-edu" + "/src/main/java"); //输出目录,生成的代码最终输出的地方,请写你的项目的绝对路径
        gc.setAuthor("testjava");
        gc.setOpen(false); //生成后是否打开资源管理器
        gc.setFileOverride(false); //重新生成时文件是否覆盖
        gc.setServiceName("%sService");	//去掉Service接口的首字母I
        gc.setIdType(IdType.ID_WORKER_STR); //主键策略,ID_WORKER表示默认Integer,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/gulischool?serverTimeZone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("123456");
        dsc.setDbType(DbType.MYSQL);
        mpg.setDataSource(dsc);

        // 4、包配置(生成的包名)
        PackageConfig pc = new PackageConfig();
        pc.setParent("com.yzpnb");
        pc.setModuleName("eduservice"); //模块名 com.yzpnb.eduservice

        pc.setController("controller"); //com.yzpnb.eduservice.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();
    }
}

在这里插入图片描述在这里插入图片描述

2、创建启动类

在这里插入图片描述

3、创建mybatis plus配置类

package com.yzpnb.eduservice.config;

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

@Configuration
@MapperScan(value="com.yzpnb.eduservice.mapper")
public class MpConfiguration {

}

在这里插入图片描述

4、编写Controller

package com.yzpnb.eduservice.controller;


import com.yzpnb.eduservice.entity.EduTeacher;
import com.yzpnb.eduservice.service.EduTeacherService;
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 java.util.List;

/**
 * <p>
 * 讲师 前端控制器
 * </p>
 *
 * @author testjava
 * @since 2020-05-07
 */
@RestController //此注解功能和Controller相同,但是增加了Rest功能,也就是返回JSON数据,我们以往都是在方法上添加@ResponseBody注解,现在,可以省略这个注解了
@RequestMapping("/eduservice/eduteacher")//注意我这里设置的路径
public class EduTeacherController {

    /*注入service*/
    @Autowired
    EduTeacherService eduTeacherService;

    /**
     * 查询
     * REST风格
     * */
    //1、查询所有讲师数据
    @GetMapping("findAll")//这里没写@ResponseBody注解,是因为我的类使用的@ResrController注解,封装了这个注解
    public List<EduTeacher> findAll()
    {
        return eduTeacherService.list();//list方法是代码生成器帮我们生成的service接口继承的工具类提供的方法,用来查询所有数据
    }
}

5、测试环境是否成功

在这里插入图片描述

四、实现REST风格的删除

1、为实体类中逻辑删除字段添加注解

@ApiModelProperty(value = "逻辑删除 1(true)已删除, 0(false)未删除")
@TableLogic//逻辑删除
private Boolean isDeleted;

2、整合swagger

为什么整合swagger

我们如果想使用rest风格,则需要根据不同请求类型做出不同的反馈,因为方法名字都一样
	get请求,用来查询
	post请求,用来上传,新增数据
	delete请求,用来删除
	put请求,用来更新,修改数据
但是,我们只能处理get或post请求,如何能让我们处理delete和put请求呢
以前我们会从前端配置from表单之类的一些方式解决,不方便测试
所有有了swagger框架,可以帮我们生成、描述、调用和可视化RESTful风格的Web服务
优点:
	1、生成一个在线的接口文档(接口功能,参数类型,数据类型等)
	2、方便接口测试

1、创建一个全局模块(不创建也行,但是因为swagger是所有子模块微服务都要用到的,所以创建一个全局的就不用配置多次了,当然其它插件也可以配置到全局模块中)
在这里插入图片描述
2、配置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>gulischool</artifactId>
        <groupId>com.yzpnb</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>common</artifactId>
    <packaging>pom</packaging><!--打包方式为pom-->

    <dependencies>
        <!--redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>
        <!--mybatis plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.1</version>
        </dependency>
        <!--mybatis plus 代码生成器-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.3.1</version>
        </dependency>
        <!--添加 模板引擎 依赖,MyBatis-Plus 支持 Velocity(默认):这是代码生成器需要的依赖-->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.2</version>
        </dependency>
        <!--swagger-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    </dependencies>

</project>

3、创建三级子模块service_base用来存储整合的代码

package com.yzpnb.service_base_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;

import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.List;

@Configuration
@EnableSwagger2//表中此类为Swagger2
public class SwaggerConfig {
    @Bean
    public Docket webApiConfig() {
        List<Parameter> pars = new ArrayList<Parameter>();
        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("webApi")//分组名
                .apiInfo(webApiInfo())//在线文档的信息,传入ApiInfo对象,就是下面内个方法返回的对象
                .select()
                .paths(Predicates.not(PathSelectors.regex("/admin/.*")))//路径中包含admin时不显示信息
                .paths(Predicates.not(PathSelectors.regex("/error/.*")))
                .build();
    }

    private ApiInfo webApiInfo() {
        return new ApiInfoBuilder()
                .title("gulischool 接口 API 文档")
                .description("展示先做基础功能,后面再添加业务")
                .termsOfServiceUrl("https://www.yzpnb.com/aa/")
                .version("1.0")
                .contact(new Contact("Helen","http://yzpnb.com","915501928@qq.com"))
                .build();
    }

}

在这里插入图片描述
4、在service_edu中使用全局配置
在这里插入图片描述
5、启动类扫描swagger配置类(因为spring boot 自动扫描它的子文件或同级文件,而全局配置模块不是它的子文件,所以需要配置)

package com.yzpnb.eduservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@ComponentScan(basePackages={"com.yzpnb"})//这样它会将所有com.yzpnb包下内容扫描,而不只是扫描子文件或同级文件
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class,args);
    }
}

在这里插入图片描述
6、运行微服务并测试在这里插入图片描述
7、swagger的3个提示注解

@Api@ApiOperation@ApiParam三个常用注解,详细请看下面例子,下面例子并不能运行,只做讲解
@Api(value="标注在类上的解释信息")
public class EduTeacherController {
    /**
     * 删除
     * */
    //根据id删除
    @ApiOperation("标注在处理请求方法上的解释信息")
    @DeleteMapping("deleteById/{id}")
    public boolean deleteById(@ApiParam(name="id",value = "标注在请求方法参数上的解释信息",required = true) @PathVariable String id)
    {
        return eduTeacherService.removeById(id);//继承的方法,根据id删除数据
    }
}

五、返回结果(响应数据)统一规范

开发过程中,有时有多人共同开发,而每个人的习惯不同,写的接口规则也不同.
比如,A工程师喜欢用boolean表示成功与否,而B工程师喜欢01表示.
这时前端工程师的开发就非常麻烦。
而所有工程师遵循一个标准开发,就可以解决问题
当我们返回json字符串的时候,可以按一定规则统一化所有接口响应的数据,比如:
{
	"sucess":布尔值, 	//表示是否响应成功
	"code":数字,		//响应码
	"message":字符串,	//返回信息
	"data":HashMap,		//返回的数据
}
我们就以此为例

1、在全局模块中配置(因为所有接口都遵循此规范)在这里插入图片描述
2、定义一个接口,用来返回状态码

package com.yzpnb.common_utils;

public interface ResultCode {

    /**
     * 状态码
     *  20000:成功SUCCESS
     *  20001:失败ERROR
     */
    public static Integer SUCCESS =20000;

    public static Integer ERROR=20001;
}

在这里插入图片描述
3、定义一个类,来处理响应和返回统一数据

package com.yzpnb.common_utils;

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

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

@Data
public class Result {
    /**
     * 当我们返回json字符串的时候,可以按以下规则
     * {
     * 	"sucess":布尔值, 	//表示是否响应成功
     * 	"code":数字,		//响应码
     * 	"message":字符串,	//返回信息
     * 	"data":HashMap,		//返回的数据
     * }
     *
     * 创建成员变量
     */

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

    @ApiModelProperty(value="状态码")
    private Integer code;

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

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

    /**私有化构造方法:就是说除了Result类本身,其它类不能new Result类的对象了**/
    private Result(){}

    /**获取一个私有的Result对象。Result本身是可以new 对象,无论私有与否**/
    private static Result result=new Result();

    /**处理响应成功的静态方法**/
    public static Result ok(){
        result.setSuccess(true);            //设置为true,表示处理响应成功
        result.setCode(ResultCode.SUCCESS); //调用我们提供状态码的接口,设置状态码
        result.setMessage("成功");          //设置提示信息
        return result;                      //返回对象,外键不能new,只能通过静态方法获取对象

    }
    /**处理响应失败的静态方法**/
    public static Result error(){
        result.setSuccess(false);         //设置为false,表示处理响应失败
        result.setCode(ResultCode.ERROR); //调用我们提供状态码的接口,设置状态码
        result.setMessage("失败");        //设置提示信息
        return result;
    }

    /**设置值方法*/
    public Result succes(Boolean b){
        this.success=b;
        return this;
    }

    public Result code(Integer i){
        this.code=i;
        return this;
    }

    public Result message(String str){
        this.message=str;
        return this;
    }

    public Result data(String key ,Object value){
      	this.data.clear();//先清空,因为我这里是单例设计模式,data中数据永远都在
        this.data.put(key,value);
        return this;
    }

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

在这里插入图片描述
4、在微服务中使用统一配置(引入通用模块依赖)
在这里插入图片描述
5、将接口的返回值,统统更改为统一结果Result类对象

 /*注入service*/
    @Autowired
    EduTeacherService eduTeacherService;

    /**
     * 查询
     * REST风格
     * */
    //1、查询所有讲师数据
    @ApiOperation("标注在处理请求方法上的解释信息")
    @GetMapping("findAll")//这里没写@ResponseBody注解,是因为我的类使用的@ResrController注解,封装了这个注解
    public Result findAll()
    {
        //list方法是代码生成器帮我们生成的service接口继承的工具类提供的方法,用来查询所有数据
        //通过Result.ok()的形式获取Result对象,然后通过我们设置值的方法data添加一条数据
        return Result.ok().data("allEduTeacher",eduTeacherService.list());
    }

    /**
     * 删除
     * */
    //根据id删除
    @DeleteMapping("deleteById/{id}")
    public Result deleteById(@ApiParam(name="id",value = "标注在请求方法参数上的解释信息",required = true) @PathVariable String id)
    {
        if(eduTeacherService.removeById(id))//继承的方法,根据id删除数据,删除成功返回true,失败返回false
        {
            return Result.ok();
        }
        else{
            return Result.error();
        }

    }

在这里插入图片描述
6、测试
1、进入swagger-ui
在这里插入图片描述
2、测试查询在这里插入图片描述在这里插入图片描述在这里插入图片描述
3、测试删除
在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

六、分页查询

1、配置分页插件

 @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false
        // paginationInterceptor.setOverflow(false);
        // 设置最大单页限制数量,默认 500 条,-1 不受限制
        // paginationInterceptor.setLimit(500);
        // 开启 count 的 join 优化,只针对部分 left join
        paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
        return paginationInterceptor;
    }

在这里插入图片描述
2、编写controller接口

//2、分页查询讲师,其中所有@Api开头的注解都是swagger提供的,解释注解
    @ApiOperation(value="分页查询讲师")
    @GetMapping("limitSelect/{current}/{size}")
    public Result limitSelect(@ApiParam(name="current",value ="当前页",required=true)
                                @PathVariable("current") Long current,
                              @ApiParam(name="size",value="每页记录数")
                                @PathVariable("size") Long size){
        //1、创建page对象
        Page<EduTeacher> page=new Page<>(current,size);
        //2、通过接口中方法实现分页
        return Result.ok().data("limitEduTeacher",eduTeacherService.page(page));
    }

3、测试
在这里插入图片描述在这里插入图片描述

七、添加数据

1、自动填充(因为表中有两个字段,添加时间和修改时间)

1、实体类对应字段加注解

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

@ApiModelProperty(value = "更新时间")
@TableField(fill=FieldFill.INSERT_UPDATE)//创建和修改时更新
private Date gmtModified;

2、公有模块中,设置自动填充配置类

package com.yzpnb.service_base_handler;

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

import java.util.Date;

@Component//将组件注入到IOC容器
public class MyMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
    /**注意这里的监听字段gmtCreate和gmtModified是java属性名,不是字段名*/
        this.setFieldValByName("gmtCreate",new Date(),metaObject);
        this.setFieldValByName("gmtModified",new Date(),metaObject);
    }

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

在这里插入图片描述
3、编写controller接口

/**
     * 添加
     * */
    //1、添加讲师
    @ApiOperation("添加讲师")
    @PostMapping("insert")
    public Result insert(@ApiParam(name = "eduTeacher",value ="添加的json数据" )
                         @RequestBody EduTeacher eduTeacher)//@RequestBody可将传来的json字符串转换为指定对象
    {
        if(eduTeacherService.save(eduTeacher))
        {
            return Result.ok();
        }
        else
        {
            return Result.error();
        }

    }

4、测试
在这里插入图片描述在这里插入图片描述在这里插入图片描述

八、修改

说明:

修改字段时,我们必须避免脏读、幻读、不可重复读
而mybatis plus封装了乐观锁,也就是为数据库每条数据添加一个version 版本号,当版本号与用户
当前查询结果不匹配时,则无法修改。

我们修改时,也必须先查后改才行

那么对于没有遵循先查后改的,乐观锁不起作用,也就是说
==对于需要使用乐观锁的,你先查然后改即可,对于不需要乐观锁的,直接改就行了==

我们这里暂时用不到乐观锁,因为讲师每个是独立的,不会涉及到多个人操作同一条数据

1、编写controller接口

 /**
     * 修改
     * */
    @ApiOperation("根据id修改讲师信息")
    @PutMapping("updateEduTeacher")
    public Result updateEduTeacher(@ApiParam(name="eduTeacher",value="修改的讲师json")
                                   @RequestBody EduTeacher eduTeacher)
    {
        //2、修改
        if(eduTeacherService.updateById(eduTeacher)){
            return Result.ok();
        }
        else
        {
            return Result.error();
        }

    }

2、测试
在这里插入图片描述

十、处理异常,统一规范

1、通用异常

1、将统一响应规范的依赖引入到全局模块(此时 service_base将拥有common_utils的依赖)
在这里插入图片描述
2、公共模块通用异常类

package com.yzpnb.service_base_handler;

import com.yzpnb.common_utils.Result;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

@ControllerAdvice//全局异常处理、全局数据绑定、全局数据预处理
public class MyExceptionHandler {

    @ExceptionHandler(Exception.class)//表示此方法对所有异常都有效
    @ResponseBody//将对象封装成json数据返回
    public Result error(Exception e){
        e.printStackTrace();
        return Result.error().message("请求失败,请重试!!!");
    }
}

在这里插入图片描述
3、解决依赖重复在这里插入图片描述
4、测试在这里插入图片描述在这里插入图片描述

2、自定义异常(就是自己提供一个异常,给通用异常类使用)

1、创建自定义异常类,继承RuntimeException类

package com.yzpnb.service_base_handler;

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

/**
 * 自定义异常类
 * */

@Data//为类中成员变量自动生成get set toString
@AllArgsConstructor //自动生成有参构造方法,参数是所有参数
@NoArgsConstructor  //自动生成无参构造
public class CustomExceptionHandler extends RuntimeException{

    private Integer code;//状态码

    private String message;//异常信息
}

在这里插入图片描述
2、通用异常中处理我们自定义的异常

/**处理自定义异常*/
    @ExceptionHandler(CustomExceptionHandler.class)//表示此方法只对我们自己定义的这个异常有效
    @ResponseBody
    public Result customError(CustomExceptionHandler e){//参数就是我们自定义异常类的对象
        e.printStackTrace();//父类提供的方法
        return Result.error().code(e.getCode()).message(e.getMessage());//将统一返回结果的状态码和提示信息,换为自定以异常的
    }

在这里插入图片描述
3、使用自定义异常

/**
     * 查询
     * REST风格
     * */
    //1、查询所有讲师数据
    @ApiOperation("查询所有讲师")
    @GetMapping("findAll")//这里没写@ResponseBody注解,是因为我的类使用的@ResrController注解,封装了这个注解
    public Result findAll()
    {
        try{
            int a=1/0;
        }catch(Exception e){
            /**因为我们自定义异常,系统不认识,对系统来说就是一个普通的类,所有需要我们手动抛出*/
            throw new CustomExceptionHandler(20003,"我是自定义异常!!!");
        }
        //list方法是代码生成器帮我们生成的service接口继承的工具类提供的方法,用来查询所有数据
        //通过Result.ok()的形式获取Result对象,然后通过我们设置值的方法data添加一条数据
        return Result.ok().data("allEduTeacher",eduTeacherService.list());
    }

在这里插入图片描述
4、测试
在这里插入图片描述

十一、配置使用Logback统一日志规范

1、不要在application.yml中配置任何日志相关的配置,spring的mybatis plus 等等统统不要配
2、配置logback-spring.xml(注意其中我标注的一些配置,路径是你必须重新设置的,我用&&&&符号将它括起来了)

<?xml version="1.0" encoding="UTF-8"?>
<configuration  scan="true" scanPeriod="10 seconds">
    <!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
    <!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true -->
    <!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
    <!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false-->
    <contextName>logback</contextName>
    <!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 -->
    <!--&&&&&&&&&设置日志路径&&&&&&&&&&-->
    <property name="log.path" value="F:\log" /><!--将日志输出到桌面-->
    <!-- 彩色日志 -->
    <!-- 配置格式变量:CONSOLE_LOG_PATTERN 彩色日志格式 -->
    <!-- magenta:洋红 -->
    <!-- boldMagenta:粗红-->
    <!-- cyan:青色 -->
    <!-- white:白色 -->
    <!-- magenta:洋红 -->
    <property name="CONSOLE_LOG_PATTERN"
    value="%yellow(%date{yyyy-MM-dd HH:mm:ss}) |%highlight(%-5level) |%blue(%thread) |%blue(%file:%line) |%green(%logger) |%cyan(%msg%n)"/>
    <!--输出到控制台-->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
        <!-- 例如:如果此处配置了INFO级别,则后面其他位置即使配置了DEBUG级别的日志,也不会被输出 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
        <encoder>
            <Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
            <!-- 设置字符集 -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>
    <!--输出到文件-->
    <!-- 时间滚动输出 level为 INFO 日志 -->
    <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文件的路径及文件名 -->
        <file>${log.path}/log_info.log</file>
        <!--日志文件输出格式-->
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 每天日志归档路径以及格式 -->
            <fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文件保留天数-->
            <maxHistory>15</maxHistory>
        </rollingPolicy>
        <!-- 此日志文件只记录info级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <!-- 时间滚动输出 level为 WARN 日志 -->
    <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文件的路径及文件名 -->
        <file>${log.path}/log_warn.log</file>
        <!--日志文件输出格式-->
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            <charset>UTF-8</charset> <!-- 此处设置字符集 -->
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文件保留天数-->
            <maxHistory>15</maxHistory>
        </rollingPolicy>
        <!-- 此日志文件只记录warn级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>warn</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <!-- 时间滚动输出 level为 ERROR 日志 -->
    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文件的路径及文件名 -->
        <file>${log.path}/log_error.log</file>
        <!--日志文件输出格式-->
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            <charset>UTF-8</charset> <!-- 此处设置字符集 -->
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文件保留天数-->
            <maxHistory>15</maxHistory>
        </rollingPolicy>
        <!-- 此日志文件只记录ERROR级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <!--
        <logger>用来设置某一个包或者具体的某一个类的日志打印级别、以及指定<appender><logger>仅有一个name属性,
        一个可选的level和一个可选的addtivity属性。
        name:用来指定受此logger约束的某一个包或者具体的某一个类。
        level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
              如果未设置此属性,那么当前logger将会继承上级的级别。
    -->
    <!--
        使用mybatis的时候,sql语句是debug下才会打印,而这里我们只配置了info,所以想要查看sql语句的话,有以下两种操作:
        第一种把<root level="INFO">改成<root level="DEBUG">这样就会打印sql,不过这样日志那边会出现很多其他消息
        第二种就是单独给mapper下目录配置DEBUG模式,代码如下,这样配置sql语句会打印,其他还是正常DEBUG级别:
     -->
    <!--开发环境:打印控制台-->
    <springProfile name="dev">
        <!--可以输出项目中的debug日志,包括mybatis的sql日志-->
        <logger name="com.guli" level="INFO" />
        <!--
            root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性
            level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,默认是DEBUG
            可以包含零个或多个appender元素。
        -->
        <root level="INFO">
            <appender-ref ref="CONSOLE" />
            <appender-ref ref="INFO_FILE" />
            <appender-ref ref="WARN_FILE" />
            <appender-ref ref="ERROR_FILE" />
        </root>
    </springProfile>
    <!--生产环境:输出到文件-->
    <springProfile name="pro">
        <root level="INFO">
            <appender-ref ref="CONSOLE" />
            <appender-ref ref="DEBUG_FILE" />
            <appender-ref ref="INFO_FILE" />
            <appender-ref ref="ERROR_FILE" />
            <appender-ref ref="WARN_FILE" />
        </root>
    </springProfile>
</configuration>

在这里插入图片描述
3、测试在这里插入图片描述在这里插入图片描述

将异常输出到日志文件中

1、在类上添加注解

@Slf4j//日志注解

在这里插入图片描述
2、使用log的方法将信息输入到本地日志文件中

            log.error(e.getMessage());//将指定信息输入到日志文件中,error表示输入到error文件中
//            log.info(e.getMessage());  info就是将信息输入到info文件中,以此类推
//            log.debug(e.getMessage());

在这里插入图片描述
3、运行测试
在这里插入图片描述

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
现场大屏幕具有开幕墙、闭幕墙、消息墙、抽奖、签到、嘉宾展示、抢红包功能,利用开幕墙对整个活动的展示介绍、也适合活动进行中的间歇时间、消息墙可以再等待和互动的时候,让员工发布消息,是/一款非常流行的微信大屏幕系统。 重要说明:付费报名模式目前只支持开通微信支付的服务号。 1、本模块支持开幕墙、闭幕墙、消息墙、二维码扫描墙、3D签到墙(支持logo签到和文字签到)(4种展示效果)、多奖品切换现场抽奖、酷炫互动疯狂抢红包、嘉宾墙等,后续将再新增多个墙,敬请期待; 2、每个大屏幕都支持自定义背景、和背景有音乐功能,购买的客户将免费赠送背景素材包; 3、现场抽奖奖品支持同时设置多个奖品,并且可以设置每个奖品的顺序,方便根据奖品价值安排抽奖顺序,奖品支持实物和红包(); 4、抢红包奖品支持实物、微信卡券、红包等,支持自定义奖品数量、概率等; 5、抢红包支持设置每个人最多中奖次数、超过了就不会再中奖了; 6、抢红包活动支持设置赞助商广告,粉丝的中奖提示页面会弹出赞助广告; 7、抢红包活动支持多波活动举办,支持一波活动结束后直接重置,之前中奖的数据不会被清空,后台和中奖者手机端都可以看到并且兑换红包。 8、红包奖品支持直接发送和提现两种模式,方便做大额红包奖励。 9、3D签到墙支持4种展示方式,前后台都可以自由切换,手机端签到可以支持是/否需要填写个人信息,个人信息支持填写姓名、手机、公司/职位等; 10、大屏幕支持设置密码才能访问的功能; 11、消息墙支持开启是/否需要消息审核的功能,支持同时发生消息和图片的功能,并且支持图片再显示的时候是/否自动放大功能。 12、后台支持自定义活动流程说明,方便参与者再手机端直接查看活动流程。 13、支持开启和关闭强制关注才能参与活动的功能; 14、自带LBS限制地区功能,可以设置参与人的地区范围; 15、本模块只支持认证服务号使用(使用红包功能必须开通微信支付),其他非认证服务号的可以借用权限(借用权限的账号无法使用卡券功能); 运营方案推荐: 【公司年会方案】 使用开幕墙、闭幕墙、消息墙、抽奖、签到、嘉宾展示、抢红包功能,利用开幕墙对整个活动的展示介绍、也适合活动进行中的间歇时间、消息墙可以再等待和互动的时候,让员工发布消息。签到墙采用水晶球模式。 整个年会设置多波抢红包活动,利用抢红包重置功能,可以举办多波互动抢红包,既能引爆现场,又能回馈员工福利。 现场抽奖功能可以把奖品依次从低到高设置,把价值最高的放最后面。 【本地自媒体现场活动】 使用开幕墙、闭幕强、抢红包功能,开幕墙和闭幕墙可以做成赞助商广告墙,利用抢红包的高互动功能,并且可以举办多波的功能,快速引爆活动现场。 适用范围 微信墙、超级大屏幕、微信大屏幕、现场大屏幕 1、本地自媒体大号,拉商家赞助; 2、公司年会、学校、企事业单位等等; 3、微信运营服务提供商; 4、婚礼策划机构

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

殷丿grd_志鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值