如何在Pentaho Spoon中添加条件实现CSV数据增量插入
实现CSV插入数据库时过滤已存在记录的两种方案
一、数据库层面过滤(高效优先,适合大数据量)
直接通过SQL语句实现过滤,不用在Java里逐条校验,性能更优,还能避免并发场景下的重复插入问题。
1. 用INSERT ... SELECT ... WHERE NOT EXISTS
前提是你的表有唯一标识字段(比如user_id),可以把CSV数据拼成临时数据集,再和目标表对比:
INSERT INTO target_table (user_id, name, email, age) SELECT csv.user_id, csv.name, csv.email, csv.age FROM ( -- 这里替换成CSV里的实际数据,多条用UNION ALL拼接 SELECT '1001' AS user_id, '张三' AS name, 'zhangsan@xxx.com' AS email, 25 AS age UNION ALL SELECT '1002' AS user_id, '李四' AS name, 'lisi@xxx.com' AS email, 28 AS age ) AS csv WHERE NOT EXISTS ( SELECT 1 FROM target_table t WHERE t.user_id = csv.user_id );
Java里可以批量构造这个SQL的数据集部分,或者先把CSV导入数据库临时表再执行上述语句。
2. 用INSERT ... ON DUPLICATE KEY UPDATE(需唯一约束)
先给表的唯一字段(比如user_id)加主键或唯一索引,然后插入时遇到重复键就忽略:
INSERT INTO target_table (user_id, name, email, age) VALUES ('1001', '张三', 'zhangsan@xxx.com', 25), ('1002', '李四', 'lisi@xxx.com', 28) ON DUPLICATE KEY UPDATE user_id = user_id; -- 重复时不做任何修改,相当于跳过
MySQL也支持更简洁的INSERT IGNORE,但ON DUPLICATE KEY可以灵活选择重复时是否更新:
INSERT IGNORE INTO target_table (user_id, name, email, age) VALUES ('1001', '张三', 'zhangsan@xxx.com', 25), ('1002', '李四', 'lisi@xxx.com', 28);
二、Java代码层面过滤(适合小数据量)
数据量不大时,可以先把数据库里已有的唯一标识拉到内存,再过滤CSV数据:
代码示例
// 1. 拉取数据库中已存在的user_id集合 Set<String> existingIds = new HashSet<>(); try (Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT user_id FROM target_table")) { while (rs.next()) { existingIds.add(rs.getString("user_id")); } } // 2. 遍历CSV数据,过滤掉已存在的记录 List<User> toInsert = new ArrayList<>(); for (User csvUser : csvDataList) { if (!existingIds.contains(csvUser.getUserId())) { toInsert.add(csvUser); } } // 3. 批量插入过滤后的列表 String insertSql = "INSERT INTO target_table (user_id, name, email, age) VALUES (?, ?, ?, ?)"; try (PreparedStatement pstmt = conn.prepareStatement(insertSql)) { for (User user : toInsert) { pstmt.setString(1, user.getUserId()); pstmt.setString(2, user.getName()); pstmt.setString(3, user.getEmail()); pstmt.setInt(4, user.getAge()); pstmt.addBatch(); } pstmt.executeBatch(); }
注意:这种方法在数据量大时会占用较多内存,而且如果查询完到插入的间隙有其他程序插入数据,可能出现重复,所以高并发或大数据量场景优先用数据库方案。
内容的提问来源于stack exchange,提问作者Ansh
相关产品推荐
相关产品推荐

