【SpringBoot/MVC】从Oracle下载百万条记录的CSV
工程下载地址:https://files.cnblogs.com/files/xiandedanteng/CsvDownloadOracle20191110-2.rar
画面:
核心代码:
控制器:
package com.hy.csvdld.ctrl; import java.io.File; import java.io.FileInputStream; import java.net.URLDecoder; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import com.hy.csvdld.service.EmpService; import com.hy.csvdld.util.CsvMaker; @Controller public class WebCtrl { private static Logger log = Logger.getLogger(WebCtrl.class); @Autowired EmpService empService; @RequestMapping("/") public String index(Model model) { log.info("进入index页"); return "index.html"; } @RequestMapping("/downloadTen") public void downloadTen(HttpServletResponse res, HttpServletRequest req) throws Exception { log.info("Start downloadTen"); SimpleDateFormat dfs = new SimpleDateFormat("yyyyMMddHHmmss"); Date time = new Date(); String tStamp = dfs.format(time); String localFilename = tStamp+".csv"; String path=req.getSession().getServletContext().getRealPath("/"); String localFilepath = path+localFilename; log.info("准备生成的本地路径文件名="+localFilepath); res.setContentType("multipart/form-data"); res.setCharacterEncoding("UTF-8"); res.setContentType("text/html"); String userAgent = req.getHeader("User-Agent"); if (userAgent.contains("MSIE") || userAgent.contains("Trident")) { // IE Core localFilename = java.net.URLEncoder.encode(localFilename, "UTF-8"); } else { // Non-IE Core localFilename = new String((localFilename).getBytes("UTF-8"), "ISO-8859-1"); } res.setHeader("Content-Disposition", "attachment;fileName=" + localFilename); localFilepath = URLDecoder.decode(localFilepath, "UTF-8"); File file=new File(localFilepath); CsvMaker maker=new CsvMaker(); maker.makeTenCsv(file, empService); log.info("已经生成文件:"+localFilepath); FileInputStream instream = new FileInputStream(localFilepath); ServletOutputStream outstream = res.getOutputStream(); int b = 0; byte[] buffer = new byte[1024]; while ((b = instream.read(buffer)) != -1) { outstream.write(buffer, 0, b); } instream.close(); if (outstream != null) { outstream.flush(); outstream.close(); boolean isDeleted=file.delete(); if(isDeleted) { log.info("已经删除文件:"+localFilepath); } } } @RequestMapping("/downloadMany/{count}") public void downloadMany(HttpServletResponse res, HttpServletRequest req,@PathVariable String count) throws Exception { log.info("Start downloadGeneratedCsvFile"); SimpleDateFormat dfs = new SimpleDateFormat("yyyyMMddHHmmss"); Date time = new Date(); String tStamp = dfs.format(time); String localFilename = tStamp+".csv"; String path=req.getSession().getServletContext().getRealPath("/"); String localFilepath = path+localFilename; log.info("准备生成的本地路径文件名="+localFilepath); res.setContentType("multipart/form-data"); res.setCharacterEncoding("UTF-8"); res.setContentType("text/html"); String userAgent = req.getHeader("User-Agent"); if (userAgent.contains("MSIE") || userAgent.contains("Trident")) { // IE Core localFilename = java.net.URLEncoder.encode(localFilename, "UTF-8"); } else { // Non-IE Core localFilename = new String((localFilename).getBytes("UTF-8"), "ISO-8859-1"); } res.setHeader("Content-Disposition", "attachment;fileName=" + localFilename); localFilepath = URLDecoder.decode(localFilepath, "UTF-8"); File file=new File(localFilepath); CsvMaker mk=new CsvMaker(); mk.makeManyCsv(file, empService, Integer.parseInt(count)); log.info("已经生成文件:"+localFilepath); FileInputStream instream = new FileInputStream(localFilepath); ServletOutputStream outstream = res.getOutputStream(); int b = 0; byte[] buffer = new byte[1024]; while ((b = instream.read(buffer)) != -1) { outstream.write(buffer, 0, b); } instream.close(); if (outstream != null) { outstream.flush(); outstream.close(); boolean isDeleted=file.delete(); if(isDeleted) { log.info("已经删除文件:"+localFilepath); } } } @RequestMapping("/downloadPartial/{count}") public void downloadPartial(HttpServletResponse res, HttpServletRequest req,@PathVariable String count) throws Exception { log.info("Start downloadPartial"); SimpleDateFormat dfs = new SimpleDateFormat("yyyyMMddHHmmss"); Date time = new Date(); String tStamp = dfs.format(time); String localFilename = tStamp+".csv"; String path=req.getSession().getServletContext().getRealPath("/"); String localFilepath = path+localFilename; log.info("准备生成的本地路径文件名="+localFilepath); res.setContentType("multipart/form-data"); res.setCharacterEncoding("UTF-8"); res.setContentType("text/html"); String userAgent = req.getHeader("User-Agent"); if (userAgent.contains("MSIE") || userAgent.contains("Trident")) { // IE Core localFilename = java.net.URLEncoder.encode(localFilename, "UTF-8"); } else { // Non-IE Core localFilename = new String((localFilename).getBytes("UTF-8"), "ISO-8859-1"); } res.setHeader("Content-Disposition", "attachment;fileName=" + localFilename); localFilepath = URLDecoder.decode(localFilepath, "UTF-8"); File file=new File(localFilepath); CsvMaker mk=new CsvMaker(); mk.makePartialCsv(file, empService, Integer.parseInt(count)); log.info("已经生成文件:"+localFilepath); FileInputStream instream = new FileInputStream(localFilepath); ServletOutputStream outstream = res.getOutputStream(); int b = 0; byte[] buffer = new byte[1024]; while ((b = instream.read(buffer)) != -1) { outstream.write(buffer, 0, b); } instream.close(); if (outstream != null) { outstream.flush(); outstream.close(); boolean isDeleted=file.delete(); if(isDeleted) { log.info("已经删除文件:"+localFilepath); } } } }
CSV生成器:
package com.hy.csvdld.util; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.List; import org.apache.log4j.Logger; import com.hy.csvdld.Entity.Emp; import com.hy.csvdld.service.EmpService; // 用于生成CSV文件 public class CsvMaker { private static Logger log = Logger.getLogger(CsvMaker.class); public void makeTenCsv(File file, EmpService empService) { try { List<Emp> emps = empService.selectTenEmp(); FileWriter fileWriter = new FileWriter(file, true); int index = 0; for (Emp emp:emps) { index++; String info =""+index+","+ emp.asCsvLine()+ System.getProperty("line.separator"); fileWriter.write(info); } fileWriter.flush(); fileWriter.close(); } catch (IOException e) { e.printStackTrace(); } } public void makeManyCsv(File file, EmpService empService,int count) { try { List<Emp> emps = empService.selectMany(count); FileWriter fileWriter = new FileWriter(file, true); int index = 0; for (Emp emp:emps) { index++; String info =""+index+","+ emp.asCsvLine()+ System.getProperty("line.separator"); fileWriter.write(info); } fileWriter.flush(); fileWriter.close(); } catch (IOException e) { e.printStackTrace(); } } // 当count过大时,分批下载 public void makePartialCsv(File file, EmpService empService,int count) { try { int PartialSize=10000; int times=count/PartialSize; for(int i=0;i<times;i++){ log.info("第"+i+"批次处理"); FileWriter fileWriter = new FileWriter(file, true); List<Emp> emps = empService.selectPartial(i*PartialSize, (i+1)*PartialSize); int index = i*PartialSize; for (Emp emp:emps) { index++; String info =""+index+","+ emp.asCsvLine()+ System.getProperty("line.separator"); fileWriter.write(info); } fileWriter.flush(); fileWriter.close(); } } catch (IOException e) { e.printStackTrace(); } } }
Mapper.xml:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.hy.csvdld.dao.EmpMapper"> <select id="selectTenEmp" resultType="com.hy.csvdld.Entity.Emp"> select id,name,age,createdtime as ctime from tb01 where rownum<11 order by id </select> <select id="selectManyEmp" resultType="com.hy.csvdld.Entity.Emp"> select id,name,age,createdtime as ctime from tb01 where rownum<#{count} order by id </select> <select id="selectPartialEmp" resultType="com.hy.csvdld.Entity.Emp"> select * from (select rownum no,id,name,age,createdtime as ctime from tb01 where rownum<=#{max} order by id) tbTmp where no>#{min} </select> </mapper>
这个方案是MYSQL同类方案的新番,差别在于用rownum去替代MySql中的limit函数
--END-- 2019年11月10日14:51:32
【SpringBoot/MVC】从Oracle下载百万条记录的CSV的更多相关文章
- 使用PL/SQL删除百万条记录的大表
使用PL/SQL删除百万条记录的大表: 最近开发人员对测试环境数据库进行了压力测试,数据库中产生了大量的脏数据.有几张大表里数据量均在百万甚至千万条的记录数.开发人员现提出需求如下: 只清理其中的部分 ...
- 【原创】如何找到Oracle中哪条记录被锁
通常有这种情况,某个表或者准确的说是表的某条记录被锁(TX锁),在业务层面排查之余,一般都会想知道是哪条记录被锁,每次被锁的是否是同一条记录?还是每次都不同?通过记录可以找到这条记录可以在哪个模块.哪 ...
- Oracle前10条记录
在Oracle怎样查询表中的top10条记录呢? select * from test where rownum <=10 下面是关于rownum的介绍 ==================== ...
- MVC批量添加,增加一条记录的同时添加N条集合属性所对应的个体
类别中包含一个产品的集合属性,如何向数据库添加一条类别记录的同时,添加任意多个产品. public class Product { [DisplayName("产品名称")] pu ...
- 【Oracle/Java】以Insert ALL方式向表中插入百万条记录,耗时9分17秒
由于按一千条一插程序长期无反应,之后改为百条一插方式,运行完发现插入百万记录需要9m17s,虽然比MySQL效率差,但比单条插入已经好不少了. 对Oracle的批量插入语法不明的请参考:https:/ ...
- oracle 复制一条记录只改变主键不写全部列名
场景:表TEST中有C1,C2,C3...字段,其中C1为主键,先需要复制表TEST中一条(C1='1'的)记录,修改主键列C1和需要变更的列后,再插入到表TEST中. procedure P_TES ...
- oracle count 百万级 分页查询记要总数、总条数优化
oracle count 百万级 分页查询记录总数.总条数优化 oracle count 百万级 查询记录总数.总条数优化 最近做一个项目时,做分页时,发现分页查询速度很慢,分页我做的是两次查询,一次 ...
- oracle中根据当前记录查询前一条和后一条记录
select * from aa01_2014 where aaa001=(select c.p from (select aaa001,lag(aaa001,1,0) over (order by ...
- 【转】oracle 中随机取一条记录的两种方法
oracle 中随机取一条记录的两种方法 V_COUNT INT:=0; V_NUM INT :=0; 1:TBL_MYTABLE 表中要有一个值连续且唯一的列FID BEGIN SELECT COU ...
随机推荐
- [nginx] nginx使用SNI功能的方法
SNI是什么 在使用TLS的时候,http server希望根据HTTP请求中HOST的不同,来决定使用不同的证书. SNI细节 由于HTTP的HOST字段在HTTP GET中.而TLS的握手以及证书 ...
- [dev][ipsec][esp] ipsec链路中断的感知问题
ipsec如何感知到链路中断了?以下内容讲的是在没有配置DPD,且没有rekey的场 景下. 1. ESP认为,以下两个场景交由应用层来感知,应用层会发现ipsec的连接坏掉了. a,ESP承载的连接 ...
- spark-submit之使用pyspark
在linux下,执行pyspark代码 —— 实测有效:但是并不是所有的包都能够成功,一些很复杂的包或者对C依赖很深的包例如 numpy, pandas, scipy等,无法通过本方法实现:对一些比较 ...
- Python语言程序设计:Lab4
Programming 1.Analysing a Text File Look at the file xian_info.txt which is like this: Xi'an China 8 ...
- rabbitmq二进制安装
一.erland的安装 1.首先测试一下是否已经安装了erlang,命令 rpm -qa | grep erlang 2.没有安装则用yum安装 yum install erlang -y 二.下载r ...
- two pointers 思想
针对有序的序列特性做出的优化思想
- 在cmd运行窗口运行.py文件
步骤
- 除了不要 SELECT * ,程序员使用数据库还应知道的11个技巧
SQL:sum里加条件SELECT SUM( CASE WHEN "V7010" BETWEEN 0 AND 0.1 THEN 1 ELSE 0 END) FROM "C ...
- Selenium常用API的使用java语言之1-环境安装之Java
(一)环境安装之Java 1.安装java 点击 JDK8下载,根据自己的平台,选择相应的版本进行下载. 小知识: Java环境分JDK和JRE ,JDK就是Java Development Kit. ...
- Appium自动化测试教程-自学网-monkey自定义脚本实践
自定义脚本的稳定性测试 常规Monkey测试执行的是随机的事件流,但如果只是想让Monkey测试某个特定场景这时候就需要用到自定义脚本了,Monkey支持执行用户自定义脚本的测试,用户只需要按照Mon ...