使用SpringBoot将中国地震台网数据保存PostGIS数据库实践

目录

前言

一、数据转换

1、Json转JavaBean

2、JavaBean与数据库字段映射

二、空间数据表设计

1、表结构设计

三、PostGIS数据保存

1、Mapper接口定义

2、Service逻辑层实现

3、数据入库

4、运行实例及结果

总结


前言

        在上一篇博客中基于Java的XxlCrawler网络信息爬取实战-以中国地震台网为例,我们使用Java语言采用XxlCrawer组件进行中国地震台网数据的爬取,相信大家对如何抓取这种接口数据一定有了基本的认识,也掌握了如何基于XxlCrawer来实现自己的信息爬取实战。但是在前面的博客当中,我们仅仅是将信息爬取下来。为了在我们自己的应用系统中来应用这些基础数据,需要我们将爬取的数据进行存储起来。由于地震数据包含了空间位置信息,为方便进行空间分析的实现。这里我们将爬取的中国地震信息存储到PostGIS空间数据库中,为下一步的数据分析和可视化呈现奠定良好的基础。

        本文即紧紧围绕着将信息保存到空间数据库的目标,重点讲解如何实现将中国地震台网爬取的地震信息保存到PostGIS空间数据库中。首先讲解在爬取过程中数据格式和响应数据类型的转换,将网站回传的json数据转成符合Java命名规范的数据。然后介绍台网地震信息表的设计,如何构建空间数据表。再次介绍如何将爬取的数据调用Mybatis-Plus组件实现批量入库。如果您当前也有对地震等地质灾害数据进行分析的需求,不妨看看本博文。

一、数据转换

        在前面的博客中有提到,在中国地震台网中展示接口数据,将请求数据在浏览器中进行查看。可以看到以下的格式:

        通过这个接口可以看到,官方返回的数据中,其所有的字段名都是大写的,如下所示:

AUTO_FLAG: "M"
CATA_ID: "CD20240413222636.00"
CATA_TYPE: ""
EPI_DEPTH: 9
EPI_LAT: "24.05"
EPI_LON: "121.60"
EQ_CATA_TYPE: ""
EQ_TYPE: "M"
IS_DEL: ""
LOCATION_C: "台湾花莲县"
LOCATION_S: ""
LOC_STN: "0"
M: "4.2"
M_MB: "0"
M_MB2: "0"
M_ML: "0"
M_MS: "0"
M_MS7: "0"
NEW_DID: "CD20240413222636"
O_TIME: "2024-04-13 22:26:35"
O_TIME_FRA: "0"
SAVE_TIME: "2024-04-13 22:35:56"
SUM_STN: "0"
SYNC_TIME: "2024-04-13 22:35:56"
id: "46396"

        为了让更好的使用Java语言进行开发,使这些变量名变得更加合适,同时满足Java的编程规范。因此办结来重点讲解怎么将 json返回的数据转成java的合理变量名。

1、Json转JavaBean

        如上所言,在使用XxlCrawler进行信息爬取之后,返回的数据名称不太符合Java的命名规则。那针对这种需求,有没有什么办法来进行调整呢。答案是肯定的,不管是用Gson或者fastJson,这些设计良好的json处理框架其实都包含了Json对象与JavaBean对象的互相转换。当给定格式不符合Java命名规范的属性名,可以通过注解映射的方式修改成符合Java编码规范的变量。由于本实例中采用的是Gson组件,因此给出的示例代码也是基于Gson来实现的,其它的实现组件请自行搜索相关知识,根据官方文档的知识来进行设置。

        在Gson中,主要是采用@SerializedName("AUTO_FLAG")这个注解,注解后面的字段是通过接口返回的数据字段。把这个注解配置到属性中,表示当前属性对应哪个接口的字段。关键代码如下:

package com.yelang.project.extend.earthquake.domain.crawler;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class CeicEarthquake implements Serializable{private static final long serialVersionUID = -1212153879708670015L;private Long pkId;//主键@SerializedName("AUTO_FLAG")private String autoFlag;@SerializedName("CATA_ID")private String cataId;@SerializedName("CATA_TYPE")private String cataType;@SerializedName("EPI_DEPTH")private BigDecimal epiDepth = new BigDecimal("0.0");@SerializedName("EPI_LAT")private String epiLat;//纬度@SerializedName("EPI_LON")private String epiLon;@SerializedName("EQ_CATA_TYPE")private String eqCataType;@SerializedName("EQ_TYPE")private String eqType;@SerializedName("IS_DEL")private String isDel;@SerializedName("LOCATION_C")private String locationC;@SerializedName("LOCATION_S")private String locationS;@SerializedName("LOC_STN")private String locStn;@SerializedName("M")private String m;@SerializedName("M_MB")private String mmb;@SerializedName("M_MB2")private String mmb2;@SerializedName("M_ML")private String mml;@SerializedName("M_MS")private String mms;@SerializedName("M_MS7")private String mms7;@SerializedName("NEW_DID")private String newDid;@SerializedName("O_TIME")private Date oTime;@SerializedName("O_TIME_FRA")private String oTimeFra;@SerializedName("SAVE_TIME")private Date saveTime;@SerializedName("SUM_STN")private String sumStn;@SerializedName("SYNC_TIME")private Date syncTime;@SerializedName("id")private String epiId;
}

        通过以上的代码就可以实现将接口返回的参数映射成符合我们需求的JavaBean。

2、JavaBean与数据库字段映射

        众所周知,数据的命名一般是用小写,而且单词之间一般使用下划线连接起来。而Java中对属性的命名与数据库的字段还是有一定的差异。好在我们采用的是Mybatis_Plus这个框架,可以实现数据库字段和JavaBean的对应。为了后续介绍方便,这里将直接给出空间字段的设置。以实体类代码的形式给出。在Mybatis_Plus中,主要采用@TableField(value="cata_type")来进行数据库字段的设置。完整的代码如下所示:

package com.yelang.project.extend.earthquake.domain.crawler;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.google.gson.annotations.SerializedName;
import com.yelang.framework.handler.PgGeometryTypeHandler;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
@TableName(value ="biz_ceic_earthquake",autoResultMap = true)
public class CeicEarthquake implements Serializable{private static final long serialVersionUID = -1212153879708670015L;@TableId(value="pk_id")private Long pkId;//主键@SerializedName("AUTO_FLAG")@TableField(value="auto_flag")private String autoFlag;@SerializedName("CATA_ID")@TableField(value="cata_id")private String cataId;@SerializedName("CATA_TYPE")@TableField(value="cata_type")private String cataType;@SerializedName("EPI_DEPTH")@TableField(value="epi_depth")private BigDecimal epiDepth = new BigDecimal("0.0");@SerializedName("EPI_LAT")@TableField(value="epi_lat")private String epiLat;//纬度@SerializedName("EPI_LON")@TableField(value="epi_lon")private String epiLon;@SerializedName("EQ_CATA_TYPE")@TableField(value="eq_cata_type")private String eqCataType;@SerializedName("EQ_TYPE")@TableField(value="eq_type")private String eqType;@SerializedName("IS_DEL")@TableField(value="is_del")private String isDel;@SerializedName("LOCATION_C")@TableField(value="location_c")private String locationC;@SerializedName("LOCATION_S")@TableField(value="location_s")private String locationS;@SerializedName("LOC_STN")@TableField(value="loc_stn")private String locStn;@SerializedName("M")@TableField(value="m")private String m;@SerializedName("M_MB")@TableField(value="mmb")private String mmb;@SerializedName("M_MB2")@TableField(value="mmb2")private String mmb2;@SerializedName("M_ML")@TableField(value="mml")private String mml;@SerializedName("M_MS")@TableField(value="mms")private String mms;@SerializedName("M_MS7")@TableField(value="mms7")private String mms7;@SerializedName("NEW_DID")@TableField(value="new_did")private String newDid;@SerializedName("O_TIME")@TableField(value="o_time")private Date oTime;@SerializedName("O_TIME_FRA")@TableField(value="o_time_fra")private String oTimeFra;@SerializedName("SAVE_TIME")@TableField(value="save_time")private Date saveTime;@SerializedName("SUM_STN")@TableField(value="sum_stn")private String sumStn;@SerializedName("SYNC_TIME")@TableField(value="sync_time")private Date syncTime;@SerializedName("id")@TableField(value="epi_id")private String epiId;@TableField(typeHandler = PgGeometryTypeHandler.class)private String geom;@TableField(exist=false)private String geomJson;
}

二、空间数据表设计

        在很多的技术博客当中,都提到过如何进行空间数据库的设计,与常规的关系型数据库表不一样的是,空间数据库多了空间信息的存储的查询。以地震信息为例,就包含了其经纬度坐标信息。因此这里使用PostGIS作为空间数据库存储空间信息。

        在讲解改表是,我们首先根据接口的字段来定义其关键属性字段,然后自己设计Geometry字段,通过爬取的经纬度信息来生成Geometry信息,然后保存到相应的字段当中。

1、表结构设计

        主要表结构设计如下,包含了通过接口返回的基本信息:

 

         生成出来的SQL语句如下,如果需要的话,可以直接使用,这里直接提供,供大家参考。

CREATE TABLE "public"."biz_ceic_earthquake" ("pk_id" int8 NOT NULL,"auto_flag" varchar(30) COLLATE "pg_catalog"."default","cata_id" varchar(30) COLLATE "pg_catalog"."default","cata_type" varchar(30) COLLATE "pg_catalog"."default","epi_depth" numeric(11,8),"epi_lat" varchar(15) COLLATE "pg_catalog"."default","epi_lon" varchar(15) COLLATE "pg_catalog"."default","eq_cata_type" varchar(30) COLLATE "pg_catalog"."default","eq_type" varchar(30) COLLATE "pg_catalog"."default","is_del" varchar(6) COLLATE "pg_catalog"."default","location_c" varchar(255) COLLATE "pg_catalog"."default","location_s" varchar(100) COLLATE "pg_catalog"."default","loc_stn" varchar(20) COLLATE "pg_catalog"."default","m" varchar(10) COLLATE "pg_catalog"."default","mmb" varchar(10) COLLATE "pg_catalog"."default","mmb2" varchar(10) COLLATE "pg_catalog"."default","mml" varchar(10) COLLATE "pg_catalog"."default","mms" varchar(10) COLLATE "pg_catalog"."default","mms7" varchar(10) COLLATE "pg_catalog"."default","new_did" varchar(16) COLLATE "pg_catalog"."default","o_time" timestamp(6),"o_time_fra" varchar(10) COLLATE "pg_catalog"."default","save_time" timestamp(6),"sum_stn" varchar(10) COLLATE "pg_catalog"."default","sync_time" timestamp(6),"epi_id" varchar(10) COLLATE "pg_catalog"."default","geom" "public"."geometry",CONSTRAINT "pk_biz_ceic_earthquake" PRIMARY KEY ("pk_id")
);
CREATE INDEX "idx_biz_ceic_earthquake_eqidept" ON "public"."biz_ceic_earthquake" USING btree ("epi_depth" "pg_catalog"."numeric_ops" ASC NULLS LAST
);
CREATE INDEX "idx_biz_ceic_earthquake_geom" ON "public"."biz_ceic_earthquake" USING gist ("geom" "public"."gist_geometry_ops_2d"
);
CREATE INDEX "idx_biz_ceic_earthquake_m" ON "public"."biz_ceic_earthquake" USING btree ("m" COLLATE "pg_catalog"."default" "pg_catalog"."text_ops" ASC NULLS LAST
);
COMMENT ON COLUMN "public"."biz_ceic_earthquake"."pk_id" IS '主键id';

        为了在查询的时候提高查询性能,我们建立三个索引,两个普通索引和一个空间索引,构建在geom这个字段上的。后期如果要做空间分析可以使用空间索引进行查询效率提升。

三、PostGIS数据保存

        设计好了地震信息空间数据表,信息接口也进行了定义。万事俱备只欠东风,只需要采用Mybatis_Plus组件将爬取的信息通过接口保存到PostGIS空间数据库中即可。在第一节中其实已经将实现接口参数转换成数据库字段,关于实体类的定义在此不赘述,这里只将数据入库的流程和方法进行简单介绍。ORM框架采用Mybatis_Plus框架。

1、Mapper接口定义

        mapper接口相当于是数据库操作的总入口,由于这里仅演示如何插入数据,暂时没有其它的业务需求,因此接口中除集成的方法,暂不新增新的方法。

package com.yelang.project.extend.earthquake.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yelang.project.extend.earthquake.domain.crawler.CeicEarthquake;
public interface CeicEarthquakeMapper extends BaseMapper<CeicEarthquake>{
}

2、Service逻辑层实现

        业务逻辑层也比较简单,为了演示效果,同样不增加额外的方法,仅实现MP自带的批量插入功能来实现数据插入。

package com.yelang.project.extend.earthquake.service.impl;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yelang.project.extend.earthquake.domain.crawler.CeicEarthquake;
import com.yelang.project.extend.earthquake.mapper.CeicEarthquakeMapper;
import com.yelang.project.extend.earthquake.service.ICeicEarthquakeService;
@Service
public class CeicEarthquakeServiceImpl extends ServiceImpl<CeicEarthquakeMapper, CeicEarthquake> implements ICeicEarthquakeService{
}

3、数据入库

        数据入库主要是调用ICeicEarthquakeService的批量插入方法。这里采用Junit测试套件进行爬取测试。实际情况可以内置到SpringBoot的一个方法或者定时任务当中。在这里需要注意的一个地方就是,我们在数据库中定义了一个Geometry字段来存储空间点信息。因此在信息爬取过程中需要动态生成,主要是手动构造Wkt格式的数据,通过PgGeometryTypeHandler来实现空间类型转换,看过博客的朋友应该对这种操作方法很熟悉。爬取及入库的代码如下:

package com.yelang.project;
import java.util.Date;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.xuxueli.crawler.XxlCrawler;
import com.xuxueli.crawler.parser.strategy.NonPageParser;
import com.yelang.common.utils.StringUtils;
import com.yelang.project.extend.earthquake.domain.crawler.CeicDateAdapter;
import com.yelang.project.extend.earthquake.domain.crawler.CeicEarthquake;
import com.yelang.project.extend.earthquake.domain.crawler.CeicEarthquakeCrawler;
import com.yelang.project.extend.earthquake.service.ICeicEarthquakeService;
@SpringBootTest
@RunWith(SpringRunner.class)
public class TestXxlCrawerCeic {@Autowiredprivate ICeicEarthquakeService service;@Testpublic void testGetCeic() {String commonUrl = "https://www.ceic.ac.cn/ajax/search?start=&&end=&&jingdu1=&&jingdu2=&&weidu1=&&weidu2=&&height1=&&height2=&&zhenji1=&&zhenji2=&_="+ System.currentTimeMillis();String[] urlList = new String[20];urlList[0] = commonUrl + "&&page=" + 1;// 构造爬虫XxlCrawler crawler = new XxlCrawler.Builder().setUrls(urlList).setThreadCount(3).setPauseMillis(3000).setUserAgent("Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36").setIfPost(false).setFailRetryCount(3)// 重试三次.setPageParser(new NonPageParser() {public void parse(String url, String pageSource) {if (!StringUtils.isBlank(pageSource)) {pageSource = pageSource.substring(1, pageSource.length() - 1);Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, new CeicDateAdapter()).create();CeicEarthquakeCrawler crawler = gson.fromJson(pageSource, CeicEarthquakeCrawler.class);System.out.println("总页数:"+crawler.getNum());for (CeicEarthquake data : crawler.getShuju()) {String geom = "SRID=" + 4326 +";POINT (" + data.getEpiLon()+ " "+data.getEpiLat()+")";//拼接srid,实现动态写入System.out.println(data);System.out.println(geom);data.setGeom(geom);}service.saveBatch(crawler.getShuju(), 300);}}}).build();crawler.start(true);// 启动}
}

        上面代码的关键就是WKT的构造,默认采用4326坐标系:

String geom = "SRID=" + 4326 +";POINT (" + data.getEpiLon()+ " "+data.getEpiLat()+")";//拼接srid,实现动态写入

4、运行实例及结果

        使用Junit的测试套件运行上述方法,在控制台可以看到如下的打印结果:

        很明显在控制台中看到批量插入语句和信息爬取信息,示例信息如下:

CeicEarthquake(pkId=null, autoFlag=M, cataId=CD20240407190310.00, cataType=, epiDepth=18, epiLat=41.89, epiLon=82.17, eqCataType=, eqType=M, isDel=, locationC=新疆阿克苏地区拜城县, locationS=, locStn=0, m=4.2, mmb=0, mmb2=0, mml=0, mms=0, mms7=0, newDid=CD20240407190310, oTime=Sun Apr 07 19:03:09 CST 2024, oTimeFra=0, saveTime=Sun Apr 07 19:08:03 CST 2024, sumStn=0, syncTime=Sun Apr 07 19:08:03 CST 2024, epiId=46366, geom=null, geomJson=null)
SRID=4326;POINT (82.17 41.89)
CeicEarthquake(pkId=null, autoFlag=M, cataId=CD20240407182216.00, cataType=, epiDepth=15, epiLat=41.91, epiLon=82.00, eqCataType=, eqType=M, isDel=, locationC=新疆阿克苏地区拜城县, locationS=, locStn=0, m=3.0, mmb=0, mmb2=0, mml=0, mms=0, mms7=0, newDid=CD20240407182216, oTime=Sun Apr 07 18:22:16 CST 2024, oTimeFra=0, saveTime=Sun Apr 07 18:27:58 CST 2024, sumStn=0, syncTime=Sun Apr 07 18:27:58 CST 2024, epiId=46365, geom=null, geomJson=null)
SRID=4326;POINT (82.00 41.91)
19:43:44.403 [pool-2-thread-2] DEBUG c.y.p.e.e.m.C.insert - [debug,137] - ==>  Preparing: INSERT INTO biz_ceic_earthquake ( pk_id, auto_flag, cata_id, cata_type, epi_depth, epi_lat, epi_lon, eq_cata_type, eq_type, is_del, location_c, location_s, loc_stn, m, mmb, mmb2, mml, mms, mms7, new_did, o_time, o_time_fra, save_time, sum_stn, sync_time, epi_id, geom ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )
19:43:44.548 [pool-2-thread-2] DEBUG c.y.p.e.e.m.C.insert - [debug,137] - ==> Parameters: 1780562787278299138(Long), M(String), CD20240411005512.00(String), (String), 12(BigDecimal), 24.14(String), 121.87(String), (String), M(String), (String), 台湾花莲县海域(String), (String), 0(String), 4.4(String), 0(String), 0(String), 0(String), 0(String), 0(String), CD20240411005512(String), 2024-04-11 00:55:12.0(Timestamp), 0(String), 2024-04-11 01:05:21.0(Timestamp), 0(String), 2024-04-11 01:05:21.0(Timestamp), 46385(String), SRID=4326;POINT(121.87 24.14)(PGgeometry)

         最后来看一下在PostGIS当中是否将数据成功入库,在客户端中执行以下查询语句:

select * from biz_ceic_earthquake;

        通过上述界面看到,通过XxlCrawler爬取的信息就成功的保存到了PostGIS空间数据库中。

总结

        以上就是本文的主要内容,本文即紧紧围绕着将信息保存到空间数据库的目标,重点讲解如何实现将中国地震台网爬取的地震信息保存到PostGIS空间数据库中。首先讲解在爬取过程中数据格式和响应数据类型的转换,将网站回传的json数据转成符合Java命名规范的数据。然后介绍台网地震信息表的设计,如何构建空间数据表。再次介绍如何将爬取的数据调用Mybatis-Plus组件实现批量入库。行文仓促,定有不足,欢迎朋友们在评论浏览批评指正,不胜感激。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/823633.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c++的学习之路:23、多态(2)

摘要 多态的抽象类、原理以及虚表。 目录 摘要 一、抽象类 1、 概念 2、接口继承和实现继承 二、多态的原理 1、虚函数表 2、动态绑定与静态绑定 三、单继承和多继承关系的虚函数表 1、单继承中的虚函数表 2、多继承中的虚函数表 四、思维导图 一、抽象类 1、 概…

消息中间件Kafka分布式数据处理平台

目录 一.Kafka基本介绍 1.定义 2.特点 &#xff08;1&#xff09;高吞吐量、低延迟 &#xff08;2&#xff09;可扩展性 &#xff08;3&#xff09;持久性、可靠性 &#xff08;4&#xff09;容错性 &#xff08;5&#xff09;高并发 3.系统架构 &#xff08;1&#…

华为海思校园招聘-芯片-数字 IC 方向 题目分享——第五套

华为海思校园招聘-芯片-数字 IC 方向 题目分享——第五套 (共9套&#xff0c;有答案和解析&#xff0c;答案非官方&#xff0c;仅供参考&#xff09;&#xff08;共九套&#xff0c;每套四十个选择题&#xff09; 部分题目分享&#xff0c;完整版获取&#xff08;WX:didadida…

JVM 方法调用之方法分派

JVM 方法调用之方法分派 文章目录 JVM 方法调用之方法分派1.何为分派2.静态分派3.动态分派4.单分派与多分派5.动态分派的实现 1.何为分派 在上一篇文章《方法调用之解析调用》中讲到了解析调用&#xff0c;而解析调用是一个静态过程&#xff0c;在类加载的解析阶段就确定了方法…

ECharts:五大卓越在线示例库助力高效数据可视化开发

1. ECharts官方示例库 ECharts官网提供的示例库是最权威、最新的展示平台&#xff0c;涵盖了所有基础和高级图表类型&#xff0c;每个示例都配有详尽的代码解释和配置说明。开发者可以直接查看源代码&#xff0c;复制粘贴后稍加修改就能应用于实际项目中。 2. Make A Pie - EC…

【笔试训练】day4

不到5分钟写完&#xff0c;今天的题又又又难一点啦! 1.Fibonacci数列 思路&#xff1a; 直接模拟一遍斐波那契数列的递增过程&#xff0c;大于n就直接结束。因为后面只会越来越大&#xff0c;跟题目求的最小步数不符。在这个过程中用一个变量去维护这个当前的元素与目标n还差…

【编程TOOL】VC++6.0下载安装配置使用保姆式教程

目录 ​编辑 1.软件介绍 2.软件下载 3.软件安装 3.1.下载得到可执行文件并双击进行安装 3.2. 点击下一步 3.3. 选择安装位置 3.4. 勾选“创建桌面快捷方式”并点击下一步 5. 点击安装并等待 3.6. 先取消运行&#xff0c;后点击完成&#xff0c;软件即安装完毕 4.兼容性配置 4.1…

基于SpringBoot+Vue的疾病防控系统设计与实现(源码+文档+包运行)

一.系统概述 在如今社会上&#xff0c;关于信息上面的处理&#xff0c;没有任何一个企业或者个人会忽视&#xff0c;如何让信息急速传递&#xff0c;并且归档储存查询&#xff0c;采用之前的纸张记录模式已经不符合当前使用要求了。所以&#xff0c;对疾病防控信息管理的提升&a…

IoC与Spring

目录 IoC控制反转 现实案例 特点 目的 DI依赖注入 小总结 介绍Spring 狭义和广义上的Spring 传统编码方式的不足 需求引入 弊端分析 IoC控制反转 现实案例 1、买水果问老板各种水果的口感而不是自己去挨个尝试一遍。 2、买房子找中介而不是自己去花时间找房东。…

别找了,这35份Excel自动排班表真的好用!

别再自己做排班表了&#xff0c;调了半天不好看格式还不对。 看看自己需要的是哪些类型的排班表&#xff1f;是公司值班&#xff0c;还是直播排班&#xff0c;还是考勤汇总&#xff0c;总有一个适合你。 刚整理的35份办公常用的排班表&#xff0c;希望能帮到你&#xff01; …

基于Python的机器学习的文本分类系统

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

CentOS 7安装Redis

说明&#xff1a;本文介绍如何在CentOS 7操作系统下安装Redis 下载安装 首先&#xff0c;去官网上下载所需要安装的版本&#xff0c;官网地址&#xff1a;https://download.redis.io/releases/&#xff0c;我这里下载3.2.1版本的 下载完&#xff0c;上传到云服务器上&#xf…

<router-link>出现Error: No match for {“name“:“home“,“params“:{}}

在将<a></a>标签换到<router-link></router-link>的时候出现No match for {"name":"home","params":{}}这样的错误&#xff0c;其中格式并无错误&#xff0c; <router-link class"navbar-brand active" …

她在《繁花》大放异彩,“浪姐”暴瘦15斤,打脸了不看好她的观众

不知不觉&#xff0c;《浪姐》已经迎来第5季了。播到第4季的时候&#xff0c;改名成《乘风破浪2023》&#xff0c;这一季叫《乘风2024》&#xff0c;和前几季相比&#xff0c;热度依然不减。 都说3个女人一台戏&#xff0c;更何况这个节目&#xff0c;每次能请到30位姐姐&…

刷题。。。。。。

1.ezmd5 根据题目提示 我们知道应该是要上传两张md5值相同的图片 根据原文链接&#xff1a;cryptanalysis - Are there two known strings which have the same MD5 hash value? - Cryptography Stack Exchange 把保存下来的图片上传一下 得到flag 2.ezhttp 根据原文链接&…

node基础 第二篇

01 ffmpeg开源跨平台多媒体处理工具&#xff0c;处理音视频&#xff0c;剪辑&#xff0c;合并&#xff0c;转码等 FFmpeg 的主要功能和特性:1.格式转换:FFmpeg 可以将一个媒体文件从一种格式转换为另一种格式&#xff0c;支持几乎所有常见的音频和视频格式&#xff0c;包括 MP…

冲上热搜-奇安信今年的年终奖。。

最近,奇安信宣布全员无年终奖&#xff0c;同时冲上了脉脉热搜榜第一。作为网安界的一哥&#xff0c;奇安信的决定无疑给许多期待年终奖的员工带来了沉重的打击。 从公司内部的绩效考核机制来看,奇安信将员工分为了5个档次:S、A、B、B、B-。而大多数员工被评定为中等的B档,这意味…

【网络编程】web服务器shttpd源码剖析——命令行和文件配置解析

hello &#xff01;大家好呀&#xff01; 欢迎大家来到我的网络编程系列之web服务器shttpd源码剖析——命令行解析&#xff0c;在这篇文章中&#xff0c;你将会学习到在Linux内核中如何创建一个自己的并发服务器shttpd&#xff0c;并且我会给出源码进行剖析&#xff0c;以及手绘…

C++异常学习

C语言传统的处理错误的方式 传统的错误处理机制&#xff1a; 终止程序&#xff0c;如assert&#xff0c;缺陷&#xff1a;用户难以接受。如发生内存错误&#xff0c;除0错误时就会终止程序。返回错误码&#xff0c;缺陷&#xff1a;需要程序员自己去查找对应的错误。如系统的…

ES增强框架easy-es

因为最近做的功能是关于舆情的,所以数据量比较大的,本来打算用MySQL做时间分表来做,但是经过一段时间的测试,发现数据量太大,用时间分表不能满足性能的要求,所以决定将数据存储改为ES,但是短时间内改底层框架又不是一个小工程,时间上不允许,所以找到了一个很合适的框架,他跟myb…