从文件(XML / Flat / CSV)读取批量数据并在数据库中上传数据

时间:2012-09-02 08:02:46

标签: java database bulk

我需要从文件中读取大约1 000 000行数据,并使用Java将数据上传到数据库中。 以下是要求的细节和我已经写过的一些解决方案:

  1. 从文件中读取数据(任何格式的XML,平面文件,CSV)。 根据文件格式初始化类(使用Factory模式)。对于文本文件,我使用BufferedReader,然后添加每个创建的对象,例如列表中的员工。 类似地,对于XML,我使用SAXParser,并且在从一个对象读取数据后将其添加到列表中。

  2. 但我认为我们不能保存,或者我们应该在列表中保存1 000 000个对象。所以我需要在读取文件和列表达到一定大小时并行地将数据刷新到数据库中。这是我被困的地方。应如何处理?我应该运行一个并行线程,一旦列表大小达到1000,就会更新数据库中的数据,同时读取文件的线程应该等待吗? DB可以是任何数据库Oracle / MS访问。

  3. 以下是阅读文本文件的代码:

    public class FlatFileLoader implements Loader {
    
    @Override
    public List<Employee> readData(String path) {
    
        try {
            List<Employee> personList =  new ArrayList<Person>();
            FileReader fr = new FileReader(path);
            BufferedReader br = new BufferedReader(fr);
              String line=null;
    
              while ((line = br.readLine()) != null) {
                  Employee person = scanLine(line, DataConstants.DELIMITER);
                  if(null != person)
                  personList.add(person);
    
                }
              br.close();
    
            }
            catch (IOException e) {
              System.err.println(e);
            }
        return null;
    }
    
    private Employee scanLine(String recordLine, String delim) {
        Employee person=null;
        List data= new ArrayList();
        StringTokenizer lineScanner = new StringTokenizer(recordLine, delim);
        while (lineScanner.hasMoreElements()) {
            String nextEle= (String) lineScanner.nextElement();
            if(nextEle.equalsIgnoreCase("FIRST_NAME")){
                break;
            }
            data.add(nextEle);
    
        }
        if(data.size() > 0){
            DataUtil.populatedata(data);
        }
        return person;
    }
    
    }
    

    方法 DataUtil.populatedata(data) 创建Employee个对象。 那么我应该在哪里将数据更新到DB? 任何改进上述代码的建议也是受欢迎的。

1 个答案:

答案 0 :(得分:0)

你想如何刷新数据主要取决于你想要使用多少内存,但是在加载1000个对象之后刷新数据是一个好主意,因为你不必为每个加载的Employee实例写入数据库, 1000个物体也不会占用太多记忆。

如果您使用并行线程来刷新Employee对象列表,那么请注意线程同步问题:在创建线程t2以插入下一个1000个对象之前,线程t1可能无法完成将其1000个对象插入到db中。因此,两个线程现在并行地将对象插入到DB中,因此输入文件(XML,文本)中的数据排序可能不会保留在DB中。

我的建议:保持简单,让读者等待数据插入数据库。 1000000对象并不是那么多......

在personList.add(person)之后插入数据库插入代码:

....
    if(personList.size()>=1000){
        flushToDB(personList);
        personList.clear();
    }
....

同时,

void flushtoDB(List<Employee> persons){
    for(Employee person:persons){
        //insert Employee object into DB
    }
}