当前位置: 首页 > 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;存在多个…...

像素皇城灵蛇贺岁:5分钟部署你的赛博春联生成器(保姆级教程)

像素皇城灵蛇贺岁&#xff1a;5分钟部署你的赛博春联生成器&#xff08;保姆级教程&#xff09; 1. 前言&#xff1a;当传统春节遇上赛博美学 春节贴春联是延续千年的传统习俗&#xff0c;但你是否想过用AI技术为这个传统注入新的活力&#xff1f;今天我们要介绍的"像素…...

别再只改默认密码了!Nacos 1.x/2.x 生产环境安全加固保姆级清单(附漏洞自查脚本)

Nacos生产环境安全加固全指南&#xff1a;从基础配置到漏洞防御 在微服务架构盛行的今天&#xff0c;Nacos作为服务发现和配置管理的核心组件&#xff0c;其安全性直接影响整个系统的稳定性。许多团队在部署Nacos时往往只满足于修改默认密码&#xff0c;却忽视了完整的安全防护…...

DriverStore Explorer:突破Windows驱动管理瓶颈,释放系统空间提升80%存储效率

DriverStore Explorer&#xff1a;突破Windows驱动管理瓶颈&#xff0c;释放系统空间提升80%存储效率 【免费下载链接】DriverStoreExplorer Driver Store Explorer [RAPR] 项目地址: https://gitcode.com/gh_mirrors/dr/DriverStoreExplorer 诊断存储异常&#xff1a;设…...

ESP32 LVGL8.1 —— 消息框进阶:自定义按钮与事件处理实战

1. ESP32与LVGL8.1消息框基础认知 第一次接触ESP32和LVGL8.1的消息框功能时&#xff0c;我完全被它的灵活性震惊了。想象一下&#xff0c;你正在开发一个智能家居控制面板&#xff0c;当用户操作不当或者系统需要确认时&#xff0c;弹出一个美观的对话框是多么自然的事情。这就…...

DanKoe 视频笔记:深度工作:改变生活的常规 [特殊字符]

在本教程中&#xff0c;我们将学习一套能极大提升专注力与生产力的深度工作常规。这套方法的核心在于理解并管理你的注意力&#xff0c;将其视为最宝贵的资源&#xff0c;并像管理计算机内存一样去优化它。我们将从核心概念开始&#xff0c;逐步拆解具体步骤&#xff0c;帮助你…...

MongoDB高级面试:进阶面试题50题及答案详解

更多内容请见: 《深入掌握MongoDB数据库》 - 专栏介绍和目录 文章目录 一、高级查询优化与执行计划 (8题) 二、高级索引策略 (8题) 三、高级分片策略与优化 (8题) 四、性能调优与瓶颈分析 (7题) 五、高级复制集配置与故障处理 (6题) 六、高级事务与一致性模型 (5题) 七、安全高…...

基于大数据 Spark+Hadoop+Hive的中国不同城市奶茶品牌的影响力分析

前言现如今在中国市场中&#xff0c;奶茶行业以其别具一格的魅力和庞大的年轻消费群体&#xff0c;具备一些研究价值。伴随着消费者需求的日益多样化和市场竞争的逐步激烈&#xff0c;奶茶品牌在中国不同城市的影响力呈现出显著的差异。本研究基于这一背景&#xff0c;以中国不…...

电路设计与漫画艺术的跨界融合

1. 当电路遇见漫画&#xff1a;工程师的艺术表达在大多数人眼中&#xff0c;电路设计是冰冷的数据和复杂的公式&#xff0c;而漫画则是天马行空的创意表达。但作为一名从业十年的硬件工程师&#xff0c;我发现这两者其实有着惊人的相似之处——它们都需要严谨的结构设计&#x…...

郭老师-悟性高的人,为何不合群?

悟性高的人&#xff0c;为何不合群&#xff1f; ——他们在独处中&#xff0c;与道同行“你以为他孤独&#xff0c; 其实—— 他正与万物对话。”&#x1f33f; 不合群&#xff0c;不是缺陷&#xff0c; 而是—— 为悟性留出呼吸的空间。&#x1f9d8; 一、独处 ≠ 孤独&#x…...

如何选择ComfyUI-FramePackWrapper的模型加载方案?从技术选型到场景适配全解析

如何选择ComfyUI-FramePackWrapper的模型加载方案&#xff1f;从技术选型到场景适配全解析 【免费下载链接】ComfyUI-FramePackWrapper 项目地址: https://gitcode.com/gh_mirrors/co/ComfyUI-FramePackWrapper 在AI视频生成工作流中&#xff0c;模型加载是影响效率与稳…...