Java实现excel表数据的批量存储(结合easyexcel插件)
场景:加哥最近在做项目时,苦于系统自身并未提供数据批量导入的功能还不能自行添加上该功能,且自身不想手动一条一条将数据录入系统。随后,自己使用JDBC连接数据库、使用EasyExcel插件读取表格并将数据按照业务逻辑批量插入数据库完成数据的初始化。接下来就看看加哥是怎么做的呢?
第一步:创建一个maven项目并导入依赖。
结合项目需要,只需要数据库和easyexcel的依赖包(在这里加哥使用的是mysql数据库,引入的就是mysql的数据库驱动,如果你想用sqlServer等数据库自行更换依赖就行)。
<!--数据库驱动--> <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.21</version> </dependency> <!--表格导入处理--> <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.1.3</version> </dependency>
第二步:手写或者准备好JDBC连接、操作数据库的工具类。
在这里加哥是把JDBC连接数据库、操作数据库、关闭数据库封装成了工具类并用static修饰作为静态方法,方便后面使用时候直接使用类型.方法调用。
以下是数据库的驱动、url、用户名、密码定义
//驱动 private static String driver = "com.mysql.jdbc.Driver"; //URL private static String url = "jdbc:mysql://127.0.0.1:3306/mytestcharacterEncoding=utf-8&serverTimezone=Asia/Shanghai"; //用户名 private static String username = "root"; // 密码 private static String pwd = "123456";
连接数据库的方法,由于使用比较频繁将其抽取为一个独立的方法,该方法主要是加载驱动、创建连接。自己可以定义好后,在main方法中直接调用若执行通过则和数据库建立连接成功,否则失败。
/*** 创建连接* @return*/ public static Connection getConnection(){Connection connection=null;//加载驱动try {Class.forName(driver);} catch (ClassNotFoundException e) {e.printStackTrace();}//建立连接获取Connection对象try {connection= DriverManager.getConnection(url,username,pwd);} catch (SQLException e) {e.printStackTrace();}return connection; }
关闭连接,由于每次创建连接、都会有一个新的连接打开,如果一直不关闭就会出现连接建立满了的情况,也容易造成资源浪费,因为每次都必须关闭则也将其抽取成一个独立的方法。
/*** 关闭链接* @param connection* @param statement* @param resultSet*/ public static void closeAll(Connection connection, Statement statement, ResultSet resultSet){try {if(resultSet!=null){resultSet.close();}if(statement!=null){statement.close();}if (connection!=null){connection.close();}} catch (SQLException e) {e.printStackTrace();} }
封装增删改方法,由于增删改调用的方法一致,则可以将其抽取成一个公用方法,在后面需要的时候直接调用该方法即可。查询方法由于每次处理的数据不一致,不适合做成公用方法。
/*** 执行增、删、改的方法* @param sql* @return*/ public static int execute(String sql){//获取链接Connection connection=getConnection();int flag=0;try {//创建Statement对象Statement statement=connection.createStatement();//执行sql语句flag=statement.executeUpdate(sql);//关闭链接closeAll(connection,statement,null);} catch (SQLException e) {e.printStackTrace();}return flag; }
最后,为了保证我们写的方法可以正常建立连接、关闭连接、完成对应操作,需要大家创建一个main方法完成测试,下面是加哥给大家提供的。但是你在测试过程中,必须保证自己的数据库及其表、表字段都存在。
/*测试*/ public static void main(String[] args) {String sql = "SELECT * FROM bs_structure WHERE id = 1688350472671";Connection connection = getConnection();Statement statement = null;try {statement= connection.createStatement();ResultSet resultSet = statement.executeQuery(sql);while(resultSet.next()){String typename = resultSet.getString(3);System.out.println("类别名称:"+typename);}} catch (SQLException e) {e.printStackTrace();} }
第三步、创建实体类
实体类的属性必须和excel表格的列数一致,一般有多少列就会定义多少个属性,这里的实体类就是为了后面读取表格时映射处理使用的。以下是加哥的表格式,由于模版有12列则加哥定义了12个属性。大家可以结合自己excel表格的实际情况去完成。
实体类
public class Structure {@ExcelProperty(value = "序号", index = 0)private String param1;@ExcelProperty(value = "水厂", index = 1)private String param2;@ExcelProperty(value = "工艺", index = 2)private String param3;@ExcelProperty(value = "设备", index = 3)private String param4;@ExcelProperty(value = "测点", index = 4)private String param5;@ExcelProperty(value = "点长名", index = 6)private String param6;@ExcelProperty(value = "点描述", index = 7)private String param7;@ExcelProperty(value = "设备类型名称", index = 11)private String param8;@ExcelProperty(value = "数据类型", index = 8)private String param9;@ExcelProperty(value = "小数位数", index = 9)private String param10;@ExcelProperty(value = "单位", index = 10)private String param11;@ExcelProperty(value = "测点名称", index = 5)private String param12;public String getParam1() {return param1;}public void setParam1(String param1) {this.param1 = param1;}public String getParam2() {return param2;}public void setParam2(String param2) {this.param2 = param2;}public String getParam3() {return param3;}public void setParam3(String param3) {this.param3 = param3;}public String getParam4() {return param4;}public void setParam4(String param4) {this.param4 = param4;}public String getParam5() {return param5;}public void setParam5(String param5) {this.param5 = param5;}public String getParam6() {return param6;}public void setParam6(String param6) {this.param6 = param6;}public String getParam7() {return param7;}public void setParam7(String param7) {this.param7 = param7;}public String getParam8() {return param8;}public void setParam8(String param8) {this.param8 = param8;}public String getParam9() {return param9;}public void setParam9(String param9) {this.param9 = param9;}public String getParam10() {return param10;}public void setParam10(String param10) {this.param10 = param10;}public String getParam11() {return param11;}public void setParam11(String param11) {this.param11 = param11;}public String getParam12() {return param12;}public void setParam12(String param12) {this.param12 = param12;} }
第四步、定义DAO层
在DAO层定义并实现自己需要操作数据库表的方法,加哥在这里直接在DAO层实现并区分接口和实现类,大家可以区分开来做。
public String selectParentId(String param) throws SQLException {String sql = "select id from bs_structure where structure_name='" + param + "'";Connection connection = BaseDao.getConnection();Statement statement = connection.createStatement();ResultSet resultSet = statement.executeQuery(sql);String id = "";while (resultSet.next()) {id = resultSet.getString(1);}BaseDao.closeAll(connection,statement,resultSet);return id;}public String selectParentId1(String param,String param1) throws SQLException {String sql = "select id from bs_structure where structure_name='" + param + "' and parent_uuid= '"+param1+"'";Connection connection = BaseDao.getConnection();Statement statement = connection.createStatement();ResultSet resultSet = statement.executeQuery(sql);String id = "";while (resultSet.next()) {id = resultSet.getString(1);}BaseDao.closeAll(connection,statement,resultSet);return id;}public String selectCedianId1(String param,String param1) throws SQLException {String sql = "select id from bs_monitor_attr where structure_uuid='" + param + "' and tag_long_name= '"+param1+"'";Connection connection = BaseDao.getConnection();Statement statement = connection.createStatement();ResultSet resultSet = statement.executeQuery(sql);String id = "";while (resultSet.next()) {id = resultSet.getString(1);}BaseDao.closeAll(connection,statement,resultSet);return id;}public String selectObjectId(String objectType, String typename) throws SQLException {String sql = "SELECT id FROM `bs_object` where object_type='" + objectType + "' and type_name='" + typename + "'";Connection connection = BaseDao.getConnection();Statement statement = connection.createStatement();ResultSet resultSet = statement.executeQuery(sql);String id = "";while (resultSet.next()) {id = resultSet.getString(1);}BaseDao.closeAll(connection,statement,resultSet);return id; } public String selectObjectId1(String typename) throws SQLException {String sql = "SELECT id FROM `bs_object` where type_name='" + typename + "'";Connection connection = BaseDao.getConnection();Statement statement = connection.createStatement();ResultSet resultSet = statement.executeQuery(sql);String id = "";while (resultSet.next()) {id = resultSet.getString(1);}BaseDao.closeAll(connection,statement,resultSet);return id; } /*** 基本信息表数据填充** @param id* @param structureUuid* @param structureInfoCode* @param structureinfovalue* @return*/ public int insertStructure(String id, String structureUuid, String structureInfoCode, String structureinfovalue) {String sql = "insert into bs_structure_info (id,structure_uuid,structure_info_code,structure_info_value) values ('" + id + "','" + structureUuid + "','" + structureInfoCode + "','" + structureinfovalue + "')";return BaseDao.execute(sql); }public int insertSbtype(Structure structure) {Calendar cal = Calendar.getInstance();String utcTime=String.valueOf(cal.getTimeInMillis());String sql = "insert into bs_object (id,object_type,type_name,type_code) values ('" + utcTime + "','" + structure.getParam2() + "','" + structure.getParam3() + "','" + structure.getParam4() + "')";Calendar cal1 = Calendar.getInstance();String utcTime1=String.valueOf(cal1.getTimeInMillis());String sql1 = "insert into bs_object_param (id,object_uuid,param_uuid,param_val) values ('" + utcTime1 + "','" + utcTime + "','f4ae866d-937a-11ec-9c0b-00ff8dea45f7','')";BaseDao.execute(sql);return BaseDao.execute(sql1); }/*** 根据名称查询类型** @param name* @return* @throws SQLException*/ public String selectSbtypeByName(String name) throws SQLException {String sql = "select id from bs_object where type_name='" + name + "'";Connection connection = BaseDao.getConnection();Statement statement = connection.createStatement();ResultSet resultSet = statement.executeQuery(sql);String id = "";while (resultSet.next()) {id = resultSet.getString(1);}BaseDao.closeAll(connection,statement,resultSet);return id; }/*** 保存设备实例数据* @param id* @param object_uuid* @param structure_name* @param parent_uuid* @param if_scrap* @param if_logic_delete* @param if_restrain* @param object_type* @param structure_code* @param type_name* @param if_issued* @return*/ public int saveStructure(String id, String object_uuid, String structure_name, String parent_uuid, String if_scrap, String if_logic_delete, String if_restrain, String object_type, String structure_code, String type_name, String if_issued) {String sql = "INSERT INTO `bs_structure` \n" +"\t(`id`, \n" +"\t`object_uuid`, \n" +"\t`structure_name`, \n" +"\t`parent_uuid`, \n" +"\t`if_scrap`, \n" +"\t`object_type`, \n" +"\t`structure_code`, \n" +"\t`type_name`, \n" +"\t`if_issued`\n" +"\t)\n" +"\tVALUES\n" +"\t('"+id+"', \n" +"\t'"+object_uuid+"', \n" +"\t'"+structure_name+"', \n" +"\t'"+parent_uuid+"', \n" +"\t'"+if_scrap+"', \n" +"\t'"+object_type+"', \n" +"\t'"+structure_code+"', \n" +"\t'"+type_name+"', \n" +"\t'"+if_issued+"'\n" +"\t);\n";return BaseDao.execute(sql); }/*** 插入数据** @param id* @param objectId* @param pointName* @param tagDescribe* @param dataType* @param readOrWrite* @param decimal* @param unit* @param inShow* @param ifshow3d* @param ifrange* @return*/ public int insertObjectMonitor(String id, String objectId, String pointName, String tagDescribe, String pointType, String dataType, String readOrWrite, String decimal, String unit, String inShow, String ifshow3d, String ifrange) {String sql = "insert into bs_object_monitor_attr (id,object_id,point_name,tag_describe,point_type,data_type,read_or_write,decimal_digit,unit,if_show,if_show_3d,if_ranging) values ('" + id + "','" + objectId + "','" + pointName + "','" + tagDescribe + "','" + pointType + "','" + dataType + "','" + readOrWrite + "','" + decimal + "','" + unit + "','" + inShow + "','" + ifshow3d + "','" + ifrange + "')";return BaseDao.execute(sql); }/*** 根据对象类型id获取测点信息数据** @param name* @return* @throws SQLException*/ public String selectCedianInfoByobjid(String name,String name1) throws SQLException {String sql = "select id from bs_object_monitor_attr where point_name='" + name + "' and object_id='"+name1+"'";Connection connection = BaseDao.getConnection();Statement statement = connection.createStatement();ResultSet resultSet = statement.executeQuery(sql);String id = "";while (resultSet.next()) {id = resultSet.getString(1);}BaseDao.closeAll(connection,statement,resultSet);return id; }/*** 根据单位名称获取单位的id* @param name* @return* @throws SQLException*/ public String selectUnitIdByName(String name) throws SQLException {String sql="SELECT id FROM `bs_unit` where unit_name='"+name+"'";Connection connection = BaseDao.getConnection();Statement statement = connection.createStatement();ResultSet resultSet = statement.executeQuery(sql);String id = "";while (resultSet.next()) {id = resultSet.getString(1);}BaseDao.closeAll(connection,statement,resultSet);return id; }
第五步、定义Service层
在Service层定义数据的保存方法,便于处理时候调用。
/*** 上一行数据的存储*/public Structure afterData;/*** 数据持久化* @param cachedDataList* @throws SQLException*/public void saveStructure(List<Structure> cachedDataList) throws SQLException, InterruptedException {System.out.println(cachedDataList);StructureDao structureDao =new StructureDao();for(int i=1;i<cachedDataList.size();i++){//等待Structure structure=cachedDataList.get(i);//若出现合并行将其合并行的数据填充进来if("".equals(structure.getParam2())||null==structure.getParam2()){structure.setParam2(afterData.getParam2());}if("".equals(structure.getParam3())||null==structure.getParam3()){structure.setParam3(afterData.getParam3());}if("".equals(structure.getParam4())||null==structure.getParam4()){structure.setParam4(afterData.getParam4());}if("".equals(structure.getParam5())||null==structure.getParam5()){structure.setParam5(afterData.getParam5());}if("".equals(structure.getParam6())||null==structure.getParam6()){structure.setParam6(afterData.getParam6());}if("".equals(structure.getParam7())||null==structure.getParam7()){structure.setParam7(afterData.getParam7());}if("".equals(structure.getParam8())||null==structure.getParam8()){structure.setParam8(afterData.getParam8());}//先判断第一个节点是否存在,存在的话查询它的idString parentID= structureDao.selectParentId(structure.getParam2());Calendar cal = Calendar.getInstance();//将点长名进行拆分String[] changmingchaifens=structure.getParam6().split("/");if(parentID==""&&parentID.equals("")){//获取object对应关系表String objectID= structureDao.selectObjectId("非设备","厂区");//不存在String preUuid =String.valueOf(cal.getTimeInMillis())+(int)(1+Math.random()*100);//System.out.println("preUuid0"+preUuid);int flag= structureDao.saveStructure(preUuid, objectID, structure.getParam2(), "1688107649766", "", "", "", "非设备", changmingchaifens[0], "厂区", "false");if(flag==1){parentID=preUuid;}//提交节点的基本信息表获取数据structureDao.insertStructure(UUID.randomUUID().toString().replace("-", ""),parentID,"type_name","厂区");structureDao.insertStructure(UUID.randomUUID().toString().replace("-", ""),parentID,"f4ae8186-937a-11ec-9c0b-00ff8dea45f7","116.404,39.915,0,0,13");structureDao.insertStructure(UUID.randomUUID().toString().replace("-", ""),parentID,"f4ae866d-937a-11ec-9c0b-00ff8dea45f7","getPtFormHtml?code=Bd_DeviceDetails");}//判断工艺节点是否存在String parentIdOfGy= structureDao.selectParentId1(structure.getParam3(),parentID);if(parentIdOfGy==""&&parentIdOfGy.equals("")){//获取object对应关系表String objectID= structureDao.selectObjectId("非设备","管理节点");TimeUnit.MILLISECONDS.sleep(1);//不存在String preUuid = String.valueOf(cal.getTimeInMillis())+(int)(1+Math.random()*100);int flag= structureDao.saveStructure(preUuid, objectID, structure.getParam3(), parentID,"", "", "", "非设备", changmingchaifens[1], "管理节点", "false");if(flag==1){parentIdOfGy=preUuid;}//提交节点的基本信息表获取数据structureDao.insertStructure(UUID.randomUUID().toString().replace("-", ""),parentIdOfGy,"type_name","管理节点");structureDao.insertStructure(UUID.randomUUID().toString().replace("-", ""),parentIdOfGy,"f4ae8186-937a-11ec-9c0b-00ff8dea45f7","116.404,39.915,0,0,13");structureDao.insertStructure(UUID.randomUUID().toString().replace("-", ""),parentIdOfGy,"f4ae866d-937a-11ec-9c0b-00ff8dea45f7","getPtFormHtml?code=Bd_DeviceDetails");}//判断设备是否存在:根据他的父节点及其设备名称判断是否存在若不存在进行导入String parentIdOfSb= structureDao.selectParentId1(structure.getParam4(),parentIdOfGy);if(parentIdOfSb==""&&parentIdOfSb.equals("")){//获取object对应关系表String objectID= structureDao.selectObjectId1(structure.getParam8());TimeUnit.MILLISECONDS.sleep(1);//不存在String preUuid = String.valueOf(cal.getTimeInMillis())+(int)(1+Math.random()*100);int flag= structureDao.saveStructure(preUuid, objectID, structure.getParam4(), parentIdOfGy,"", "", "","设备",preUuid, structure.getParam8(), "false");if(flag==1){parentIdOfSb=preUuid;}//测点信息录入String preUuidcd = String.valueOf(cal.getTimeInMillis());String[] point_names=structure.getParam5().split("_");String[] tag_describes=structure.getParam7().split("_");String sql1="";if(null==structure.getParam10()&&null==structure.getParam11()){//不保存数据位数//System.out.println(structure.getParam6());String longName="/"+structure.getParam6();sql1= "insert into bs_monitor_attr (id,structure_uuid,point_name,tag_describe,data_type,read_or_write,data_source,tag_long_name) values ('"+preUuidcd+"','"+parentIdOfSb+"','"+structure.getParam12()+"','"+tag_describes[tag_describes.length-1]+"','"+structure.getParam9()+"','只读','2','"+longName+"')";}else{String longName="/"+structure.getParam6();sql1= "insert into bs_monitor_attr (id,structure_uuid,point_name,tag_describe,data_type,read_or_write,data_source,tag_long_name,decimal_digit,unit) values ('"+preUuidcd+"','"+parentIdOfSb+"','"+structure.getParam12()+"','"+tag_describes[tag_describes.length-1]+"','"+structure.getParam9()+"','只读','2','"+longName+"','"+Integer.valueOf(structure.getParam10())+"','"+structureDao.selectUnitIdByName(structure.getParam11())+"')";}int flag1=BaseDao.execute(sql1);//根据名称查询设备类型idString object_id= structureDao.selectObjectId1(structure.getParam8());//根据测点名称判断数据是否存在String cedianId= structureDao.selectCedianInfoByobjid(structure.getParam12(),object_id);if(cedianId==""&&cedianId.equals("")){//不存在//将测点数据同步至设备类型对应的bs_object_monitor_attr里面structureDao.insertObjectMonitor(String.valueOf(cal.getTimeInMillis()),object_id,structure.getParam12(),tag_describes[tag_describes.length-1],"",structure.getParam9(),"只读",structure.getParam10(),structureDao.selectUnitIdByName(structure.getParam11()),"1","1","1");}//提交节点的基本信息表获取数据structureDao.insertStructure(UUID.randomUUID().toString().replace("-", ""),parentIdOfSb,"type_name",structure.getParam8());structureDao.insertStructure(UUID.randomUUID().toString().replace("-", ""),parentIdOfSb,"f4ae8186-937a-11ec-9c0b-00ff8dea45f7","116.404,39.915,0,0,13");structureDao.insertStructure(UUID.randomUUID().toString().replace("-", ""),parentIdOfSb,"f4ae866d-937a-11ec-9c0b-00ff8dea45f7","getPtFormHtml?code=Bd_DeviceDetails");System.out.println("第{"+(i)+"}条数据,存储至数据库完成!");}else{//判断测点信息在不在//测点信息录入,根据设备id与长名判断是否一致,若不一致则录入String[] point_names=structure.getParam5().split("_");//根据测点名称判断数据是否存在String longName1="/"+structure.getParam6();String cedianId0 = structureDao.selectCedianId1(parentIdOfSb,longName1);if(cedianId0==""&&cedianId0.equals("")){//录入String preUuidcd = String.valueOf(cal.getTimeInMillis());String[] tag_describes=structure.getParam7().split("_");String sql1="";if(null==structure.getParam10()&&null==structure.getParam11()){//不保存数据位数String longName="/"+structure.getParam6();sql1= "insert into bs_monitor_attr (id,structure_uuid,point_name,tag_describe,data_type,read_or_write,data_source,tag_long_name) values ('"+preUuidcd+"','"+parentIdOfSb+"','"+structure.getParam12()+"','"+tag_describes[tag_describes.length-1]+"','"+structure.getParam9()+"','只读','2','"+longName+"')";}else{String longName="/"+structure.getParam6();sql1= "insert into bs_monitor_attr (id,structure_uuid,point_name,tag_describe,data_type,read_or_write,data_source,tag_long_name,decimal_digit,unit) values ('"+preUuidcd+"','"+parentIdOfSb+"','"+structure.getParam12()+"','"+tag_describes[tag_describes.length-1]+"','"+structure.getParam9()+"','只读','2','"+longName+"','"+Integer.valueOf(structure.getParam10())+"','"+structureDao.selectUnitIdByName(structure.getParam11())+"')";}int flag1=BaseDao.execute(sql1);//根据名称查询设备类型idString object_id= structureDao.selectObjectId1(structure.getParam8());String cedianId= structureDao.selectCedianInfoByobjid(structure.getParam12(),object_id);if(cedianId==""&&cedianId.equals("")){//不存在//将测点数据同步至设备类型对应的bs_object_monitor_attr里面structureDao.insertObjectMonitor(String.valueOf(cal.getTimeInMillis()),object_id,structure.getParam12(),tag_describes[tag_describes.length-1],"",structure.getParam9(),"只读",structure.getParam10(),structureDao.selectUnitIdByName(structure.getParam11()),"1","1","1");}//提交节点的基本信息表获取数据/* structureDao.insertStructure(UUID.randomUUID().toString().replace("-", ""),parentIdOfSb,"type_name",structure.getParam8());structureDao.insertStructure(UUID.randomUUID().toString().replace("-", ""),parentIdOfSb,"f4ae8186-937a-11ec-9c0b-00ff8dea45f7","116.404,39.915,0,0,13");structureDao.insertStructure(UUID.randomUUID().toString().replace("-", ""),parentIdOfSb,"f4ae866d-937a-11ec-9c0b-00ff8dea45f7","getPtFormHtml?code=Bd_DeviceDetails"); */System.out.println("第{"+(i)+"}条数据,存储至数据库完成!");}else {System.out.println("第{"+(i)+"}条数据已存在,已跳过该条记录!");}}//数据缓存afterData=cachedDataList.get(i);}}
第六步,使用EasyExcel批量读取并保存数据
大家可以打开easyexcel官网选择自己适合的读取方法,下面展示出来的仅是一种,读取数据并保存数据,在保存数据里面替换成自己的service层的保存方法即可。
String fileName = "D:\\实例表.xlsx";// 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭 EasyExcel.read(fileName, Structure.class, new ReadListener<Structure>() {/*** 单次缓存的数据量*/public static final int BATCH_COUNT = 1000;/***临时存储的数据*/private List<Structure> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);@Overridepublic void invoke(Structure data, AnalysisContext context) {cachedDataList.add(data);if (cachedDataList.size() >= BATCH_COUNT) {try {saveData();} catch (SQLException | InterruptedException e) {e.printStackTrace();}finally {// 存储完成清理 listcachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);}}}@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {try {saveData();} catch (SQLException | InterruptedException e) {e.printStackTrace();}}/*** 加上存储数据库*/private void saveData() throws SQLException, InterruptedException {StructureService structureService=new StructureService();structureService.saveStructure(cachedDataList);} }).sheet().doRead();
第七步,去数据库查看是否存储成功并检查数据是否正确。
相关文章:

Java实现excel表数据的批量存储(结合easyexcel插件)
场景:加哥最近在做项目时,苦于系统自身并未提供数据批量导入的功能还不能自行添加上该功能,且自身不想手动一条一条将数据录入系统。随后,自己使用JDBC连接数据库、使用EasyExcel插件读取表格并将数据按照业务逻辑批量插入数据库完…...

Config:客户端连接服务器访问远程
springcloud-config: springcloud-config push pom <?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:schemaLocatio…...

【KMP算法-代码随想录】
目录 1.什么是KMP2.什么是next数组3.什么是前缀表(1)前后缀含义(2)最长公共前后缀(3)前缀表的必要性 4.计算前缀表5.前缀表与next数组(1)使用next数组来匹配 6.构造next数组…...

【手写promise——基本功能、链式调用、promise.all、promise.race】
文章目录 前言一、前置知识二、实现基本功能二、实现链式调用三、实现Promise.all四、实现Promise.race总结 前言 关于动机,无论是在工作还是面试中,都会遇到Promise的相关使用和原理,手写Promise也有助于学习设计模式以及代码设计。 本文主…...

计算机网络-笔记-第二章-物理层
目录 二、第二章——物理层 1、物理层的基本概念 2、物理层下面的传输媒体 (1)光纤、同轴电缆、双绞线、电力线【导引型】 (2)无线电波、微波、红外线、可见光【非导引型】 (3)无线电【频谱的使用】 …...

前端开发中的单伪标签清除和双伪标签清除
引言 在前端开发中,我们经常会遇到一些样式上的问题,其中之一就是伪元素造成的布局问题。为了解决这个问题,我们可以使用伪标签清除技术。本篇博客将介绍单伪标签清除和双伪标签清除的概念、用法和示例代码,并详细解释它们的原理…...

云计算中的数据安全与隐私保护策略
文章目录 1. 云计算中的数据安全挑战1.1 数据泄露和数据风险1.2 多租户环境下的隔离问题 2. 隐私保护策略2.1 数据加密2.2 访问控制和身份验证 3. 应对方法与技术3.1 零知识证明(Zero-Knowledge Proofs)3.2 同态加密(Homomorphic Encryption&…...

MacOS软件安装包分享(附安装教程)
目录 一、软件简介 二、软件下载 一、软件简介 MacOS是一种由苹果公司开发的操作系统,专门用于苹果公司的计算机硬件。它被广泛用于创意和专业应用程序,如图像设计、音频和视频编辑等。以下是关于MacOS的详细介绍。 1、MacOS的历史和演变 MacOS最初于…...

【linux进程概念】
目录: 冯诺依曼体系结构操作系统进程 基本概念描述进程-PCBtask_struct-PCB的一种task_ struct内容分类组织进程查看进程 fork()函数 冯诺依曼体系结构 我们常见的计算机,如笔记本。我们不常见的计算机,如服务器,大部分都遵守冯诺…...

直击成都国际车展:远航汽车多款车型登陆车展,打造完美驾乘体验
随着市场渗透率日益高涨,新能源汽车成为今年成都国际车展的关注焦点。在本届车展上,新能源品牌占比再创新高,覆盖两个展馆,印证了当下新能源汽车市场的火爆。作为大运集团重磅打造的高端品牌,远航汽车深度洞察高端智能…...

android nv21 转 yuv420sp
上面两个函数的目标都是将NV21格式的数据转换为YUV420P格式,但是它们在处理U和V分量的方式上有所不同。 在第一个函数NV21toYUV420P_1中,U和V分量的处理方式是这样的:对于U分量,它从NV21数据的Y分量之后的每个奇数位置取数据&…...

使用Nacos与Spring Boot实现配置管理
🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…...

初识【类和对象】
目录 1.面向过程和面向对象初步认识 2.类的引入 3.类的定义 4.类的访问限定符及封装 5.类的作用域 6.类的实例化 7.类的对象大小的计算 8.类成员函数的this指针 1.面向过程和面向对象初步认识 C语言是面向过程的,关注的是过程,分析出求解问题的…...

软考高级系统架构设计师系列论文八十六:论企业应用集成
软考高级系统架构设计师系列论文八十六:论企业应用集成 一、企业应用集成相关知识点二、摘要三、正文四、总结一、企业应用集成相关知识点 软考高级系统架构设计师系列之:企业集成平台技术的应用和架构设计二、摘要 2022年10月,我参加了***车站综合信息平台项目的开发,承…...

HarmonyOS ArkUI 属性动画入门详解
HarmonyOS ArkUI 属性动画入门详解 前言属性动画是什么?我们借助官方的话来说,我们自己简单归纳下 参数解释举个例子旋转动画 位移动画组合动画总结 前言 鸿蒙OS最近吹的很凶,赶紧卷一下。学习过程中发现很多人吐槽官方属性动画这一章比较敷…...

基于XGBoots预测A股大盘《上证指数》(代码+数据+一键可运行)
对AI炒股感兴趣的小伙伴可加WX:caihaihua057200(备注:学校/公司名字方向) 另外我还有些AI的应用可以一起研究(我一直开源代码) 1、引言 在这期内容中,我们回到AI预测股票,转而探索…...

5G NR:PRACH频域资源
PRACH在频域位置由IE RACH-ConfigGeneric中参数msg1-FrequencyStart和msg1-FDM所指示,其中, msg1-FrequencyStart确定PRACH occasion 0的RB其实位置相对于上行公共BWP的频域其实位置(即BWP 0)的偏移,即确定PRACH的频域起始位置msg1-FDM的取值…...

设计模式——组合模式
什么是组合模式 组合模式(Composite Pattern):组合多个对象形成树形结构以表示具有“整体—部分”关系的层次结构。组合模式对单个对象(即叶子对象)和组合对象(即容器对象)的使用具有一致性,组合模式又可以…...

get属性是什么?有什么用?在什么场景用?get会被Json序列化?
在JavaScript中,对象的属性不仅可以是数据属性(即常规的键值对),还可以是访问器属性(accessor properties)。访问器属性不包含实际的数据值,而是定义了如何获取(get)和设…...

这可能是你看过最详细的 [八大排序算法]
排序算法 前置知识 [排序稳定性]一、直接插入排序二、希尔排序三、直接选择排序四、堆排序五、冒泡排序六、快速排序七、归并排序八、计数排序(非比较排序)排序复杂度和稳定性总结 前置知识 [排序稳定性] 假定在待排序的记录序列中,存在多个…...

docker的安装
CentOS7 安装 Docker 安装需要的软件包, yum-util 提供yum-config-manager功能,另两个是devicemapper驱动依赖 yum install -y yum-utils device-mapper-persistent-data lvm2 添加下载源 yum-config-manager --add-repo http://mirrors.aliyun.com/…...

【业务功能篇75】微服务项目环境搭建docker-mysql-redisSpringCloudAlibaba
项目环境准备 1.虚拟机环境 我们可以通过VMWare来安装,但是通过VMWare安装大家经常会碰到网络ip连接问题,为了减少额外的环境因素影响,Docker内容的讲解我们会通过VirtualBox结合Vagrant来安装虚拟机。 VirtualBox官网:https:/…...

学习笔记|认识数码管|控制原理|数码管实现0-9的显示|段码跟位码|STC32G单片机视频开发教程(冲哥)|第九集:数码管静态显示
文章目录 1.认识数码管2.控制原理十进制转换为任意进制其它进制转十进制 3.数码管实现0-9的显示1.用数组定义0-9的内码段码跟位码的区别2.尝试用延时实现0-9的循环显示3.用按键控制数字的加或者减。 总结课后练习: 1.认识数码管 数码管按段数可分为七段数码管和八段…...

CentOS 7/8 firewall 转发端口
#开启系统路由模式功能 echo net.ipv4.ip_forward1>>/etc/sysctl.conf sysctl -p #开启firewalld systemctl start firewalld 打开防火墙伪装IP # 检查是否允许伪装IP,返回no表示没开启,反之开启伪装IP firewall-cmd --query-masquerade #设置…...

mysql自动备份脚本
备份脚本 #!/bin/bash #author cheng #mysql数据自动备份 mysql_user“root” mysql_password“passwprd” mysql_host“localhost” mysql_port“3306” mysql_charset“utf8mb4” #备份文件存放地址(根据实际情况填写) backup_location/usr/cheng/msg_manager/sql #是否删…...

VUE笔记(九)vuex
一、vuex的简介 1、回顾组件之间的通讯 父组件向子组件通讯:通过props实现 子组件向父组件通讯:通过自定义事件($emit)方式来实现 兄弟组件之间的通讯:事件总线($eventBus)、订阅与发布方式来实现 跨级组件的通讯…...

Webpack高频面试题
Webpack高频面试题 1 谈谈你对webpack的看法 现在的前端网页功能丰富,特别是SPA(single page web application 单页应用)技术流行后,JavaScript的复杂度增加和需要一大堆依赖包,还需要解决Scss,Less……新…...

数字基带传输系统
文章目录 前言一、数字基带系统基本组成二、基本码型1、数字基带信号2、6 种基本码型 三、数字基带信号的频谱特性四、数字基带信号选码1、原则2、常用的传输码型①、AMI 码(传号交替反转码)②、 H D B 3 HDB_3 HDB3 码(3 阶高密度双极性码…...

FPGA使用MIG调用SODIMM内存条接口教程,提供vivado工程源码和技术支持
目录 1、前言免责声明 2、SODIMM内存条简介3、设计思路框架视频输入视频缓存MIG配置调用SODIMM内存条VGA时序视频输出 4、vivado工程详解5、上板调试验证6、福利:工程代码的获取 1、前言 FPGA应用中,数据缓存是一大重点,不管是图像处理还是A…...

深度学习数据预处理
参考文章:深度学习中的数据预处理方法总结 在深度学习中,数据预处理(preprocessing)的重要性体现在以下几个方面: 1、数据质量: 原始数据通常包含错误、缺失值、异常值和噪声。预处理能够检测和处理这些问…...