前言
MySQL数据库是一种比较昂贵的资源,存储的数据必须是高价值的数据。对于一些存储在MySQL中,数据不变,且基本用不到的表。有时可以拉取下来备份到文件系统当中了,节约成本。本文将讲述用Java代码从MySQL中拉取数据库表为sql脚本,然后将其压缩为zip文件,节省空间。
实现原理
导出mysql数据为sql文本时用到的命令是:
###关键字和用户名之类的没有空格隔开,最后没有分号;
mysqldump -uUserName -pPassWord -hHost -PPort database tablename > D:\test\123.sql
执行过程:
- 先在MySQL的安装bin目录打开命令窗口(cmd)。
- 在输出目录查看文件,也可以不带盘符,默认为bin目录。
Java实现导出
获取表名
##假如每次获取该数据库中的1张表
SELECT
TABLE_NAME
FROM
information_schema.TABLES
WHERE
TABLE_SCHEMA = ( SELECT DATABASE ( ) )
ORDER BY
TABLE_NAME ASC
LIMIT 1
构建压缩后的文件名称
##tableName从上面得来
String zipName="src/main/resources/temp/"+tableName+".zip";
读取流并压缩
/**
* 拉取sql文件并压缩sql文件为zip文件
*
* @throws IOException
* IO异常
*/
public void getAndZip(String tableName, String zipName) throws IOException {
InputStream is = null;
OutputStream os = null;
ZipOutputStream zos = null;
String sqlName = tableName + ".sql";
// 构造sql命令
StringBuilder command = new StringBuilder();
// 构建导出sql命令:此处的数据库及其名称需要事先定义好
command.append("mysqldump -u").append(userName).append(" -p").append(passWord).append(" -h").append(host).append(" -P").append("3306").append(" ")
.append(table).append(" ").append(tableName);
try {
// 执行导出
Process pro = Runtime.getRuntime().exec(command.toString());
// 获取输入流,到了这一步基本完成了,如果只需要sql文本文件,这此时就可以自己将输入流读取为文本,不需要在进行下面的操作
is = pro.getInputStream();
os = new FileOutputStream(zipName);
// 压缩
zos = new ZipOutputStream(os);
// 这个是压缩sql文件,利用文件名创建条目sqlname以.sql结尾
ZipEntry zipEntry = new ZipEntry(sqlName);
//放进Entry
zos.putNextEntry(zipEntry);
// 读取完后无数据,即为-1
int count = -1;
// 每次读取16MB,内存能够支持,这里是依次写入,而不是一次性写入
byte[] bytes = new byte[LENGTH_16MB];
// 每次写16MB
while ((count = is.read(bytes)) != -1) {
// 写一次刷一次
zos.write(bytes, 0, count);
zos.flush();
}
} catch (IOException e) {
//日志记录
} catch (Exception e) {
//日志记录
} finally {
// 关闭流,注意顺序,一旦错了,会出现意想不到的错误。
close(zos, os, is);
}
}
下面是一个关闭多个流的简单方法
/**
* 多个关闭的简单方法
*/
private void close(Closeable... closeables) {
// 空直接返回
if (closeables == null || closeables.length == 0) {
return;
}
// 循环关闭流
for (Closeable closeable : closeables) {
try {
if (Objects.nonNull(closeable)) {
closeable.close();
}
} catch (Exception e) {
LOG.error("关闭流异常:{}", e);
}
}
}
注意事项
- mysqldump命令是window下面的命令,代码在本地可能运行良好,但是发到Linux服务器上基本会出现异常,此时需要运维的帮助,在Linux的MySQL中打入mysqlld.exe还是mysqldump.exe镜像,具体哪一个忘了。
- 流的关闭一定要遵从
先
进行实例化操作的后
关闭。或者直接使用Java8及以上的try_resource写法,最省事。