SSM 实现网站后台导出 sql 文件备份数据库

本贴最后更新于 1826 天前,其中的信息可能已经时异事殊

网站备份常常是很有必要的,备份的方式有很多。之前不懂怎么备份,网上查了一下,看看怎么通过 Java 程序执行备份 cmd 命令,再结合 solo 的实现,自己的毕设也算是实现了这样的功能。solo 用的是 Latke 的一个工具类 Execs,但是我在用这个工具类的时候,可以 ping,但是就是不能做执行备份的 cmd 命令,可能是自己使用的姿势不对,所以索性自己给改改。

准备

导出是参看了 solo 的,压缩成 zip 包再响应前端,压缩用到了一个工具类:jodd-core-5.0.12.jar,下载地址:https://mvnrepository.com/artifact/org.jodd/jodd-core

JSP

我这里主要就是一个 a 标签。

<a href="exportSQL">导出数据库</a>

Controller

//从配置文件获得数据库信息,以备导出数据库
@Value("#{configProperties['jdbc.username']}")
private String dbUser;
@Value("#{configProperties['jdbc.password']}")
private String dbPwd;
@Value("#{configProperties['jdbc.url']}")
private String dbURL;

这里连接数据库,是通过 jdbc.properties 文件得到的,获取值如上。

//导出数据库

@RequestMapping("/exportSQL")
@ResponseBody
public void exportSQL(HttpServletRequest request, HttpServletResponse response) throws FileNotFoundException, IOException {
	int beginIndex = dbURL.lastIndexOf("/") + 1;
	int endIndex = dbURL.indexOf("?");
	//截取,获得数据库名字
	String databaseName = dbURL.substring(beginIndex, endIndex);
	// 设置导出编码为utf8。这里必须是utf8。cmd命令,-u和-p后边没有空格
	String cmd = "mysqldump -u" + dbUser + " -p" + dbPwd + " -hlocalhost --set-charset=utf8 --databases " + databaseName;
	try {
		Runtime runtime = Runtime.getRuntime();
		// 调用 MySQL 的 CMD
		Process child = runtime.exec(cmd);
		// 把进程执行中的控制台输出信息写入.sql文件,即生成了备份文件。注:如果不对控制台信息进行读出,则会导致进程堵塞无法运行
		InputStream in = child.getInputStream();// 控制台的输出信息作为输入流
		InputStreamReader xx = new InputStreamReader(in, "utf8");// 设置输出流编码为utf8。这里必须是utf8,否则从流中读入的是乱码
		String inStr;
		StringBuffer sb = new StringBuffer("");
		String outStr;
		// 组合控制台输出信息字符串
		BufferedReader br = new BufferedReader(xx);
		while ((inStr = br.readLine()) != null) {
			sb.append(inStr + "\r\n");
		}
		outStr = sb.toString();
		//取得系统缓存目录
		String tmpDir = System.getProperty("java.io.tmpdir");
		//获得当前时间戳
		String date = DateFormatUtil.getStringTime();
		String localFilePath = tmpDir + "db_shms-" + date + ".sql";
		File localFile = new File(localFilePath);
		byte[] data = outStr.getBytes("UTF-8");
		try (final OutputStream output = new FileOutputStream(localFile)) {
			IOUtils.write(data, output);
		}
		File zipFile = ZipUtil.zip(localFile);
		byte[] zipData;
		try (final FileInputStream inputStream = new FileInputStream(zipFile)) {
			zipData = IOUtils.toByteArray(inputStream);
		}
		//设置响应相关的参数
		response.setContentType("application/zip");
		final String fileName = "db_shms-" + date + ".zip";
		response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
		final ServletOutputStream outputStream = response.getOutputStream();
		outputStream.write(zipData);
		in.close();
		xx.close();
		br.close();
		outputStream.flush();
		outputStream.close();
		//删除缓存目录的缓存文件,sql文件和zip文件
		localFile.delete();
		zipFile.delete();
	} catch (Exception e) {
		e.printStackTrace();
	}
}

需要注意的就是 cmd 命令,在哪些地方需要空格,哪里不需要空格,毕竟是命令,关系到导出是否成功。
关于 mysqldump 命令的详细参数,可以看这个 https://www.cnblogs.com/liuriqi/p/4207310.html

XML 配置

这里主要就是配置 properties 文件。

xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/util 
		http://www.springframework.org/schema/util/spring-util.xsd">

	<!-- 加载数据库配置文件 -->
	<util:properties id="configProperties" location="classpath:jdbc.properties" />

这样,在 Controller 就能通过 @Value 注解获得配置文件的相应参数值。至于 jdbc.properties 文件,这里就不写了,就是数据库配置的 properties 文件。

  • MySQL

    MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。MySQL 是最流行的关系型数据库管理系统之一。

    675 引用 • 535 回帖
  • 数据备份
    3 引用 • 2 回帖
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3168 引用 • 8207 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • 88250

    执行命令那里有点问题,没有读取错误流可能会导致命令进程阻塞。最好单独启一个线程来执行命令,并重定向该命令进程的错误流到输出流,命令进程还要设置执行超时防止意外情况下出现僵尸进程导致资源不释放。

    可参考这里的代码 🍇

    1 回复
  • kangaroo1122

    嗯嗯,好的,谢谢 D 大的回复,我再去研究一下你们的实现过程,再改进一下!