目录
1.1):导入heima-leadnews-article微服务,资料在当天的文件夹中
一.分表
1.导入数据库sql脚本
CREATE DATABASE IF NOT EXISTS leadnews_article DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE leadnews_article;
SET NAMES utf8;
/*
Navicat MySQL Data Transfer
Source Server : localhost
Source Server Version : 50721
Source Host : localhost:3306
Source Database : leadnews_article
Target Server Type : MYSQL
Target Server Version : 50721
File Encoding : 65001
Date: 2021-04-19 15:05:13
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for ap_article
-- ----------------------------
DROP TABLE IF EXISTS `ap_article`;
CREATE TABLE `ap_article` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '标题',
`author_id` int(11) unsigned DEFAULT NULL COMMENT '文章作者的ID',
`author_name` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '作者昵称',
`channel_id` int(10) unsigned DEFAULT NULL COMMENT '文章所属频道ID',
`channel_name` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '频道名称',
`layout` tinyint(1) unsigned DEFAULT NULL COMMENT '文章布局\r\n 0 无图文章\r\n 1 单图文章\r\n 2 多图文章',
`flag` tinyint(3) unsigned DEFAULT NULL COMMENT '文章标记\r\n 0 普通文章\r\n 1 热点文章\r\n 2 置顶文章\r\n 3 精品文章\r\n 4 大V 文章',
`images` varchar(1000) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '文章图片\r\n 多张逗号分隔',
`labels` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '文章标签最多3个 逗号分隔',
`likes` int(5) unsigned DEFAULT NULL COMMENT '点赞数量',
`collection` int(5) unsigned DEFAULT NULL COMMENT '收藏数量',
`comment` int(5) unsigned DEFAULT NULL COMMENT '评论数量',
`views` int(5) unsigned DEFAULT NULL COMMENT '阅读数量',
`province_id` int(11) unsigned DEFAULT NULL COMMENT '省市',
`city_id` int(11) unsigned DEFAULT NULL COMMENT '市区',
`county_id` int(11) unsigned DEFAULT NULL COMMENT '区县',
`created_time` datetime DEFAULT NULL COMMENT '创建时间',
`publish_time` datetime DEFAULT NULL COMMENT '发布时间',
`sync_status` tinyint(1) DEFAULT '0' COMMENT '同步状态',
`origin` tinyint(1) unsigned DEFAULT '0' COMMENT '来源',
`static_url` varchar(150) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1383828014629179394 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='文章信息表,存储已发布的文章';
-- ----------------------------
-- Records of ap_article
-- ----------------------------
INSERT INTO `ap_article` VALUES ('1302862387124125698', '什么是Java语言', '4', 'admin', '1', 'java', '1', null, 'group1/M00/00/00/wKjIgl9V2CqAZe18AAOoOOsvWPc041.png', null, null, null, null, null, null, null, null, '2020-09-07 14:52:54', '2020-09-07 14:56:18', '0', '0', null);
INSERT INTO `ap_article` VALUES ('1302864436297482242', 'Java语言跨平台原理', '4', 'admin', '1', 'java', '1', null, 'group1/M00/00/00/wKjIgl9V2n6AArZsAAGMmaPdt7w502.png', null, null, null, null, null, null, null, null, '2020-09-07 15:01:02', '2020-09-07 15:01:02', '0', '0', null);
INSERT INTO `ap_article` VALUES ('1302864730402078722', '我是一个测试标题', '4', 'admin', '1', 'java', '1', null, 'group1/M00/00/00/wKjIgl892wqAANwOAAJW8oQUlAc087.jpg', null, null, null, null, null, null, null, null, '2020-09-07 15:02:12', '2020-09-07 15:02:12', '0', '0', null);
INSERT INTO `ap_article` VALUES ('1302865008438296577', '过山车故障20名游客倒挂空中', '4', 'admin', '1', 'java', '3', null, 'group1/M00/00/00/wKjIgl892wqAANwOAAJW8oQUlAc087.jpg,group1/M00/00/00/wKjIgl892xmAG_yjAAB6OkkuJd4819.jpg,group1/M00/00/00/wKjIgl892wKAZLhtAASZUi49De0836.jpg', null, null, null, null, null, null, null, null, '2020-09-07 15:03:19', '2020-09-07 15:03:19', '0', '0', null);
INSERT INTO `ap_article` VALUES ('1302865306489733122', '武汉高校开学典礼万人歌唱祖国', '4', 'admin', '1', 'java', '3', null, 'group1/M00/00/00/wKjIgl892vuAXr_MAASCMYD0yzc919.jpg,group1/M00/00/00/wKjIgl892xGANV6qAABzWOH8KDY775.jpg,group1/M00/00/00/wKjIgl892wqAANwOAAJW8oQUlAc087.jpg', null, null, null, null, null, null, null, null, '2020-09-07 15:04:30', '2020-09-07 15:04:30', '0', '0', null);
INSERT INTO `ap_article` VALUES ('1302865474094120961', '天降铁球砸死女婴整栋楼被判赔', '4', 'admin', '1', 'java', '1', null, 'group1/M00/00/00/wKjIgl892tyAFc60AAMUNUuOKPA619.jpg', null, null, null, null, null, null, null, null, '2020-09-07 15:05:10', '2020-09-07 15:05:10', '0', '0', null);
INSERT INTO `ap_article` VALUES ('1302977178887004162', '央视曝光境外医疗豪华旅游套路', '4', 'admin', '1', 'java', '0', null, 'group1/M00/00/00/wKjIgl892wqAANwOAAJW8oQUlAc087.jpg', null, null, null, null, null, null, null, null, '2020-09-07 22:29:02', '2020-09-07 22:29:02', '0', '0', null);
INSERT INTO `ap_article` VALUES ('1302977458215067649', '10多名陌生人合力托举悬窗女童', '4', 'admin', '1', 'java', '1', null, 'group1/M00/00/00/wKjIgl892vOASiunAAGzs3UZ1Cg252.jpg', null, null, null, null, null, null, null, null, '2020-09-07 22:30:09', '2020-09-07 22:30:09', '0', '0', null);
INSERT INTO `ap_article` VALUES ('1302977558807060482', '杨澜回应一秒变脸', '4', 'admin', '1', 'java', '1', null, 'group1/M00/00/00/wKjIgl892wKAZLhtAASZUi49De0836.jpg', null, null, null, null, null, null, null, null, '2020-09-07 22:30:33', '2020-09-07 22:30:33', '0', '0', null);
INSERT INTO `ap_article` VALUES ('1302977754114826241', '黄龄工作室发视频回应', '4', 'admin', '4', 'Python', '1', null, 'group1/M00/00/00/wKjIgl892vuAXr_MAASCMYD0yzc919.jpg', null, null, null, null, null, null, null, null, '2020-09-07 22:31:19', '2020-09-07 22:31:19', '0', '0', null);
INSERT INTO `ap_article` VALUES ('1302977754114826242', '黄龄工作室发视频回应', '4', 'admin', '4', 'Python', '1', null, 'group1/M00/00/00/wKjIgl892vuAXr_MAASCMYD0yzc919.jpg', '', null, null, null, null, null, null, null, '2020-09-07 22:31:19', '2020-09-07 22:31:19', '0', '0', null);
INSERT INTO `ap_article` VALUES ('1302977754114826243', '黄龄工作室发视频回应', '4', 'admin', '4', 'Python', '1', null, 'group1/M00/00/00/wKjIgl892vuAXr_MAASCMYD0yzc919.jpg', '', null, null, null, null, null, null, null, '2020-09-07 22:31:19', '2020-09-07 22:31:19', '0', '0', null);
INSERT INTO `ap_article` VALUES ('1303156149041758210', '全国抗击新冠肺炎疫情表彰大会', '4', 'admin', '1', 'java', '1', null, 'group1/M00/00/00/wKjIgl9W6iOAD2doAAFY4E1K7-g384.png', null, null, null, null, null, null, null, null, '2020-09-08 10:20:12', '2020-09-08 10:20:12', '0', '0', null);
INSERT INTO `ap_article` VALUES ('1383827787629252610', 'Kafka文件的存储机制', '4', 'admin', '1', 'java', '1', null, 'http://192.168.200.130:9000/leadnews/2021/4/20210418/4a498d9cf3614570ac0cb2da3e51c164.jpg', null, null, null, null, null, null, null, null, '2021-04-19 01:00:29', '2021-04-19 00:20:17', '0', '0', null);
INSERT INTO `ap_article` VALUES ('1383827888816836609', '为什么项目经理不喜欢重构?', '4', 'admin', '1', 'java', '1', null, 'http://192.168.200.130:9000/leadnews/2021/4/20210418/4a498d9cf3614570ac0cb2da3e51c164.jpg', null, null, null, null, null, null, null, null, '2021-04-19 01:00:54', '2021-04-19 00:19:09', '0', '0', null);
INSERT INTO `ap_article` VALUES ('1383827911810011137', 'Base64编解码原理', '4', 'admin', '1', 'java', '1', null, 'http://192.168.200.130:9000/leadnews/2021/4/20210418/b44c65376f12498e873223d9d6fdf523.jpg', null, null, null, null, null, null, null, null, '2021-04-19 01:00:59', '2021-04-19 00:17:42', '0', '0', null);
INSERT INTO `ap_article` VALUES ('1383827952326987778', '工作线程数是不是设置的越大越好', '4', 'admin', '1', 'java', '1', null, 'http://192.168.200.130:9000/leadnews/2021/4/20210418/a3f0bc438c244f788f2df474ed8ecdc1.jpg', null, null, null, null, null, null, null, null, '2021-04-19 01:01:09', '2021-04-19 00:16:52', '0', '0', null);
INSERT INTO `ap_article` VALUES ('1383827976310018049', '小白如何辨别其真与伪&好与坏?', '4', 'admin', '1', 'java', '1', null, 'http://192.168.200.130:9000/leadnews/2021/4/20210418/1818283261e3401892e1383c1bd00596.jpg', null, null, null, null, null, null, null, null, '2021-04-19 01:01:14', '2021-04-19 00:14:58', '0', '0', null);
INSERT INTO `ap_article` VALUES ('1383827995813531650', '学IT,为什么要学项目课程?', '4', 'admin', '1', 'java', '3', null, 'http://192.168.200.130:9000/leadnews/2021/4/20210418/7d0911a41a3745efa8509a87f234813c.jpg,http://192.168.200.130:9000/leadnews/2021/4/20210418/c7c3d36d25504cf6aecdcd5710261773.jpg,http://192.168.200.130:9000/leadnews/2021/4/20210418/e8113ad756a64ea6808f91130a6cd934.jpg', null, null, null, null, null, null, null, null, '2021-04-19 01:01:19', '2021-04-19 00:10:48', '0', '0', null);
INSERT INTO `ap_article` VALUES ('1383828014629179393', '“真”项目课程对找工作有什么帮助?', '4', 'admin', '1', 'java', '1', null, 'http://192.168.200.130:9000/leadnews/2021/4/20210418/7d0911a41a3745efa8509a87f234813c.jpg', null, null, null, null, null, null, null, null, '2021-04-19 01:01:24', '2021-04-19 00:08:05', '0', '0', null);
-- ----------------------------
-- Table structure for ap_article_config
-- ----------------------------
DROP TABLE IF EXISTS `ap_article_config`;
CREATE TABLE `ap_article_config` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`article_id` bigint(20) unsigned DEFAULT NULL COMMENT '文章ID',
`is_comment` tinyint(1) unsigned DEFAULT NULL COMMENT '是否可评论',
`is_forward` tinyint(1) unsigned DEFAULT NULL COMMENT '是否转发',
`is_down` tinyint(1) unsigned DEFAULT NULL COMMENT '是否下架',
`is_delete` tinyint(1) unsigned DEFAULT NULL COMMENT '是否已删除',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_article_id` (`article_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1383828014645956610 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='APP已发布文章配置表';
-- ----------------------------
-- Records of ap_article_config
-- ----------------------------
INSERT INTO `ap_article_config` VALUES ('1302862387933626369', '1302862387124125698', '1', '1', '0', '0');
INSERT INTO `ap_article_config` VALUES ('1302864437425750018', '1302864436297482242', '1', '1', '0', '0');
INSERT INTO `ap_article_config` VALUES ('1302864731203190785', '1302864730402078722', '1', '1', '0', '0');
INSERT INTO `ap_article_config` VALUES ('1302865009533009922', '1302865008438296577', '1', '1', '0', '0');
INSERT INTO `ap_article_config` VALUES ('1302865307408285697', '1302865306489733122', '1', '1', '0', '0');
INSERT INTO `ap_article_config` VALUES ('1302865475297886209', '1302865474094120961', '1', '1', '0', '0');
INSERT INTO `ap_article_config` VALUES ('1302977180199821313', '1302977178887004162', '1', '1', '0', '0');
INSERT INTO `ap_article_config` VALUES ('1302977459322363905', '1302977458215067649', '1', '1', '0', '0');
INSERT INTO `ap_article_config` VALUES ('1302977559788527618', '1302977558807060482', '1', '1', '0', '0');
INSERT INTO `ap_article_config` VALUES ('1302977754882383873', '1302977754114826241', '1', '1', '0', '0');
INSERT INTO `ap_article_config` VALUES ('1302977754882383874', '1302977754114826242', '1', '1', '0', '0');
INSERT INTO `ap_article_config` VALUES ('1302977754882383875', '1302977754114826243', '1', '1', '0', '0');
INSERT INTO `ap_article_config` VALUES ('1303156149909979137', '1303156149041758210', '1', '1', '0', '0');
INSERT INTO `ap_article_config` VALUES ('1383827787704750082', '1383827787629252610', '1', '1', '0', '0');
INSERT INTO `ap_article_config` VALUES ('1383827888829419522', '1383827888816836609', '1', '1', '0', '0');
INSERT INTO `ap_article_config` VALUES ('1383827911822594049', '1383827911810011137', '1', '1', '0', '0');
INSERT INTO `ap_article_config` VALUES ('1383827952326987779', '1383827952326987778', '1', '1', '0', '0');
INSERT INTO `ap_article_config` VALUES ('1383827976322600962', '1383827976310018049', '1', '1', '0', '0');
INSERT INTO `ap_article_config` VALUES ('1383827995821920257', '1383827995813531650', '1', '1', '0', '0');
INSERT INTO `ap_article_config` VALUES ('1383828014645956609', '1383828014629179393', '1', '1', '0', '0');
-- ----------------------------
-- Table structure for ap_article_content
-- ----------------------------
DROP TABLE IF EXISTS `ap_article_content`;
CREATE TABLE `ap_article_content` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`article_id` bigint(20) unsigned DEFAULT NULL COMMENT '文章ID',
`content` longtext COLLATE utf8mb4_unicode_ci COMMENT '文章内容',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_article_id` (`article_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1383828014650150915 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='APP已发布文章内容表';
-- ----------------------------
-- Records of ap_article_content
-- ----------------------------
INSERT INTO `ap_article_content` VALUES ('1302862388957036545', '1302862387124125698', '[{\"type\":\"text\",\"value\":\"Java语言是美国Sun公司(Stanford University Network),在1995年推出的高级的编程语言。所谓编程语言,是计算机的语言,人们可以使用编程语言对计算机下达命令,让计算机完成人们需要的功能。\\n\\n2009年,Sun公司被甲骨文公司收购,所以我们现在访问oracle官网即可:https://www.oracle.com\\nJava语言共同创始人之一:詹姆斯·高斯林 (James Gosling),被称为“Java之父”\\n\"},{\"type\":\"image\",\"value\":\"http://192.168.200.130/group1/M00/00/00/wKjIgl9V2CqAZe18AAOoOOsvWPc041.png\"},{\"type\":\"text\",\"value\":\"Java语言发展历史\\n\\n- 1995年Sun公司推出Java语言\\n- 1996年发布Java 1.0版本\\n- 1997年发布Java 1.1版本\\n- 1998年发布Java 1.2版本\\n- 2000年发布Java 1.3版本\\n- 2002年发布Java 1.4版本\\n- 2004年发布Java 5.0版本\\n- 2006年发布Java 6.0版本\\n- 2009年Oracle甲骨文公司收购Sun公司\\n- 2011年发布Java 7.0版本\\n- 2014年发布Java 8.0版本\\n- 2017年9月发布Java 9.0版本\\n- 2018年3月发布Java 10.0版本\\n- 2018年9月发布Java 11.0版本\\n\"},{\"type\":\"text\",\"value\":\"Java 语言的三个版本\\n\\n- JavaSE:标准版,用于桌面应用的开发,是其他两个版本的基础。\\n - 学习JavaSE的目的, 是为了就业班要学习的JavaEE打基础.\\n\"},{\"type\":\"image\",\"value\":\"http://192.168.200.130/group1/M00/00/00/wKjIgl9V2F6AdQxAAAGyaOdp4gk784.png\"},{\"type\":\"text\",\"value\":\"- JavaEE:企业版,用于Web方向的网站开发\\n - 网站:网页 + 后台服务器\\n\\nJava语言主要应用在互联网程序的开发领域。常见的互联网程序比如天猫、京东、物流系统、网银系统等,以及服务器后台处理大数据的存储、查询、数据挖掘等也有很多应用。\\n\"}]');
INSERT INTO `ap_article_content` VALUES ('1302864438885367810', '1302864436297482242', '[{\"type\":\"text\",\"value\":\"Java虚拟机——JVM\\n\\n- JVM(Java Virtual Machine ):Java虚拟机,简称JVM,是运行所有Java程序的假想计算机,是Java程序的运行环境,是Java 最具吸引力的特性之一。我们编写的Java代码,都运行在JVM 之上。\\n- 跨平台:任何软件的运行,都必须要运行在操作系统之上,而我们用Java编写的软件可以运行在任何的操作系统上,这个特性称为Java语言的跨平台特性。该特性是由JVM实现的,我们编写的程序运行在JVM上,而JVM运行在操作系统上。\\n\"},{\"type\":\"image\",\"value\":\"http://192.168.200.130/group1/M00/00/00/wKjIgl9V2n6AArZsAAGMmaPdt7w502.png\"},{\"type\":\"text\",\"value\":\"如图所示,Java的虚拟机本身不具备跨平台功能的,每个操作系统下都有不同版本的虚拟机。\\n\\n问题1: Java 是如何实现跨平台的呢?\\n\\n- 答:因为在不同操作系统中都安装了对应版本的 JVM 虚拟机\\n- 注意: Java程序想要运行, 必须依赖于JVM虚拟机.\\n\\n问题2: JVM 本身是否允许跨平台呢?\\n\\n- 答:不允许,允许跨平台的是 Java 程序,而不是虚拟机。\\n\"}]');
INSERT INTO `ap_article_content` VALUES ('1302864732679585794', '1302864730402078722', '[{\"type\":\"text\",\"value\":\"这些都是测试这些都是测试这些都是测试这些都是测试这些都是测试这些都是测试\"},{\"type\":\"image\",\"value\":\"http://192.168.200.130/group1/M00/00/00/wKjIgl892wqAANwOAAJW8oQUlAc087.jpg\"},{\"type\":\"text\",\"value\":\"这些都是测试这些都是测试这些都是测试这些都是测试\"}]');
INSERT INTO `ap_article_content` VALUES ('1302865011026182145', '1302865008438296577', '[{\"type\":\"text\",\"value\":\"过山车故障20名游客倒挂空中过山车故障20名游客倒挂空中过山车故障20名游客倒挂空中过山车故障20名游客倒挂空中过山车故障20名游客倒挂空中过山车故障20名游客倒挂空中过山车故障20名游客倒挂空中过山车故障20名游客倒挂空中过山车故障20名游客倒挂空中过山车故障20名游客倒挂空中\"},{\"type\":\"image\",\"value\":\"http://192.168.200.130/group1/M00/00/00/wKjIgl892uyAR12rAADi7UxPXeM267.jpg\"},{\"type\":\"text\",\"value\":\"过山车故障20名游客倒挂空中过山车故障20名游客倒挂空中过山车故障20名游客倒挂空中过山车故障20名游客倒挂空中过山车故障20名游客倒挂空中过山车故障20名游客倒挂空中过山车故障20名游客倒挂空中\"},{\"type\":\"text\",\"value\":\"请在这里输入正文\"}]');
INSERT INTO `ap_article_content` VALUES ('1302865308704325633', '1302865306489733122', '[{\"type\":\"text\",\"value\":\"武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国\"},{\"type\":\"image\",\"value\":\"http://192.168.200.130/group1/M00/00/00/wKjIgl892vuAXr_MAASCMYD0yzc919.jpg\"},{\"type\":\"text\",\"value\":\"武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国武汉高校开学典礼万人歌唱祖国v\"}]');
INSERT INTO `ap_article_content` VALUES ('1302865476799447041', '1302865474094120961', '[{\"type\":\"text\",\"value\":\"天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔\"},{\"type\":\"image\",\"value\":\"http://192.168.200.130/group1/M00/00/00/wKjIgl892tyAFc60AAMUNUuOKPA619.jpg\"},{\"type\":\"text\",\"value\":\"天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔天降铁球砸死女婴整栋楼被判赔vv\"},{\"type\":\"text\",\"value\":\"请在这里输入正文\"}]');
INSERT INTO `ap_article_content` VALUES ('1302977181835599873', '1302977178887004162', '[{\"type\":\"text\",\"value\":\"央视曝光境外医疗豪华旅游套路央视曝光境外医疗豪华旅游套路央视曝光境外医疗豪华旅游套路央视曝光境外医疗豪华旅游套路央视曝光境外医疗豪华旅游套路央视曝光境外医疗豪华旅游套路央视曝光境外医疗豪华旅游套路央视曝光境外医疗豪华旅游套路央视曝光境外医疗豪华旅游套路央视曝光境外医疗豪华旅游套路央视曝光境外医疗豪华旅游套路央视曝光境外医疗豪华旅游套路\"},{\"type\":\"image\",\"value\":\"http://192.168.200.130/group1/M00/00/00/wKjIgl892wqAANwOAAJW8oQUlAc087.jpg\"}]');
INSERT INTO `ap_article_content` VALUES ('1302977460907810818', '1302977458215067649', '[{\"type\":\"text\",\"value\":\"510多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童\"},{\"type\":\"image\",\"value\":\"http://192.168.200.130/group1/M00/00/00/wKjIgl892vOASiunAAGzs3UZ1Cg252.jpg\"},{\"type\":\"image\",\"value\":\"http://192.168.200.130/group1/M00/00/00/wKjIgl892uyAR12rAADi7UxPXeM267.jpg\"},{\"type\":\"text\",\"value\":\"10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童v\"},{\"type\":\"text\",\"value\":\"请10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童10多名陌生人合力托举悬窗女童v\"}]');
INSERT INTO `ap_article_content` VALUES ('1302977561034235906', '1302977558807060482', '[{\"type\":\"text\",\"value\":\"杨澜回应一秒变脸杨澜回应一秒变脸杨澜回应一秒变脸杨澜回应一秒变脸杨澜回应一秒变脸杨澜回应一秒变脸\"},{\"type\":\"image\",\"value\":\"http://192.168.200.130/group1/M00/00/00/wKjIgl892wKAZLhtAASZUi49De0836.jpg\"},{\"type\":\"text\",\"value\":\"杨澜回应一秒变脸杨澜回应一秒变脸杨澜回应一秒变脸杨澜回应一秒变脸杨澜回应一秒变脸杨澜回应一秒变脸杨澜回应一秒变脸杨澜回应一秒变脸\"},{\"type\":\"text\",\"value\":\"请在这里输入正文\"}]');
INSERT INTO `ap_article_content` VALUES ('1302977755742216193', '1302977754114826241', '[{\"type\":\"text\",\"value\":\"3黄龄工作室发视频回应黄龄工作室发视频回应黄龄工作室发视频回应黄龄工作室发视频回应黄龄工作室发视频回应黄龄工作室发视频回应黄龄工作室发视频回应黄龄工作室发视频回应黄龄工作室发视频回应黄龄工作室发视频回应黄龄工作室发视频回应黄龄工作室发视频回应黄龄工作室发视频回应黄龄工作室发视频回应黄龄工作室发视频回应\"},{\"type\":\"image\",\"value\":\"http://192.168.200.130/group1/M00/00/00/wKjIgl892vuAXr_MAASCMYD0yzc919.jpg\"},{\"type\":\"text\",\"value\":\"请在这里输入正文黄龄工作室发视频回应黄龄工作室发视频回应黄龄工作室发视频回应黄龄工作室发视频回应黄龄工作室发视频回应黄龄工作室发视频回应黄龄工作室发视频回应黄龄工作室发视频回应黄龄工作室发视频回应黄龄工作室发视频回应黄龄工作室发视频回应黄龄工作室发视频回应\"}]');
INSERT INTO `ap_article_content` VALUES ('1303156151151493121', '1303156149041758210', '[{\"type\":\"image\",\"value\":\"http://192.168.200.130/group1/M00/00/00/wKjIgl9W6iOAD2doAAFY4E1K7-g384.png\"},{\"type\":\"text\",\"value\":\"全国抗击新冠肺炎疫情表彰大会开始15家“文化会客厅”展现产业发展的集群效应全球疫情简报:印度新冠确诊病例超420万 升至全球第二中方提出《全球数据安全倡议》\"}]');
INSERT INTO `ap_article_content` VALUES ('1383827787742498817', '1383827787629252610', '[{\"type\":\"text\",\"value\":\"Kafka文件的存储机制Kafka文件的存储机制Kafka文件的存储机制Kafka文件的存储机制Kafka文件的存储机制Kafka文件的存储机制Kafka文件的存储机制Kafka文件的存储机制Kafka文件的存储机制Kafka文件的存储机制\"},{\"type\":\"image\",\"value\":\"http://192.168.200.130:9000/leadnews/2021/4/20210418/4a498d9cf3614570ac0cb2da3e51c164.jpg\"},{\"type\":\"text\",\"value\":\"请在这里输入正文\"}]');
INSERT INTO `ap_article_content` VALUES ('1383827888833613826', '1383827888816836609', '[{\"type\":\"text\",\"value\":\"经常听到开发人员抱怨 ,“这么烂的代码,我来重构一下!”,“这代码怎么能这么写呢?谁来重构一下?”,“这儿有个坏味道,重构吧!”\\n\\n作为一名项目经理,每次听到“重构”两个字,既想给追求卓越代码的开发人员点个赞,同时又会感觉非常紧张,为什么又要重构?马上就要上线了,怎么还要改?是不是应该阻止开发人员做重构?\\n\\n重构几乎是开发人员最喜欢的一项实践了,可项目经理们却充满了顾虑,那么为什么项目经理不喜欢重构呢?\\n\\n老功能被破坏\\n不止一次遇到这样的场景,某一天一个老功能突然被破坏了,项目经理们感到奇怪,产品这块儿的功能已经很稳定了,也没有在这部分开发什么新功能,为什么突然出问题了呢?\"},{\"type\":\"image\",\"value\":\"http://192.168.200.130:9000/leadnews/2021/4/20210418/e8113ad756a64ea6808f91130a6cd934.jpg\"},{\"type\":\"image\",\"value\":\"http://192.168.200.130:9000/leadnews/2021/4/20210418/4a498d9cf3614570ac0cb2da3e51c164.jpg\"},{\"type\":\"text\",\"value\":\"请在这里输入正文\"}]');
INSERT INTO `ap_article_content` VALUES ('1383827911826788353', '1383827911810011137', '[{\"type\":\"text\",\"value\":\"我在面试过程中,问过很多高级java工程师,是否了解Base64?部分人回答了解,部分人直接回答不了解。而说了解的那部分人却回答不上来它的原理。\\n\\nBase64 的由来\\nBase64是网络上最常见的用于传输8Bit字节代码的编码方式之一,大家可以查看RFC2045~RFC2049,上面有MIME的详细规范。它是一种基于用64个可打印字符来表示二进制数据的表示方法。它通常用作存储、传输一些二进制数据编码方法!也是MIME(多用途互联网邮件扩展,主要用作电子邮件标准)中一种可打印字符表示二进制数据的常见编码方法!它其实只是定义用可打印字符传输内容一种方法,并不会产生新的字符集!\\n\\n传统的邮件只支持可见字符的传送,像ASCII码的控制字符就 不能通过邮件传送。这样用途就受到了很大的限制,比如图片二进制流的每个字节不可能全部是可见字符,所以就传送不了。最好的方法就是在不改变传统协议的情 况下,做一种扩展方案来支持二进制文件的传送。把不可打印的字符也能用可打印字符来表示,问题就解决了。Base64编码应运而生,Base64就是一种 基于64个可打印字符来表示二进制数据的表示方法。\"},{\"type\":\"image\",\"value\":\"http://192.168.200.130:9000/leadnews/2021/4/20210418/b44c65376f12498e873223d9d6fdf523.jpg\"},{\"type\":\"text\",\"value\":\"请在这里输入正文\"}]');
INSERT INTO `ap_article_content` VALUES ('1383827952335376385', '1383827952326987778', '[{\"type\":\"text\",\"value\":\"根据经验来看,jdk api 一般推荐的线程数为CPU核数的2倍。但是有些书籍要求可以设置为CPU核数的8倍,也有的业务设置为CPU核数的32倍。\\n“工作线程数”的设置依据是什么,到底设置为多少能够最大化CPU性能,是本文要讨论的问题。\\n\\n工作线程数是不是设置的越大越好\\n显然不是的。使用java.lang.Thread类或者java.lang.Runnable接口编写代码来定义、实例化和启动新线程。\\n一个Thread类实例只是一个对象,像Java中的任何其他对象一样,具有变量和方法,生死于堆上。\\nJava中,每个线程都有一个调用栈,即使不在程序中创建任何新的线程,线程也在后台运行着。\\n一个Java应用总是从main()方法开始运行,main()方法运行在一个线程内,它被称为主线程。\\n一旦创建一个新的线程,就产生一个新的调用栈。\"},{\"type\":\"image\",\"value\":\"http://192.168.200.130:9000/leadnews/2021/4/20210418/a3f0bc438c244f788f2df474ed8ecdc1.jpg\"}]');
INSERT INTO `ap_article_content` VALUES ('1383827976322600963', '1383827976310018049', '[{\"type\":\"text\",\"value\":\"通过上篇《IT培训就业艰难,行业乱象频发,如何破解就业难题?》一文,相信大家已初步了解“项目课程”对程序员能否就业且高薪就业的重要性。\\n\\n 因此,小白在选择IT培训机构时,关注的重点就在于所学“项目课程”能否真正帮你增加就业筹码。当然,前提必须是学到“真”项目。\"},{\"type\":\"image\",\"value\":\"http://192.168.200.130:9000/leadnews/2021/4/20210418/1818283261e3401892e1383c1bd00596.jpg\"}]');
INSERT INTO `ap_article_content` VALUES ('1383827995834503170', '1383827995813531650', '[{\"type\":\"text\",\"value\":\"在选择IT培训机构时,你应该有注意到,很多机构都将“项目课程”作为培训中的重点。那么,为什么要学习项目课程?为什么项目课程才是IT培训课程的核心?\\n\\n 1\\n\\n 在这个靠“技术经验说话”的IT行业里,假如你是一个计算机或IT相关专业毕业生,在没有实际项目开发经验的情况下,“找到第一份全职工作”可能是你职业生涯中遇到的最大挑战。\\n\\n 为什么说找第一份工作很难?\\n\\n 主要在于:实际企业中用到的软件开发知识和在学校所学的知识是完全不同的。假设你已经在学校和同学做过周期长达2-3个月的项目,但真正工作中的团队协作与你在学校中经历的协作也有很多不同。\"},{\"type\":\"image\",\"value\":\"http://192.168.200.130:9000/leadnews/2021/4/20210418/e8113ad756a64ea6808f91130a6cd934.jpg\"},{\"type\":\"text\",\"value\":\"在实际团队中,每一位成员彼此团结一致,为项目的交付而努力,这也意味着你必须要理解好在项目中负责的那部分任务,在规定时间交付还需确保你负责的功能,在所有环境中都能很好地发挥作用,而不仅仅是你的本地机器。\\n\\n 这需要你对项目中的每一行代码严谨要求。学校练习的项目中,对bug的容忍度很大,而在实际工作中是绝对不能容忍的。项目中的任何一个环节都涉及公司利益,任何一个bug都可能影响公司的收入及形象。\"},{\"type\":\"image\",\"value\":\"http://192.168.200.130:9000/leadnews/2021/4/20210418/c7c3d36d25504cf6aecdcd5710261773.jpg\"}]');
INSERT INTO `ap_article_content` VALUES ('1383828014650150914', '1383828014629179393', '[{\"type\":\"text\",\"value\":\"找工作,企业重点问的是项目经验,更是HR筛选的“第一门槛”,直接决定了你是否有机会进入面试环节。\\n\\n 项目经验更是评定“个人能力/技能”真实性的“证据”,反映了求职者某个方面的实际动手能力、对某个领域或某种技能的掌握程度。\"},{\"type\":\"image\",\"value\":\"http://192.168.200.130:9000/leadnews/2021/4/20210418/7d0911a41a3745efa8509a87f234813c.jpg\"},{\"type\":\"text\",\"value\":\"很多经过培训期望快速上岗的程序员,靠着培训机构“辅导”顺利经过面试官对于“项目经验”的考核上岗后,在面对“有限时间”“复杂业务”“新项目需求”等多项标签加持的工作任务,却往往不知从何下手或开发进度极其缓慢。最终结果就是:熬不过试用期。\\n\\n 从而也引发了企业对于“培训出身程序员”的“有色眼光”。你甚至也一度怀疑“IT培训班出来的人真的不行吗?”\"}]');
-- ----------------------------
-- Table structure for ap_author
-- ----------------------------
DROP TABLE IF EXISTS `ap_author`;
CREATE TABLE `ap_author` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(20) DEFAULT NULL COMMENT '作者名称',
`type` tinyint(1) unsigned DEFAULT NULL COMMENT '0 爬取数据\r\n 1 签约合作商\r\n 2 平台自媒体人\r\n ',
`user_id` int(11) unsigned DEFAULT NULL COMMENT '社交账号ID',
`created_time` datetime DEFAULT NULL COMMENT '创建时间',
`wm_user_id` int(11) unsigned DEFAULT NULL COMMENT '自媒体账号',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_type_name` (`type`,`name`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COMMENT='APP文章作者信息表';
-- ----------------------------
-- Records of ap_author
-- ----------------------------
INSERT INTO `ap_author` VALUES ('1', 'zhangsan', '2', '1', '2020-03-19 23:43:54', null);
INSERT INTO `ap_author` VALUES ('2', 'lisi', '2', '2', '2020-03-19 23:47:44', null);
INSERT INTO `ap_author` VALUES ('3', 'wangwu', '2', '3', '2020-03-19 23:50:09', null);
INSERT INTO `ap_author` VALUES ('4', 'admin', '2', '4', '2020-03-30 16:36:41', null);
-- ----------------------------
-- Table structure for ap_collection
-- ----------------------------
DROP TABLE IF EXISTS `ap_collection`;
CREATE TABLE `ap_collection` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`entry_id` int(11) unsigned DEFAULT NULL COMMENT '实体ID',
`article_id` bigint(20) unsigned DEFAULT NULL COMMENT '文章ID',
`type` tinyint(1) unsigned DEFAULT NULL COMMENT '点赞内容类型\r\n 0文章\r\n 1动态',
`collection_time` datetime DEFAULT NULL COMMENT '创建时间',
`published_time` datetime DEFAULT NULL COMMENT '发布时间',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_user_type` (`entry_id`,`article_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='APP收藏信息表';
-- ----------------------------
-- Records of ap_collection
-- ----------------------------
INSERT INTO `ap_collection` VALUES ('1', '1', '1303156149041758210', '0', '2020-04-07 23:46:47', '2020-04-07 23:46:50');
2.导入实体类
package com.heima.model.article.pojos;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 文章信息表,存储已发布的文章
* </p>
*
* @author itheima
*/
@Data
@TableName("ap_article")
public class ApArticle implements Serializable {
@TableId(value = "id",type = IdType.ID_WORKER)
private Long id;
/**
* 标题
*/
private String title;
/**
* 作者id
*/
@TableField("author_id")
private Long authorId;
/**
* 作者名称
*/
@TableField("author_name")
private String authorName;
/**
* 频道id
*/
@TableField("channel_id")
private Integer channelId;
/**
* 频道名称
*/
@TableField("channel_name")
private String channelName;
/**
* 文章布局 0 无图文章 1 单图文章 2 多图文章
*/
private Short layout;
/**
* 文章标记 0 普通文章 1 热点文章 2 置顶文章 3 精品文章 4 大V 文章
*/
private Byte flag;
/**
* 文章封面图片 多张逗号分隔
*/
private String images;
/**
* 标签
*/
private String labels;
/**
* 点赞数量
*/
private Integer likes;
/**
* 收藏数量
*/
private Integer collection;
/**
* 评论数量
*/
private Integer comment;
/**
* 阅读数量
*/
private Integer views;
/**
* 省市
*/
@TableField("province_id")
private Integer provinceId;
/**
* 市区
*/
@TableField("city_id")
private Integer cityId;
/**
* 区县
*/
@TableField("county_id")
private Integer countyId;
/**
* 创建时间
*/
@TableField("created_time")
private Date createdTime;
/**
* 发布时间
*/
@TableField("publish_time")
private Date publishTime;
/**
* 同步状态
*/
@TableField("sync_status")
private Boolean syncStatus;
/**
* 来源
*/
private Boolean origin;
/**
* 静态页面地址
*/
@TableField("static_url")
private String staticUrl;
}
ap_article_config文章配置对应实体类
package com.heima.model.article.pojos;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
/**
* <p>
* APP已发布文章配置表
* </p>
*
* @author itheima
*/
@Data
@TableName("ap_article_config")
public class ApArticleConfig implements Serializable {
@TableId(value = "id",type = IdType.ID_WORKER)
private Long id;
/**
* 文章id
*/
@TableField("article_id")
private Long articleId;
/**
* 是否可评论
* true: 可以评论 1
* false: 不可评论 0
*/
@TableField("is_comment")
private Boolean isComment;
/**
* 是否转发
* true: 可以转发 1
* false: 不可转发 0
*/
@TableField("is_forward")
private Boolean isForward;
/**
* 是否下架
* true: 下架 1
* false: 没有下架 0
*/
@TableField("is_down")
private Boolean isDown;
/**
* 是否已删除
* true: 删除 1
* false: 没有删除 0
*/
@TableField("is_delete")
private Boolean isDelete;
}
ap_article_content 文章内容对应的实体类
package com.heima.model.article.pojos;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
@Data
@TableName("ap_article_content")
public class ApArticleContent implements Serializable {
@TableId(value = "id",type = IdType.ID_WORKER)
private Long id;
/**
* 文章id
*/
@TableField("article_id")
private Long articleId;
/**
* 文章内容
*/
private String content;
}
3.分表规则
二.文章列表接口
(1)思路
1,在默认频道展示10条文章信息
2,可以切换频道查看不同种类文章
3,当用户下拉可以加载最新的文章(分页)本页文章列表中发布时间为最大的时间为依据
4,当用户上拉可以加载更多的文章信息(按照发布时间)本页文章列表中发布时间最小的时间为依据
5,如果是当前频道的首页,前端传递默认参数:
-
maxBehotTime:0(毫秒)
-
minBehotTime:20000000000000(毫秒)--->2063年
2)接口定义
加载首页 | 加载更多 | 加载最新 | |
---|---|---|---|
接口路径 | /api/v1/article/load | /api/v1/article/loadmore | /api/v1/article/loadnew |
请求方式 | POST | POST | POST |
参数 | ArticleHomeDto | ArticleHomeDto | ArticleHomeDto |
响应结果 | ResponseResult | ResponseResult | ResponseResult |
package com.heima.model.article.dtos;
import lombok.Data;
import java.util.Date;
@Data
public class ArticleHomeDto {
// 最大时间
Date maxBehotTime;
// 最小时间
Date minBehotTime;
// 分页size
Integer size;
// 频道ID
String tag;
}
3)功能实现
1.1):导入heima-leadnews-article微服务,资料在当天的文件夹中
注意:需要在heima-leadnews-service的pom文件夹中添加子模块信息,如下:
<modules>
<module>heima-leadnews-user</module>
<module>heima-leadnews-article</module>
</modules>
需要在nacos中添加对应的配置
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/leadnews_article?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
username: root
password: root
# 设置Mapper接口所对应的XML文件位置,如果你在Mapper接口中有自定义方法,需要进行该配置
mybatis-plus:
mapper-locations: classpath*:mapper/*.xml
# 设置别名包扫描路径,通过该属性可以给包中的类注册别名
type-aliases-package: com.heima.model.article.pojos
1.2):定义接口
package com.heima.article.controller.v1;
import com.heima.model.article.dtos.ArticleHomeDto;
import com.heima.model.common.dtos.ResponseResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/v1/article")
public class ArticleHomeController {
@PostMapping("/load")
public ResponseResult load(@RequestBody ArticleHomeDto dto) {
return null;
}
@PostMapping("/loadmore")
public ResponseResult loadMore(@RequestBody ArticleHomeDto dto) {
return null;
}
@PostMapping("/loadnew")
public ResponseResult loadNew(@RequestBody ArticleHomeDto dto) {
return null;
}
}
1.3):编写mapper文件
package com.heima.article.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.heima.model.article.dtos.ArticleHomeDto;
import com.heima.model.article.pojos.ApArticle;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface ApArticleMapper extends BaseMapper<ApArticle> {
public List<ApArticle> loadArticleList(@Param("dto") ArticleHomeDto dto, @Param("type") Short type);
}
对应的映射文件
在resources中新建mapper/ApArticleMapper.xml 如下配置:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.heima.article.mapper.ApArticleMapper">
<resultMap id="resultMap" type="com.heima.model.article.pojos.ApArticle">
<id column="id" property="id"/>
<result column="title" property="title"/>
<result column="author_id" property="authorId"/>
<result column="author_name" property="authorName"/>
<result column="channel_id" property="channelId"/>
<result column="channel_name" property="channelName"/>
<result column="layout" property="layout"/>
<result column="flag" property="flag"/>
<result column="images" property="images"/>
<result column="labels" property="labels"/>
<result column="likes" property="likes"/>
<result column="collection" property="collection"/>
<result column="comment" property="comment"/>
<result column="views" property="views"/>
<result column="province_id" property="provinceId"/>
<result column="city_id" property="cityId"/>
<result column="county_id" property="countyId"/>
<result column="created_time" property="createdTime"/>
<result column="publish_time" property="publishTime"/>
<result column="sync_status" property="syncStatus"/>
<result column="static_url" property="staticUrl"/>
</resultMap>
<select id="loadArticleList" resultMap="resultMap">
SELECT
aa.*
FROM
`ap_article` aa
LEFT JOIN ap_article_config aac ON aa.id = aac.article_id
<where>
and aac.is_delete != 1
and aac.is_down != 1
<!-- loadmore -->
<if test="type != null and type == 1">
and aa.publish_time <![CDATA[<]]> #{dto.minBehotTime}
</if>
<if test="type != null and type == 2">
and aa.publish_time <![CDATA[>]]> #{dto.maxBehotTime}
</if>
<if test="dto.tag != '__all__'">
and aa.channel_id = #{dto.tag}
</if>
</where>
order by aa.publish_time desc
limit #{dto.size}
</select>
</mapper>
1.4):编写业务层代码
package com.heima.article.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.heima.model.article.dtos.ArticleHomeDto;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.common.dtos.ResponseResult;
import java.io.IOException;
public interface ApArticleService extends IService<ApArticle> {
/**
* 根据参数加载文章列表
* @param loadtype 1为加载更多 2为加载最新
* @param dto
* @return
*/
ResponseResult load(Short loadtype, ArticleHomeDto dto);
}
实现类:
package com.heima.article.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.article.mapper.ApArticleMapper;
import com.heima.article.service.ApArticleService;
import com.heima.common.constants.ArticleConstants;
import com.heima.model.article.dtos.ArticleHomeDto;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.common.dtos.ResponseResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
@Service
@Transactional
@Slf4j
public class ApArticleServiceImpl extends ServiceImpl<ApArticleMapper, ApArticle> implements ApArticleService {
// 单页最大加载的数字
private final static short MAX_PAGE_SIZE = 50;
@Autowired
private ApArticleMapper apArticleMapper;
/**
* 根据参数加载文章列表
* @param loadtype 1为加载更多 2为加载最新
* @param dto
* @return
*/
@Override
public ResponseResult load(Short loadtype, ArticleHomeDto dto) {
//1.校验参数
Integer size = dto.getSize();
if(size == null || size == 0){
size = 10;
}
size = Math.min(size,MAX_PAGE_SIZE);
dto.setSize(size);
//类型参数检验
if(!loadtype.equals(ArticleConstants.LOADTYPE_LOAD_MORE)&&!loadtype.equals(ArticleConstants.LOADTYPE_LOAD_NEW)){
loadtype = ArticleConstants.LOADTYPE_LOAD_MORE;
}
//文章频道校验
if(StringUtils.isEmpty(dto.getTag())){
dto.setTag(ArticleConstants.DEFAULT_TAG);
}
//时间校验
if(dto.getMaxBehotTime() == null) dto.setMaxBehotTime(new Date());
if(dto.getMinBehotTime() == null) dto.setMinBehotTime(new Date());
//2.查询数据
List<ApArticle> apArticles = apArticleMapper.loadArticleList(dto, loadtype);
//3.结果封装
ResponseResult responseResult = ResponseResult.okResult(apArticles);
return responseResult;
}
}
定义常量类
package com.heima.common.constants;
public class ArticleConstants {
public static final Short LOADTYPE_LOAD_MORE = 1;
public static final Short LOADTYPE_LOAD_NEW = 2;
public static final String DEFAULT_TAG = "__all__";
}
15):编写控制器代码
package com.heima.article.controller.v1;
import com.heima.article.service.ApArticleService;
import com.heima.common.constants.ArticleConstants;
import com.heima.model.article.dtos.ArticleHomeDto;
import com.heima.model.common.dtos.ResponseResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/v1/article")
public class ArticleHomeController {
@Autowired
private ApArticleService apArticleService;
@PostMapping("/load")
public ResponseResult load(@RequestBody ArticleHomeDto dto) {
return apArticleService.load(ArticleConstants.LOADTYPE_LOAD_MORE,dto);
}
@PostMapping("/loadmore")
public ResponseResult loadMore(@RequestBody ArticleHomeDto dto) {
return apArticleService.load(ArticleConstants.LOADTYPE_LOAD_MORE,dto);
}
@PostMapping("/loadnew")
public ResponseResult loadNew(@RequestBody ArticleHomeDto dto) {
return apArticleService.load(ArticleConstants.LOADTYPE_LOAD_NEW,dto);
}
}
1.6):swagger测试或前后端联调测试
第一:在app网关的微服务的nacos的配置中心添加文章微服务的路由,完整配置如下:
spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]': # 匹配所有请求
allowedOrigins: "*" #跨域处理 允许所有的域
allowedMethods: # 支持的方法
- GET
- POST
- PUT
- DELETE
routes:
# 用户微服务
- id: user
uri: lb://leadnews-user
predicates:
- Path=/user/**
filters:
- StripPrefix= 1
# 文章微服务
- id: article
uri: lb://leadnews-article
predicates:
- Path=/article/**
filters:
- StripPrefix= 1
第二:启动nginx,直接使用前端项目测试,启动文章微服务,用户微服务、app网关微服务
三.文章详情
再查询文章详情的时候,我们可以有两种方法:
1.直接查询数据库,将文章内容返回前端
2.通过模版引擎,提前将文章制作成html网页,然后上传到分布式文件系统minio中,返回文章的url
关于freemark可以看这篇博客:
https://jhikun.blog.csdn.net/article/details/135039703?spm=1001.2014.3001.5502
在此不再过多描述:
四.MinIo
1 MinIO简介
MinIO基于Apache License v2.0开源协议的对象存储服务,可以做为云存储的解决方案用来保存海量的图片,视频,文档。由于采用Golang实现,服务端可以工作在Windows,Linux, OS X和FreeBSD上。配置简单,基本是复制可执行程序,单行命令可以运行起来。
MinIO兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。
S3 ( Simple Storage Service简单存储服务)
基本概念
-
bucket – 类比于文件系统的目录
-
Object – 类比文件系统的文件
-
Keys – 类比文件名
官网文档:MinIO对象存储 Kubernetes — MinIO中文文档 | MinIO Kubernetes中文文档
2.docker安装minIo
先创建两个目录用来作为data和config:
mkdir -p /usr/local/minio/config
mkdir -p /usr/local/minio/data
拉取镜像:
docker pull minio/minio
启动容器
docker run -p 9000:9000 -p 9090:9090 \
--name minio \
-d --restart=always \
-e "MINIO_ROOT_USER=minio" \
-e "MINIO_ROOT_PASSWORD=minio123456" \
-v /usr/local/minio/data:/data \
-v /usr/local/minio/config:/root/.minio \
minio/minio server \
/data --console-address ":9090" -address ":9000"
进入控制台:
创建桶bucket
修改权限为public
然后就可以自己上传文件了
3.封装springboot-starter
我们的多个微服务可能都需要依赖Minio来上传文件,例如文章要上传html文件,图片要上传img文件,所以我们可以封装到一个starter中,在需要的项目中引入依赖即可:
3.1目录结构
项目名称为common-oss-starter,为什么叫这个名称呢?因为我们的上传可能不止minio一种,后期可以会使用阿里云的oss,七牛云的oss,等,所以起名为common,暂时只封装为minioTemplate
下面我们需要再/resources目录下面创建/META-INF目录,在下面创建spring.factories文件,
写入以下内容:
3.2.spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.oss.template.MinIoTemplate
这是springboot的自动装配原理,如果不熟悉可以看其他大佬写的文章,在此不再展开分析
3.3项目的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.common.oss</groupId>
<artifactId>common-oss-starter</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.3.9.RELEASE</version>
</dependency>
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>7.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.3.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>2.3.9.RELEASE</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>2.3.9.RELEASE</version>
</dependency>
</dependencies>
</project>
3.4创建MinIoConfig配置类:
package com.oss.config;
import com.oss.template.MinIoTemplate;
import io.minio.MinioClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
import java.util.Objects;
/**
* 针对于minio的配置
*/
@Configuration
@EnableConfigurationProperties({MinIoConfigProperties.class})
@ConditionalOnClass({MinIoTemplate.class})
public class MinIoConfig {
private final static Logger log = LoggerFactory.getLogger(MinIoConfig.class);
@Resource
private MinIoConfigProperties minIoConfigProperties;
/**
* 创建minio客户端
* @return
*/
@Bean
public MinioClient minioClient(){
log.info("minioConfigProperties:{}",minIoConfigProperties);
return
MinioClient.builder().credentials(minIoConfigProperties.getAccessKey(),minIoConfigProperties.getSecretKey())
.endpoint(minIoConfigProperties.getEndpoint()).build();
}
public MinIoConfig() {
}
public MinIoConfigProperties getMinIoConfigProperties() {
return minIoConfigProperties;
}
public void setMinIoConfigProperties(MinIoConfigProperties minIoConfigProperties) {
this.minIoConfigProperties = minIoConfigProperties;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MinIoConfig that = (MinIoConfig) o;
return Objects.equals(minIoConfigProperties, that.minIoConfigProperties);
}
@Override
public int hashCode() {
return Objects.hash(minIoConfigProperties);
}
@Override
public String toString() {
return "MinIoConfig{" +
"minIoConfigProperties=" + minIoConfigProperties +
'}';
}
}
3.5MinIoConfigProperties
package com.oss.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import java.util.Objects;
/**
* minio的配置属性
*/
@ConfigurationProperties(prefix = "minio")
public class MinIoConfigProperties {
private String accessKey;
private String secretKey;
private String bucket;
private String endpoint;
public MinIoConfigProperties() {
}
public String getEndpoint() {
return endpoint;
}
public void setEndpoint(String endpoint) {
this.endpoint = endpoint;
}
public String getAccessKey() {
return accessKey;
}
public void setAccessKey(String accessKey) {
this.accessKey = accessKey;
}
public String getSecretKey() {
return secretKey;
}
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
public String getBucket() {
return bucket;
}
public void setBucket(String bucket) {
this.bucket = bucket;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MinIoConfigProperties that = (MinIoConfigProperties) o;
return accessKey.equals(that.accessKey) && secretKey.equals(that.secretKey) && bucket.equals(that.bucket);
}
@Override
public int hashCode() {
return Objects.hash(accessKey, secretKey, bucket);
}
@Override
public String toString() {
return "MinIoConfigProperties{" +
"accessKey='" + accessKey + '\'' +
", secretKey='" + secretKey + '\'' +
", bucket='" + bucket + '\'' +
", endpoint='" + endpoint + '\'' +
'}';
}
}
3.6MinIoTemplate
package com.oss.template;
import com.oss.config.MinIoConfig;
import com.oss.config.MinIoConfigProperties;
import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Import;
import org.springframework.util.StringUtils;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* minio的模板
*/
@EnableConfigurationProperties(MinIoConfigProperties.class)
@Import(MinIoConfig.class)
public class MinIoTemplate {
private static final Logger log = LoggerFactory.getLogger(MinIoTemplate.class);
@Autowired
private MinioClient minioClient;
@Autowired
private MinIoConfigProperties minIoConfigProperties;
//分隔符
public static final String separator = "/";
/**
* 构建文件路径
* @param dirPath
* @param filename
* @return
*/
public String builderFilePath(String dirPath, String filename) {
StringBuilder stringBuilder = new StringBuilder(50);
if (!StringUtils.isEmpty(dirPath)) {
stringBuilder.append(dirPath).append(separator);
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
String todayStr = sdf.format(new Date());
stringBuilder.append(todayStr).append(separator);
stringBuilder.append(filename);
return stringBuilder.toString();
}
/**
* 上传图片到minio
* @param prefix
* @param filename
* @param inputStream
* @return
*/
public String uploadImgFile(String prefix, String filename, InputStream inputStream) {
String filePath = this.builderFilePath(prefix, filename);
try {
//创建上传配置
PutObjectArgs putObjectArgs = PutObjectArgs.builder().object(filePath).contentType("image/jpg").
bucket(this.minIoConfigProperties.getBucket()).stream(inputStream, inputStream.available(), -1L)
.build();
//上传
this.minioClient.putObject(putObjectArgs);
StringBuilder urlPath = new StringBuilder(this.minIoConfigProperties.getEndpoint());
urlPath.append(separator).append(this.minIoConfigProperties.getBucket());
urlPath.append(separator);
urlPath.append(filePath);
//返回文件访问路径
return urlPath.toString();
} catch (Exception e) {
log.error("minio put file error.", e);
throw new RuntimeException("上传文件失败");
}
}
/**
* 上传html文件到Minio
* @param prefix
* @param filename
* @param inputStream
* @return
*/
public String uploadHtmlFile(String prefix, String filename, InputStream inputStream) {
String filePath = this.builderFilePath(prefix, filename);
try {
PutObjectArgs putObjectArgs = PutObjectArgs.builder().object(filePath).contentType("text/html")
.bucket(this.minIoConfigProperties.getBucket()).stream(inputStream, inputStream.available(), -1L)
.build();
this.minioClient.putObject(putObjectArgs);
StringBuilder urlPath = new StringBuilder(this.minIoConfigProperties.getEndpoint());
urlPath.append(separator).append(this.minIoConfigProperties.getBucket());
urlPath.append(separator);
urlPath.append(filePath);
return urlPath.toString();
} catch (Exception e) {
log.error("minio put file error.", e);
e.printStackTrace();
throw new RuntimeException("上传文件失败");
}
}
/**
* 删除文件
* @param pathUrl
*/
public void delete(String pathUrl) {
String key = pathUrl.replace(this.minIoConfigProperties.getEndpoint() + separator, "");
int index = key.indexOf(separator);
String bucket = key.substring(0, index);
String filePath = key.substring(index + 1);
RemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder().bucket(bucket).object(filePath).build();
try {
this.minioClient.removeObject(removeObjectArgs);
} catch (Exception e) {
log.error("minio remove file error. pathUrl:{}", pathUrl);
e.printStackTrace();
throw new RuntimeException("删除文件失败");
}
}
/**
* 下载文件
* @param pathUrl
* @return
*/
public byte[] downLoadFile(String pathUrl) {
String key = pathUrl.replace(this.minIoConfigProperties.getEndpoint() + separator, "");
int index = key.indexOf(separator);
key.substring(0, index);
String filePath = key.substring(index + 1);
InputStream inputStream = null;
try {
GetObjectArgs args = GetObjectArgs.builder().bucket(this.minIoConfigProperties.getBucket())
.object(filePath).build();
inputStream = this.minioClient.getObject(args);
} catch (Exception e) {
log.error("minio down file error. pathUrl:{}", pathUrl);
e.printStackTrace();
throw new RuntimeException("文件下载失败");
}
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] buff = new byte[100];
int rc = 0;
while(true) {
try {
if ((rc = inputStream.read(buff, 0, 100)) <= 0) {
return byteArrayOutputStream.toByteArray();
}
} catch (IOException e) {
e.printStackTrace();
}
byteArrayOutputStream.write(buff, 0, rc);
}
}
}
3.7mvn install
将写好的项目安装到本地仓库
3.7测试方法
创建一个新的test模块,然后测试方法
在pom.xml中引入
<dependency>
<groupId>com.common.oss</groupId>
<artifactId>common-oss-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
然后再application.xml中配置minio相关信息
server:
port: 8888
minio:
endpoint: http://192.168.81.128:9000
access-key: minio
bucket: leadnews
secret-key: dodo123456
然后我们创建一个test.html网页,还有准备一张图片
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>
测试网页
</div>
</body>
</html>
测试上传方法:
@SpringBootTest
class LeadnewTestApplicationTests {
@Autowired
private MinIoTemplate minIoTemplate;
@Test
void contextLoads() throws FileNotFoundException {
String s = minIoTemplate.uploadImgFile("", "test.img", new FileInputStream("C:\\Users\\10464\\Pictures\\商品\\白色.jpg"));
System.out.println(s);
}
@Test
void testDelte(){
minIoTemplate.delete("leadnews/2023/12/17/test.img");
}
@Test
void downloadImg(){
byte[] bytes = minIoTemplate.downLoadFile("leadnews/2023/12/17/test.img");
System.out.print(bytes.length);
}
@Test
void uploadHtml() throws IOException {
String s = minIoTemplate.uploadHtmlFile("", "test.html", Files.newInputStream(Paths.get("C:\\cloudProgram\\leadnew-test\\src\\main\\resources\\test.html")));
System.out.println(s);
}
}
然后我们打开minio控制台:
图片和网页成功上传到minio上了!