JDBC写数据到文件中再Copy到postgresql中

经过测试,大概写入12万条数据2秒+左右。

代码如下:

package com.nsfocus.bsaips.main;
import com.alibaba.fastjson.JSONObject;
import com.nsfocus.bsaips.util.RemoteDBUtil;
import org.postgresql.copy.CopyManager;
import org.postgresql.core.BaseConnection;
import java.sql.*;
import java.util.ArrayList;
import java.io.*;
import java.util.List;
import java.util.UUID;

public class Test {
    public String writeFile(List<JSONObject> list){
        FileWriter out = null;
        String filePath = "/tmp/"+UUID.randomUUID();

        try{
            out = new FileWriter(new File(filePath));
            for(int i=0;i<list.size();i++){
                Object[] objs = list.get(i).values().toArray();
                for(int j=0;j<objs.length;j++){
                    if(objs[j] == null){
                        out.write("null");
                    }else{
                        out.write(String.valueOf(objs[j]));
                    }
                    if(j != objs.length - 1){
                        out.write(",");
                    }
                }
                if(i != list.size() - 1){
                    out.write("\n");
                }
            }
            out.flush();
        }catch(Exception ex){
            ex.printStackTrace();
        }finally{
            if(out != null){
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return filePath;
    }

    public void copyTest(String tablename,List<JSONObject> list){
        Connection conn = null;
        CopyManager copyManager = null;
        FileReader reader = null;

        try{
            long starttime = System.currentTimeMillis();
            String filePath = writeFile(list);

            conn = RemoteDBUtil.getInstance("ip",5432,"dbname","username","password").getConnection();
            copyManager = new CopyManager((BaseConnection)conn);
            reader = new FileReader(new File(filePath));
            copyManager.copyIn("copy "+tablename+" from stdin delimiter as ',' NULL as 'null'",reader);
            long endtime = System.currentTimeMillis();

            System.out.println(endtime-starttime);
        }catch(Exception ex){
            ex.printStackTrace();
        }finally{
            if(reader != null){
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(conn != null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args){
        List<JSONObject> list = new ArrayList<JSONObject>();
        for(int i=0;i<120000;i++){
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("id",i);
            jsonObject.put("testname","aaaa");
            list.add(jsonObject);
        }

        new Test().copyTest("copytest", list);
    }
}

然后,请记住COPY完成后一定要删除文件。

删除文件的代码:

File file = new File(filePath);
if(file.exists()){
    file.delete();
}

另外,再记录一个小插曲:

居然有张表据说最多每次插入3000条数据(100*30),要不然时间就会变长而且磁盘IO很高。我的眼镜都快掉到地上摔碎了,一度怀疑自己进入了平行宇宙。

后来一看,表上有个主键约束,而写入的数据中是包含主键这个字段的,也就是每条写入的数据数据库都需要检测唯一性。而当时,表中的数据已经600w+条了。不用会怀疑入库速度为啥如此之慢了。

而主键字段本身使用UUID生成的(网卡+毫米级时间戳+随机数)绝对保证唯一的,所以根本不需要数据库来保证唯一性。把约束去掉,入库速度就坐上飞机了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值