`

Java一次性查询几十万 几百万数据解决办法

    博客分类:
  • Java
阅读更多

在做大数据量同步的时候,需要注意的内存使用问题,程序稍微控制不足,可能就会导致内存溢出等问题...在网上找了一些资料,发现大家都使用的如下方式:

 

1、先批量查询出所有数据,例子中是一万条一次

2、在查出数据后把每次的数据按一定的规则存入本地文件

3、读取文件数据时,可以采取单例模式,批量提交等方式操作数据库

 

代码如下:

public boolean createUploadFileByAll() {
        boolean flag = false;
        int onerun = 10000;  // 每次读取记录数
        int lastrow = 0; // 每次读取后的最后一条记录
        ResultSet rs = null;
        Statement stat = null;
        try {
            String hql = "SELECT count(*) FROM T_jgdm";
            int datanum = ((Long) this.getSession().createQuery(hql).uniqueResult()).intValue();
            int runnum = datanum % onerun == 0 ? (datanum / onerun) : (datanum / onerun) + 1;
            // 分批读取数据
            conn = getConn();
            stat = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
            StringBuffer text = new StringBuffer();
            text.append("机构代码(JGDM)-").append("机构名称(JGMC)-").append("首次办证日期(SCBZRQ)-");
            text.append("外经委填表人(WJWTBR)-").append("可否公开(GK)-").append("发卡标志(FKBZ)-");
            text.append("发卡数量(FKSL)-").append("打印标志(DYBZ)-").append("电邮地址(EMAIL)-");
            text.append("网址(URL)-").append("最后修改日期(LASTDATE)-").append("操作标志(CZFLAG)-");
            text.append("是否邮寄(YJFLAG)-").append("数据状态(SJZT)-").append("检验结果(JYJG)-");
            text.append("分值(FZ)-").append("作废日期(ZFRQ)-").append("办证机构区划代码(BZJGDM)-");
            text.append("变更日期(BGRQ)-").append("年检日期(NJRQ)-").append("年检期限(NJQX)-");
            text.append("迁址日期(QZRQ)-").append("开户银行(KHYH)-").append("开户账号(KHZH)\r\n");  // 文件列注解  \r\n为换行符

            for (int r = 0; r < runnum; r++) {
                System.out.println("createUploadFileByAll--" + datanum + " 开始查询第" + (r + 1) + "批数据");
                String sql = "SELECT *\n" +
                        "  FROM (SELECT rownum rn, " + QUERY_FIELD + " FROM t_jgdm ORDER BY rownum ASC)\n" +
                        " WHERE rn > " + lastrow;
                stat.setMaxRows(onerun);
                stat.setFetchSize(1000); // 当调用rs.next时,ResultSet会一次性从服务器上取1000行数据回来,在下次rs.next时,它可以直接从内存中获取出数据而不需要网络交互,从而提高效率
                rs = stat.executeQuery(sql);
                // 生成文件
                int i = 1;
                while (rs.next()) {
                    String jgdm = rs.getString("JGDM");
                    String jgmc = rs.getString("JGMC");
                    String scbzrq = rs.getString("SCBZRQ");
                    String wjwtbr = rs.getString("WJWTBR");
                    String gk = rs.getString("GK");
                    String fkbz = rs.getString("FKBZ");
                    String fksl = rs.getString("FKSL");
                    String dybz = rs.getString("DYBZ");
                    String email = rs.getString("EMAIL");
                    String url = rs.getString("URL");
                    String lastdate = rs.getString("LASTDATE");
                    String czflag = rs.getString("CZFLAG");
                    String yjflag = rs.getString("YJFLAG");
                    String sjzt = rs.getString("SJZT");
                    String jyjg = rs.getString("JYJG");
                    String fz = rs.getString("FZ");
                    String zfrq = rs.getString("ZFRQ");
                    String bzjgdm = rs.getString("BZJGDM");
                    String bgrq = rs.getString("BGRQ");
                    String njrq = rs.getString("NJRQ");
                    String njqx = rs.getString("NJQX");
                    String qzrq = rs.getString("QZRQ");
                    String khyh = rs.getString("KHYH");
                    String khzh = rs.getString("KHZH");

                    text.append(StringUtil.isNotEmpty(jgdm) ? jgdm : " ").append("^^^^");
                    text.append(StringUtil.isNotEmpty(jgmc) ? jgmc : " ").append("^^^^");
                    text.append(StringUtil.isNotEmpty(scbzrq) ? scbzrq : " ").append("^^^^");
                    text.append(StringUtil.isNotEmpty(wjwtbr) ? wjwtbr : " ").append("^^^^");
                    text.append(StringUtil.isNotEmpty(gk) ? gk : " ").append("^^^^");
                    text.append(StringUtil.isNotEmpty(fkbz) ? fkbz : " ").append("^^^^");
                    text.append(StringUtil.isNotEmpty(fksl) ? fksl : "").append("^^^^");
                    text.append(StringUtil.isNotEmpty(dybz) ? dybz : " ").append("^^^^");
                    text.append(StringUtil.isNotEmpty(email) ? email : " ").append("^^^^");
                    text.append(StringUtil.isNotEmpty(url) ? url : " ").append("^^^^");
                    text.append(StringUtil.isNotEmpty(lastdate) ? lastdate : "").append("^^^^");
                    text.append(StringUtil.isNotEmpty(czflag) ? czflag : " ").append("^^^^");
                    text.append(StringUtil.isNotEmpty(yjflag) ? yjflag : " ").append("^^^^");
                    text.append(StringUtil.isNotEmpty(sjzt) ? sjzt : " ").append("^^^^");
                    text.append(StringUtil.isNotEmpty(jyjg) ? jyjg : " ").append("^^^^");
                    text.append(StringUtil.isNotEmpty(fz) ? fz : " ").append("^^^^");
                    text.append(StringUtil.isNotEmpty(zfrq) ? zfrq : " ").append("^^^^");
                    text.append(StringUtil.isNotEmpty(bzjgdm) ? bzjgdm : " ").append("^^^^");
                    text.append(StringUtil.isNotEmpty(bgrq) ? bgrq : " ").append("^^^^");
                    text.append(StringUtil.isNotEmpty(njrq) ? njrq : " ").append("^^^^");
                    text.append(StringUtil.isNotEmpty(njqx) ? njqx : " ").append("^^^^");
                    text.append(StringUtil.isNotEmpty(qzrq) ? qzrq : " ").append("^^^^");
                    text.append(StringUtil.isNotEmpty(khyh) ? khyh : " ").append("^^^^");
                    text.append(StringUtil.isNotEmpty(khzh) ? khzh : " ").append("^^^^\r\n");

                    if (i % 1000 == 0) {
                        // 创建文件,并追加内容
                        FileOperate fileOperate = FileOperate.getFileOperate();
                        fileOperate.createFileByAddTo(UPLOAD_TEMP_FILE_NAME_BY_ALL, text.toString());
                        text = new StringBuffer("");
                    }
                    i++;
                }
                // 向文件中追加不能被1000求余的内容
                if (text.length() > 10) {
                    FileOperate fileOperate = FileOperate.getFileOperate();
                    fileOperate.createFileByAddTo(UPLOAD_TEMP_FILE_NAME_BY_ALL, text.toString());
                }
                lastrow += onerun;
            }
            rs.close();
            stat.close();
            conn.close();
            flag = true;
        } catch (Exception e) {
            flag = false;
            e.printStackTrace();
        }
        return flag;
    }

    文件操作方法如下:

/**
     * 新建文件(在原有文件内容上进行追加)
     * 默认编码UTF-8
     * @param filePathAndName
     * @param fileContent
     */
    public void createFileByAddTo(String filePathAndName, String fileContent) {
        try {
            File file = new File(filePathAndName);
            BufferedWriter bw = null;
            try {
                bw = new BufferedWriter(new FileWriter(file, true)); // 参数true表示向文件中追加内容
                bw.write(fileContent);
                bw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            System.out.println("新建文件(在原有文件内容上进行追加)出错:");
            e.printStackTrace();
        }
    }

 

分享到:
评论

相关推荐

    java快速导出几十万百万生成DBF文件数据后台

    本项目“java快速导出几十万百万生成DBF文件数据后台”主要关注如何使用Java编程语言高效地处理大规模数据,将其导出为DBF文件格式。 首先,我们需要了解Java处理大量数据的基本策略。在Java中,处理大数据的关键...

    java快速导出几十万百万生成DBF文件数据后台内附有javadbf.jar

    `javadbf.jar`库通过优化内存管理和I/O操作,可以高效地处理数十万乃至上百万条记录。以下是一些使用这个库实现高效DBF数据处理的关键步骤: 1. **引入库**: 在项目中引入`javadbf.jar`,这通常通过Maven或Gradle等...

    Java Mybatis Maven多线程处理百万数据修改的小工具项目

    总的来说,"Java Mybatis Maven多线程处理百万数据修改的小工具"项目展示了如何巧妙地结合Mybatis的灵活性和Java的多线程能力,来解决大数据量处理的难题。这种解决方案对于处理大数据场景的企业级应用具有很高的...

    java实现csv导出千万级数据实例

    1. **数据分页**:根据数据库查询能力,设定合适的分页大小,如10000条或20000条,避免一次性取出过多数据。 2. **流式处理**:使用Java的BufferedWriter类进行流式写入,每批数据读取后立即写入文件,减少内存占用...

    java导出30万数据量的excel(采用生成多个excel,最后打包zip)

    在Java开发中,处理大数据量的Excel导出是一项常见的任务,尤其当数据量达到数十万条时,单个Excel文件可能会遇到性能瓶颈或格式限制。本项目针对这一问题提出了一种解决方案,即分块生成多个Excel文件,然后将它们...

    读取百万级数据量的xlsx文件的java代码

    该代码可以处理100万数据量的excel文件,xlsx文件数据量太大,用普通的读法会报内存溢出错误,所以用官网提供的方法,一条一条的读取大excel文件,本例子从这点出发,组装excel里读取的单条数据为list,在根据需求...

    java csv大数据量导出(千万级别,不会内存溢出)

    然而,当数据量达到千万级别时,传统的单线程、一次性加载到内存的方式可能导致内存溢出,严重影响系统的稳定性和性能。为了应对这种情况,我们需要采用优化策略来实现高效且不会内存溢出的大数据量CSV导出。 首先...

    java快速插入千万级数据

    java快速插入千万级数据,亲测91秒插入1700万数据!!!

    java 读取串口数据(绝对可使用)

    Java 读取串口数据是Java编程中一个重要的部分,特别是在物联网(IoT)设备通信、嵌入式系统以及工业自动化等领域。RXTX库是一个流行的开源Java库,用于实现与串行端口(COM口)和并行端口的交互。在本教程中,我们将...

    JAVA将一个数据中数据定时自动复制(抽取)到另一个数据库

    本文将深入探讨如何使用Java编程语言实现从一个数据库中定时自动抽取数据并复制到另一个数据库,以达到数据库间的实时或近实时同步。 首先,我们需要了解基础概念。Java是一种广泛使用的面向对象的编程语言,具有...

    java多线程导出excel(千万级别)优化

    传统的Apache POI库在处理大规模数据时可能会遇到栈溢出(StackOverflowError)和内存溢出(OutOfMemoryError)等问题,因为这些库将所有数据加载到内存中一次性处理。为了解决这些问题,我们可以采用分批导出和多...

    java多个数据库实现数据同步

    在IT行业中,数据库同步是一个关键话题,特别是在分布式系统和企业级应用中,多个数据库的同步是确保数据一致性、完整性和高可用性的重要手段。本文将深入探讨如何使用Java来实现多个数据库之间的数据同步。 首先,...

    java连接opc读取数据

    最近由于项目需要,在已有java web工程里添加读取opc的接口类。通过接口将opc数据读取到本地存于oracle数据库中,供本管理系统趋势分析用。本实例在win7、xp系统本地均已调通。压缩包里有本人写的每一步详细说明操作...

    java swing 多选下拉框 支持动态加载数据

    4. **Dynamic Loading Data**:动态加载数据意味着在用户交互时,数据不是一次性全部加载,而是按需加载。这可以提高应用性能,特别是在处理大量数据时。可以使用懒加载策略,只有当用户滚动到新数据或请求更多数据...

    java中使用poi导出Excel大批量数据到客户端

    在java web系统应用中我们经常会用到大批量数据的导出,动辄就上几十万几百万的数据让我们的程序感觉压力很大,甚至都出现无法导出的情况,如内存溢出等。 java中使用poi导出Excel大批量数据到客户端 存在两个导出...

    Java抓取网页数据Demo

    在IT领域,网络数据抓取是一项重要的技能,特别是在大数据分析、搜索引擎优化和市场研究中。本文将详细讨论如何使用Java语言来抓取网页数据,包括两种主要方法:直接抓取原网页内容和处理网页中的JavaScript返回数据...

    Java抓取https网页数据

    Java抓取https网页数据,解决peer not authenticated异常。导入eclipse就能运行,带有所用的jar包(commons-httpclient-3.1.jar,commons-logging.jar,httpclient-4.2.5.jar,httpcore-4.2.4.jar)

    could not create the java virtual machine 解决办法

    ### "could not create the java virtual machine" 解决办法 在开发过程中,我们经常会遇到 “could not create the java virtual machine” 这样的错误提示。这个问题通常出现在启动基于Java的应用程序时,比如...

    数据结构与算法分析(java语言描述)中文第二版以及习题答案

    总的来说,这个资源集合为Java开发者提供了一个全面学习数据结构和算法的平台,不仅可以理论学习,还可以动手实践,对于提升编程能力和解决问题的能力大有裨益。无论是初学者还是经验丰富的开发者,都可以从中受益。

    java数据结构笔试题

    这三类题目在Java工程师的笔试中十分常见,因为它们不仅测试应聘者对数据结构与算法的理论知识掌握,还考察了对Java语言特性的熟悉程度以及编码实现的准确性。二分查找要求应聘者具备对分治思想的理解和应用,冒泡...

Global site tag (gtag.js) - Google Analytics