导入.sql文件显示进度条
业务以及问题描述:要将.sql文件进行上传并导入到数据库中。使用ScriptRunner的runScript方法。封装好的方法没办法获取执行的次数就没办法算百分比。
开始的思路是计算大文件上传的进度条,但是后来想到实际上占用时间比较久的是sql导入执行的过程。怎么把这两个进度一起进行合并计算执行进度就是个比较大的问题了。
将重点放在runScript方法,runScript有两种执行方法,一种是sendFullScript为true的将会执行executeFullScript方法,另为executeLineByLine。
public void runScript(Reader reader) {
setAutoCommit();
try {
if (sendFullScript) {
executeFullScript(reader);
} else {
executeLineByLine(reader);
}
} finally {
rollbackConnection();
}
}
顾名思义,一种是全部一起执行,一种为一行一行的执行。可以查看源代码得知,executeFullScript将每一行进行拼接,传入executeStatement方法。executeLineByLine将读取到的每一行传入到handleLine方法中,底层实现也是通过executeStatement执行。(这里我就不贴源码啦,可以自己去看一下)
说一下实现思路:
骚操作一波,文件上传部分我自己设置了百分之十,剩下百分之九十为sql的导入。创建文件夹设置百分之三到百分之四的随机数,上传文件设置百分之五到百分之六。计算文件行数(为计算sql进度做准备)设置百分之十。
接下来是sql部分:
先说思路,再贴代码。思路很简单,将ScriptRunner的代码copy出来自己改。改executeLineByLine的方法就行。需要传入三个参数:Read read和文件的总行数total,用户主键userAccount(存储进度时候的key值)在读取每一行数据的时候进行累加,将累加的值除以文件总行数total就行。
(用Redis的时候这里遇到个问题,不能注入于是乎自己写了个方法存储)
上传文件代码:
public boolean uploadFile(MultipartFile file, HttpServletRequest request,User user) throws Exception {
Random random = new Random();
String f = file.getOriginalFilename();
//拼接文件名
String filename = f.substring(f.lastIndexOf("/")+1);
String id = UUID.randomUUID().toString().replaceAll("_","").substring(0,8);
String type = filename.substring(filename.lastIndexOf("."));
String name = filename.substring