Java 具有限制行数的结果集jdbc驱动程序

Java 具有限制行数的结果集jdbc驱动程序,java,jdbc,Java,Jdbc,我正在尝试创建一个批处理程序。问题是表可能有200万行,这可能会产生内存问题。在我的工作中,我使用DB2,在家中测试时,我使用mysql 我已经用eclipse进行了调试,并且查看了resultset包含所有行的情况 我在网页上搜索过,但没有找到解决方案。例如,我的测试代码是: package misCodigos; import java.io.FileWriter; import java.io.IOException; import java.sql.Co

我正在尝试创建一个批处理程序。问题是表可能有200万行,这可能会产生内存问题。在我的工作中,我使用DB2,在家中测试时,我使用mysql

我已经用eclipse进行了调试,并且查看了resultset包含所有行的情况

我在网页上搜索过,但没有找到解决方案。例如,我的测试代码是:

    package misCodigos;

    import java.io.FileWriter;
    import java.io.IOException;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;

    public class testLimitDB {

        // JDBC driver name and database URL
        static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";  
        static final String DB_URL = "jdbc:mysql://localhost/testing";

        //  Database credentials
        static final String USER = "root";
        static final String PASS = "8182";


        private static FileWriter fw=null;

        public static void main(String[] args) {
            // Clase que pretende mostrar cómo insertar filas en java
            Connection conn = null;
            Statement stmt = null;


            try{

                //STEP 2: Register JDBC driver
                Class.forName("com.mysql.jdbc.Driver");

                //STEP 3: Open a connection
                System.out.println("Connecting to database...");
                conn = DriverManager.getConnection(DB_URL,USER,PASS);

                //STEP 4: Execute a query
                //  System.out.println("Creating statement...");
                stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
                        java.sql.ResultSet.CONCUR_READ_ONLY);
                String sql = "select * from tablaTest";


                PreparedStatement pstmt;
                pstmt = conn.prepareStatement(sql);

                conn.setAutoCommit(false);
                pstmt.setFetchSize(200);

                ResultSet rs = pstmt.executeQuery(sql);
                System.out.println("Starting to retrieve data. Memory Used: " + getUsedMemorySize());

                //System.out.println(rs.getString(rs.last()));

                /*          rs.last(); 
                int numRows = rs.getRow(); 
                System.out.println("Numero de filas: " + numRows);*/

                fw = new FileWriter("test.out");
                while (rs.next()) {
                    fw.write(rs.getInt(1) + ";" + rs.getString(2) + "\n");
                }
                System.out.println("Done retrieving data => Memory Used: "  + getUsedMemorySize());

                pstmt.close();
                conn.close();
                fw.flush();
                fw.close();

            }catch(Exception e){
                //Handle errors for Class.forName
                e.printStackTrace();
            }finally{
                //finally block used to close resources

                try{

                    if (fw != null){
                        fw.flush();
                        fw.close();      
                    }

                    if(stmt!=null) {
                        stmt.close();
                    }
                }catch(SQLException | IOException se2){
                }// nothing we can do
                try{
                    if(conn!=null) {
                        conn.close();
                    }
                }catch(SQLException se){
                    se.printStackTrace();
                }//end finally try
            }//end try
            System.out.println("Finalizado!");


        }

        public static long getUsedMemorySize() {

            long freeSize = 0L;
            long totalSize = 0L;
            long usedSize = -1L;
            try {
                Runtime info = Runtime.getRuntime();
                freeSize = info.freeMemory();
                totalSize = info.totalMemory();
                usedSize = totalSize - freeSize;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return usedSize;

        }

    }

Could anyone help me?
谢谢

PD:我创建了db2的代码。我不确定resultset是否只获取我喜欢的行,因为我在eclipse中使用了debug模式和resultset变量,现在它非常不同,并且看起来是加密的

import java.io.FileWriter;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class testLimitDB {

    // JDBC driver name and database URL
    //static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";  

    static final String JDBC_DRIVER = "com.ibm.db2.jcc.DB2Driver";  
    //static final String DB_URL = "jdbc:mysql://localhost/testing";
    static final String DB_URL = "jdbc:db2://localhost:50000/SAMPLE";

    //  Database credentials MYSQL
    //static final String USER = "root";

    static final String USER = "db2admin";
    static final String PASS = "8182";


    private static FileWriter fw=null;

    public static void main(String[] args) {
        // Clase que pretende mostrar cómo insertar filas en java

        Connection conn = null;
        Statement stmt = null;


        try{

            //STEP 2: Register JDBC driver
            Class.forName(JDBC_DRIVER);

            //STEP 3: Open a connection
            System.out.println("Connecting to database...");
            conn = DriverManager.getConnection(DB_URL,USER,PASS);

            //STEP 4: Execute a query
            //  System.out.println("Creating statement...");
            stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
                    java.sql.ResultSet.CONCUR_READ_ONLY);
            String sql = "select * from FELIPE.TABLATEST";


            PreparedStatement pstmt;
            pstmt = conn.prepareStatement(sql);

            conn.setAutoCommit(false);
            pstmt.setFetchSize(999);

            ResultSet rs = pstmt.executeQuery();
            System.out.println("Starting to retrieve data. Memory Used: " + getUsedMemorySize());

            //System.out.println(rs.getString(rs.last()));

            /*          rs.last(); 
            int numRows = rs.getRow(); 
            System.out.println("Numero de filas: " + numRows);*/

            fw = new FileWriter("test.out");
            while (rs.next()) {
                fw.write(rs.getInt(1) + ";" + rs.getString(2) + "\n");
            }
            System.out.println("Done retrieving data => Memory Used: "  + getUsedMemorySize());

            pstmt.close();
            conn.close();
            fw.flush();
            fw.close();

        }catch(Exception e){
            //Handle errors for Class.forName
            e.printStackTrace();
        }finally{
            //finally block used to close resources

            try{

                if (fw != null){
                    fw.flush();
                    fw.close();      
                }

                if(stmt!=null) {
                    stmt.close();
                }
            }catch(SQLException | IOException se2){
            }// nothing we can do
            try{
                if(conn!=null) {
                    conn.close();
                }
            }catch(SQLException se){
                se.printStackTrace();
            }//end finally try
        }//end try
        System.out.println("Finalizado!");


    }

    public static long getUsedMemorySize() {

        long freeSize = 0L;
        long totalSize = 0L;
        long usedSize = -1L;
        try {
            Runtime info = Runtime.getRuntime();
            freeSize = info.freeMemory();
            totalSize = info.totalMemory();
            usedSize = totalSize - freeSize;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return usedSize;

    }

}

我再次尝试,我的结论是驱动程序(mysql和db2)工作正常。我使用jvisualvm进行了测试,我清楚地看到内存随着光标的大小而变化。我将写一份包含不同结论的文件,并将其发布

我认为您的问题来自于使用没有服务器端游标的MySQL进行测试,而选择较大的结果集不可避免地会导致OOM,无论您是否设置了FETCH size


DB2没有同样的问题,因为游标和驱动程序不会抛出OOM。您需要定义一个非常适合的获取大小。如果你有一个大批量的工作,我会使用一个大的价值。换句话说,当您在同一环境下进行测试时:)

讨论如何在db2中进行测试。MySQL的可能重复使用“LIMIT”,您需要获取整个表的信息文件,还是只需要N行?Sasha,我需要获取整个表。谢谢Alexandre!我将尝试在DB2中进行测试,并会让您知道。:)Alexandre,我不确定行为是否正确,因为结果集非常不同,mysql和所有字段都是字母,没有意义。我想如果它用mysql抛出OOM,而用DB2抛出OOM,至少应该修复OOM异常。另一方面,如果您想100%确定它是如何工作的,您可以使用一个用于DB2 SQL监控的程序,例如QueryMonitor。在那里,您可以观察SQL是如何执行的。或者,您可以嗅探网络通信量,以查看完成了多少远程调用,这是如果您想验证获取大小。BHi Alexandre,我再次尝试,我的结论是驱动程序(mysql和db2)工作正常。我使用jvisualvm进行了测试,我清楚地看到内存随着光标的大小而变化。