Java注解实现异步导入与导出(一)

文章介绍了如何设计一个管理系统来处理批量导入导出数据的问题,通过将同步接口改为异步,利用NFS存储临时文件,以及使用注解和AOP实现通用的导入导出流程。此外,文章还提出了一种方式,让业务只需关注数据校验和持久化,而复杂的导入导出逻辑由框架统一处理,提高了代码复用性和效率。
摘要由CSDN通过智能技术生成

1.背景:

之前写过批量导入百万级数据到mysql的代码,但是局限性比较大,遇到需要复杂校验(重复性校验,有效性校验)的场景下,这种很容易就超时,同时一个系统内,肯定会有多个地方需要用到导入导出,每个地方都写一堆类似的代码,同时还得不断优化性能(数据越来越多,需要越来越复杂),这时候一个管理系统所有导入/导出记录的页面就很实用了,可以让各个模块业务专注在业务上,不需要关心上传和下载。

2.设计:

2.1 常规的导入同步流程如下, 这就引发了一个问题:如果 Excel 的行非常多,或者解析非常复杂,那么解析+校验的过程就非常耗时。如果接口是一个同步的接口,则非常容易出现接口超时,进而返回的校验错误信息也无法展示给前端,这就需要从功能上解决这个问题。

2.2 把同步改为异步,同时引入NFS用来临时存储文件

2.3 导入导出日志记录表设计如下:

CREATE TABLE `t_import_export_records` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `module_name` varchar(32) NOT NULL COMMENT '模块名称',
  `file_name` varchar(32) NOT NULL COMMENT '文件名称',
  `type` tinyint(2) NOT NULL DEFAULT '1' COMMENT '导入:1;导出:2;',
  `state` tinyint(2) NOT NULL DEFAULT '0' COMMENT '进行中:0;成功:1;失败:2;已过期:3',
  `nfs_path` varchar(200) DEFAULT NULL COMMENT '文件路径',
 `error_reason` text COMMENT '异常日志文件路径',
  `expire_time` varchar(32) NOT NULL COMMENT '过期时间,小时',
  `start_time` datetime DEFAULT NULL COMMENT '开始时间',
  `end_time` datetime DEFAULT NULL COMMENT '开始时间',
  `creator` varchar(32) DEFAULT NULL COMMENT '创建人员',
  `create_tm` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `modifier` varchar(32) DEFAULT NULL COMMENT '修改人员',
  `modify_tm` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`),
  KEY `creator` (`creator`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='导入导出日志记录表';

2.4 代码实现

从上面的流程中可以看出,每个业务自己只需要实现自己的 数据校验,持久化到db

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java异步导入数据到MySQL可以使用多线程或者异步框架来实现。其中,我推荐使用异步框架,比如Netty和Vert.x。 以Vert.x为例,可以使用以下步骤来实现异步导入数据到MySQL: 1. 在pom.xml中添加vertx-jdbc-client和mysql-connector-java依赖。 ```xml <dependencies> <dependency> <groupId>io.vertx</groupId> <artifactId>vertx-jdbc-client</artifactId> <version>3.9.0</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.23</version> </dependency> </dependencies> ``` 2. 创建Vert.x实例,并且配置JDBC连接池。示例代码如下: ```java import io.vertx.core.Vertx; import io.vertx.core.json.JsonObject; import io.vertx.ext.jdbc.JDBCClient; public class AsyncMySQLImport { public static void main(String[] args) { // 创建Vert.x实例 Vertx vertx = Vertx.vertx(); // 配置JDBC连接池 JsonObject config = new JsonObject() .put("url", "jdbc:mysql://localhost:3306/test") .put("driver_class", "com.mysql.cj.jdbc.Driver") .put("user", "root") .put("password", "password") .put("max_pool_size", 30); JDBCClient client = JDBCClient.createShared(vertx, config); } } ``` 3. 在异步方法中执行数据导入操作。示例代码如下: ```java import io.vertx.core.Vertx; import io.vertx.core.json.JsonObject; import io.vertx.ext.jdbc.JDBCClient; public class AsyncMySQLImport { public static void main(String[] args) { // 创建Vert.x实例 Vertx vertx = Vertx.vertx(); // 配置JDBC连接池 JsonObject config = new JsonObject() .put("url", "jdbc:mysql://localhost:3306/test") .put("driver_class", "com.mysql.cj.jdbc.Driver") .put("user", "root") .put("password", "password") .put("max_pool_size", 30); JDBCClient client = JDBCClient.createShared(vertx, config); // 异步方法执行数据导入操作 client.getConnection(conn -> { if (conn.succeeded()) { System.out.println("Connected to database"); conn.result().query("INSERT INTO students(name, age) VALUES('Tom', 20)", res -> { if (res.succeeded()) { System.out.println("Data imported successfully"); } else { System.out.println("Data import failed"); } }); } else { System.out.println("Failed to connect to database"); } }); } } ``` 在上述代码中,我们使用了`client.getConnection()`方法来获取数据库连接,并且在回调函数中执行了数据导入操作。该方法是一个异步方法,它会在获取到数据库连接之后回调传入的Lambda表达式。在Lambda表达式中,我们执行了`conn.result().query()`方法来执行数据导入操作,该方法同样是一个异步方法,它会在数据导入完成后回调传入的Lambda表达式。 总的来说,使用异步框架来实现Java中的异步操作可以使代码更加简洁和可读,并且可以提高应用程序的性能和吞吐量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值