10.java将大量数据(千万行,1G 以上)插入到数据库-bach+simple+文档拆分-亲测可用!!

本篇效率最高!!!-在插入千万以上1G以上数据到数据库时。推荐细看。
详细思路请看springboot读取本地大文档1G目录导航-10

在这里插入图片描述

三层
1.controller层

 @ApiOperation("insert接口-GG-Bach&SimbleSplitTxT添加数据")
    @RequestMapping(value = "insertGGBachSimbleSplitTxT", method = RequestMethod.POST)
    @ResponseBody
    public void insertGGBachSimbleSplitTxTService(){
        tsi.insertGGBachSimbleSplitTxTService();
    }

2.service层
接口

void insertGGBachSimbleSplitTxTService();

实现类

 @Override
    public void insertGGBachSimbleSplitTxTService() {
        /*1.设置batch手动提交*/
        SqlSession session = sqlSessionTemplate.getSqlSessionFactory().openSession(
                ExecutorType.BATCH, false);
        /*2.通过session 获取mapper对象*/
        tm = session.getMapper(TableMapper.class);
        try {
            /*3.1文件获取地址*/
            File file = new File("D:/data/allCountries.txt");
            /*3.2文件夹保存地址*/
            File saveDir = new File("D:/data/splitDir");
            /*4.1文件行数 获取方法会在工具类讲*/
            long totalLens = 12052592;
            /*4.2设置每个子文件最多行数*/
            long eachLens = 1000000;
            //1.先获取所有拆分好的子文件
            ArrayList<File> alFile = ReadTxt.splitTxt(file,saveDir,totalLens,eachLens);
            //2.然后遍历 分成两份 每份10万条数据调用之前的方法插入到数据库
            for(int i = 0;i<alFile.size();i++){
                //al存入的是一个子txt
                List<Geoname> al = ReadTxt.txt2String(alFile.get(i));
                int fen = al.size()/10000;
                //将10万条分成100份 每份1000条(提交) 分批提交到数据库
                for (int j = 1; j <= fen+1; j++) {
                    long time1 = System.currentTimeMillis();
                    //将1000条插入到数据库  k是al文件下标  小于遍历最大数1000行  小于al集合size
                    for(int k = (j-1)*10000;k<j*10000&&k<al.size();k++){
                        tm.insertTableSimble(al.get(k));
                    }
                    //手动每10000个一提交,提交后无法回滚
                    session.commit();
                    //清理缓存,防止溢出
                    session.clearCache();
                    long time2 = System.currentTimeMillis();
                    System.out.println("存入数据库第"+j+"次耗时:"+(time2-time1));
                }
            }

        } catch (Exception e) {
            //没有提交的数据可以回滚
            session.rollback();
        } finally {
            session.close();
        }
    }

工具类

/*4读文档 拆分文档成100份  返回路径file组成的集合
     *根据需求,直接调用静态方法start来执行操作
     *参数:
     * rows 为多少行一个文件 int 类型
     * sourceFilePath 为源文件路径 String 类型
     * targetDirectoryPath 为文件分割后存放的目标目录 String 类型
     * ---分割后的文件名为索引号(从0开始)加'_'加源文件名,例如源文件名为test.txt,则分割后文件名为0_test.txt,以此类推

     将文件按行分割
     */
    /*将文件拆分  返回文件路径组成的集合*/
    public static ArrayList<File> splitTxt(File sourceFile,File saveDir,long totalLens,long lens){
        //0.创建路径组成的集合
        ArrayList<File> alf = new ArrayList<>();
        //1.获取文件路径,需要保存的文件路径,文件总行数,被拆分的子文件行数
        try {
            //2.获取文件
            BufferedReader br = new BufferedReader(new FileReader(sourceFile));
            //3.循环读取文件i---i+10000行数据拼接\r\n存入到StringBuilder中
            long  nowLen = 1;
            //第一个循环 创建多少个文件
            for(int i = 0;i<=totalLens/lens;i++){
                Long time1 = System.currentTimeMillis();
                //第二个循环获取行,存入StringBuilder
                StringBuilder sb = new StringBuilder();
                for(int j = 0;j<lens;j++){
                    nowLen = (j+1)+i*lens;
                    sb = sb.append(br.readLine()+"\r\n");
                    if(nowLen==totalLens){
                       break;
                    }
                }
                //创建文件并存入数据
                File wfile = new File(saveDir.getAbsolutePath()+"/"+i+"_"+sourceFile.getName());
                BufferedWriter bw = new BufferedWriter(new FileWriter(wfile));
                bw.write(sb.toString());
                bw.flush();
                bw.close();
                alf.add(wfile);
                Long time2 = System.currentTimeMillis();
                System.out.println("拆分出第"+i+"个文件所需时间为:"+(time2-time1));
            }
           br.close();
            //4.将stringbuilder写到文档中
        }catch (Exception e){
            System.out.println("文件在拆分的时候报错!");
        }
        return alf;
    }
 // 3.3获取文件内容的总行数。
    static long getTotalLines(File file) {
        long lines = 0;
        try{
            FileReader in = new FileReader(file);
            LineNumberReader reader = new LineNumberReader(in);
            String s = reader.readLine();
            while (s != null) {
                lines++;
                s = reader.readLine();
            }
            reader.close();
            in.close();
        }catch (Exception e){
            System.out.println("读取文件总行数出错!");
        }
        return lines;
    }

3.mapper层
接口

void insertTableSimble(Geoname g);


实现类

 <insert id="insertTableSimble" parameterType="com.example.springboot6.bean.Geoname" >
        insert into allCountries (geonameid,name,asciiname,alternatenames,latitude,longitude,feature_class,feature_code,country_code,cc2,admin1_code,admin2_code,admin3_code,admin4_code,population,elevation,dem,timezone,modification_date)
        values (#{geonameid,jdbcType=INTEGER},#{name,jdbcType=VARCHAR},#{asciiname,jdbcType=VARCHAR},#{alternatenames,jdbcType=VARCHAR},#{latitude,jdbcType=DOUBLE},#{longitude,jdbcType=DOUBLE},#{featureClass,jdbcType=CHAR},#{featureCode,jdbcType=VARCHAR},#{countryCode,jdbcType=VARCHAR},#{cc2,jdbcType=VARCHAR},#{admin1Code,jdbcType=VARCHAR},#{admin2Code,jdbcType=VARCHAR},#{admin3Code,jdbcType=VARCHAR},#{admin4Code,jdbcType=VARCHAR},#{population,jdbcType=BIGINT},#{elevation,jdbcType=INTEGER},#{dem,jdbcType=INTEGER},#{timezone,jdbcType=VARCHAR},#{modificationDate,jdbcType=DATE})
    </insert>

完毕!

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值