mybatis 批量插入数据
目标
最近有一个需求,ip 黑名单统计,文件内容大概是以下如此
100.100.100.121 |爬虫:fei:20190806|代理:b_feilong_e:20191001
192.225.115.175 |垃圾邮件:abc:20191014
文本 blackip.txt
有有八千多万行
,文件大小有6.5G
的内容,需要根据 爬虫
和代理
分不同的文件存储ip
处理思路
正常的处理思路:将文件加载到内存,根据行中包含的关键字 爬虫
和代理
,就可以分到不同的文件,但是因为这个文件太大了,没办法一次性将文件加载到内存中,所有这种方式不可行,所以先将大文件分割多个小文件
linux 分割文件
根据文件大小分割文件
split --bytes 500M --numeric-suffixes --suffix-length=3 blackip.txt blackip_split_size_
将文件 blackip.txt 分割成一个文件大小是500M 的多个小文件,文件名 blackip_split_size_000, blackip_split_size_001。。。。等多个文件
根据文件行分割文件
split --lines 4000000 --numeric-suffixes --suffix-length=3 blackip.txt blackip_split_line_
将文件 blackip.txt 分割成一个文件行是4000000 的多个小文件,文件名 blackip_split_line_000, blackip_split_line_001。。。。等多个文件
如果按照文件大小
分割文件的话,可能将同一行的数据分在不同的文件,所有使用按行分割
,分成多个文件
以下处理文件 blackip_split_line_000, blackip_split_line_001
然后多线程处理单个文件,获取到多个IP 文件,然后将结果合并 ,可用命令
cat a.txt b.txt >> c.txt
将a.txt 和 b.txt 文件合并到 c.txt 文件中
最后合并的结果文件 allip_proxy_brush_uniq.txt
大小,213M
数据有一千五百万
条数据
这个文件大小的数据,是可以一次加载到内存的
加载到数据库中
首先得设计表结构 proxy_brush
CREATE TABLE `proxy_brush` (
`id` int(11) NOT NULL,
`ip` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
生成sql文件 proxy_brush_tmp1.sql
insert into proxy_brush(id,ip) values (1,'100.100.100.121'),(2,'100.100.100.122'),.......
以上文件有400M左右
登录cmd ,mysql -uroot -p
mysql 的命令有 ,use databases
load data local infile ‘f:\proxy_brush_tmp1.sql’ into table proxy_brush
由于以上文件太大,通过客户端 navicat ,不能一次加载完成,容易导致超时,不可行
使用 source F:\proxy_brush_tmp1.sql
命令也容易超时
所以只能换一种方式导入,如果生成
insert into proxy_brush(id,ip) values (1,'100.100.100.121')
insert into proxy_brush(id,ip) values (2,'100.100.100.121')
导入速度很慢的
mybatis 使用批处理实现
mapper 实现
<insert id="insertBatch" parameterType="java.util.List">
insert into proxy_brush(id,ip) values
<foreach collection="lists" item="item" index="i" separator=",">
(#{item.id},#{item.ip})
</foreach>
</insert>
dao接口实现
/**
* 批量插入数据
* @param lists
*/
public void insertBatch(@Param("lists") List<ProxyBrush> lists);
ProxyBrush 设计很简单
public class ProxyBrush extends Model<ProxyBrush> {
private static final long serialVersionUID = -7876888313791106541L;
/**
* 自增ID
*/
private int id;
private String ip;
@Override
protected Serializable pkVal() {
return null;
}
}
导入速度很快的,大约也就几分钟就可以导入一千五百多万条数据