当前位置: 首页 > news >正文

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插件)

场景&#xff1a;加哥最近在做项目时&#xff0c;苦于系统自身并未提供数据批量导入的功能还不能自行添加上该功能&#xff0c;且自身不想手动一条一条将数据录入系统。随后&#xff0c;自己使用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.什么是前缀表&#xff08;1&#xff09;前后缀含义&#xff08;2&#xff09;最长公共前后缀&#xff08;3&#xff09;前缀表的必要性 4.计算前缀表5.前缀表与next数组&#xff08;1&#xff09;使用next数组来匹配 6.构造next数组&#xf…...

【手写promise——基本功能、链式调用、promise.all、promise.race】

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

计算机网络-笔记-第二章-物理层

目录 二、第二章——物理层 1、物理层的基本概念 2、物理层下面的传输媒体 &#xff08;1&#xff09;光纤、同轴电缆、双绞线、电力线【导引型】 &#xff08;2&#xff09;无线电波、微波、红外线、可见光【非导引型】 &#xff08;3&#xff09;无线电【频谱的使用】 …...

前端开发中的单伪标签清除和双伪标签清除

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

云计算中的数据安全与隐私保护策略

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

MacOS软件安装包分享(附安装教程)

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

【linux进程概念】

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

直击成都国际车展:远航汽车多款车型登陆车展,打造完美驾乘体验

随着市场渗透率日益高涨&#xff0c;新能源汽车成为今年成都国际车展的关注焦点。在本届车展上&#xff0c;新能源品牌占比再创新高&#xff0c;覆盖两个展馆&#xff0c;印证了当下新能源汽车市场的火爆。作为大运集团重磅打造的高端品牌&#xff0c;远航汽车深度洞察高端智能…...

android nv21 转 yuv420sp

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

使用Nacos与Spring Boot实现配置管理

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…...

初识【类和对象】

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

软考高级系统架构设计师系列论文八十六:论企业应用集成

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

HarmonyOS ArkUI 属性动画入门详解

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

基于XGBoots预测A股大盘《上证指数》(代码+数据+一键可运行)

对AI炒股感兴趣的小伙伴可加WX&#xff1a;caihaihua057200&#xff08;备注&#xff1a;学校/公司名字方向&#xff09; 另外我还有些AI的应用可以一起研究&#xff08;我一直开源代码&#xff09; 1、引言 在这期内容中&#xff0c;我们回到AI预测股票&#xff0c;转而探索…...

5G NR:PRACH频域资源

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

设计模式——组合模式

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

get属性是什么?有什么用?在什么场景用?get会被Json序列化?

在JavaScript中&#xff0c;对象的属性不仅可以是数据属性&#xff08;即常规的键值对&#xff09;&#xff0c;还可以是访问器属性&#xff08;accessor properties&#xff09;。访问器属性不包含实际的数据值&#xff0c;而是定义了如何获取&#xff08;get&#xff09;和设…...

这可能是你看过最详细的 [八大排序算法]

排序算法 前置知识 [排序稳定性]一、直接插入排序二、希尔排序三、直接选择排序四、堆排序五、冒泡排序六、快速排序七、归并排序八、计数排序&#xff08;非比较排序&#xff09;排序复杂度和稳定性总结 前置知识 [排序稳定性] 假定在待排序的记录序列中&#xff0c;存在多个…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

3.3.1_1 检错编码(奇偶校验码)

从这节课开始&#xff0c;我们会探讨数据链路层的差错控制功能&#xff0c;差错控制功能的主要目标是要发现并且解决一个帧内部的位错误&#xff0c;我们需要使用特殊的编码技术去发现帧内部的位错误&#xff0c;当我们发现位错误之后&#xff0c;通常来说有两种解决方案。第一…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

微信小程序 - 手机震动

一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注&#xff1a;文档 https://developers.weixin.qq…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心&#xff0c;JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例&#xff1a; 1. onclick - 点击事件 当元素被单击时触发&#xff08;左键点击&#xff09; button.onclick function() {alert("按钮被点击了&#xff01;&…...

Pinocchio 库详解及其在足式机器人上的应用

Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库&#xff0c;专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性&#xff0c;并提供了一个通用的框架&…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...