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)和设…...

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

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...

高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...

算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

uniapp手机号一键登录保姆级教程(包含前端和后端)
目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号(第三种)后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台
淘宝扭蛋机小程序系统的开发,旨在打造一个互动性强的购物平台,让用户在购物的同时,能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机,实现旋转、抽拉等动作,增…...