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

来源:互联网 发布:河南雪城软件 编辑:程序博客网 时间:2024/05/18 00:05

经过测试,大概写入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生成的(网卡+毫米级时间戳+随机数)绝对保证唯一的,所以根本不需要数据库来保证唯一性。把约束去掉,入库速度就坐上飞机了。

1 0
原创粉丝点击