0

I am having a table with huge number of records say nearly 25gb with more than 1000 million records. I want to fetch them using java and write to a csv. I thought of using java8 stream to stop bring whole result set to memory but still i am getting a java heap space error.

    try {

                close=UncheckedCloseable.wrap(con);
                pSt = con.prepareStatement("select * from "+this.tblName);
                close=close.nest(pSt);
                con.setAutoCommit(false);
                pSt.setFetchSize(5000);

                ResultSet resultSet = pSt.executeQuery();
                close=close.nest(resultSet);
                Stream<String> buffer = StreamSupport.stream(new Spliterators.AbstractSpliterator<String>(
                        Long.MAX_VALUE,Spliterator.ORDERED) {

                    @Override
                    public boolean tryAdvance(Consumer<? super String> action) {
                        try {
                            if(!resultSet.next()) return false;
                            action.accept(createRecord(resultSet));
                            return true;
                        } catch(SQLException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
                            throw new RuntimeException(ex);
                        }
                    }

                }, false).onClose(close);

                System.out.println(buffer.count());
                Files.write(Paths.get(home.getAbsolutePath()+"/"+tblName+".csv"), (Iterable<String>)buffer::iterator);

            }


private String createRecord(ResultSet resultSet) throws SQLException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        StringBuffer buffer = new StringBuffer();
        int colCount = resultSet.getMetaData().getColumnCount();
        while(resultSet.next()) {
            for(int i=1; i<=colCount; i++) {
                String columnName = resultSet.getMetaData().getColumnTypeName(i);
                String getType = StringUtils.capitalize(columnName.toLowerCase());
                Method methodName = getMethodName(resultSet,getType);
                Object result = methodName.invoke(resultSet, i);
                if(result == null || result.toString().equalsIgnoreCase("null")){
                    result =  "";
                }
                if (result instanceof String) {
                    result = ((String) result).trim().replaceAll(",", "\\\\,").replace("\n", "").replace("\r", "");
                }
                buffer.append(result+",");
            }
            buffer.setLength(buffer.length()-1);
            buffer.append("\n");
        }
        return buffer.toString();
    }
Lukas Eder
  • 211,314
  • 129
  • 689
  • 1,509

0 Answers0