【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 ...
随机推荐
- java判定数据(对象)类型
1.说明一 int 是关键字,Integer是包装类,Number是所有数字了的基类(父类).所以,Number是Integer的基础,Integer是int的基础,也称Integer是int的原型类 ...
- Linux动态连接器
转自:Chapter 9. Dynamic Linking 参考:Linux动态链接器 Linux加载启动可执行程序的过程(一)内核空间加载ELF的过程 Linux加载启动可执行程序的过程(二)解释器 ...
- VMware15 桥接模式无法上网
1. 检查宿主机网络连接是否成功 2. 检查宿主机网络适配器列表是否有多余的 loop 等回环类型的适配器(楼主在安装npcap程序后系统出现回环类型的适配器,即把包发回本地,所有的虚拟机的桥接模式都 ...
- 3.Git 命令行操作
1.Git 命令行操作(本地库操作): 1.1. 创建本地库(本地库初始化): 第一步:首先在D盘建了个名为git空文件夹,命令行中cd到这个文件夹: 第二步:通过git init命令把这个目录变成G ...
- Nginx access_log日志添加返回字段
主要为方便单用户请求日志回溯分析 记录用户标记. 将用户信息打印在access_log 日志里. 步骤: 1.重写nginx 的log格式 一般是地址是 /etc/nginx/conf.d/ng ...
- springboot整合freemarker模板引擎后在页面获取basePath绝对路径
在项目中引用静态资源文件或者进行ajax请求时我们有时候会使用 ${basePath} ,其实这就是一种获取绝对路径的方式: 那么在springboot项目中要怎么配置才能使用 basePaht呢? ...
- 个性化召回算法实践(一)——CF算法
协同过滤推荐(Collaborative Filtering Recommendation)主要包括基于用户的协同过滤算法与基于物品的协同过滤算法. 下面,以movielens数据集为例,分别实践这两 ...
- [终章]进阶20-流程控制结构--if/case/while结构 - 三个while的存储过程案例(批量生成表单数据) - 随机长度的随机字符串的存储过程案例
. mysql 存储过程中尽量使用 @变量 而不用局部变量, @变量不容易报错!权限小,更改一下就报错! . sql中判断相等'=' ,用'=' 不用'=='. . #流程控制结构 /* 顺序结构: ...
- erase & remove_if 合用
words_.erase( remove_if( words_.begin(), words_.end(), [&](const entry& e) { return (e.type ...
- Java基础面试题1
http://blog.csdn.net/jackfrued/article/details/44921941 1.面向对象的特征有哪些方面? 答:面向对象的特征主要有以下几个方面: - 抽象:抽象 ...