本来想mybatis有没有实现数据库备份,然后用定时任务调用,但是更简单的方法是,利用java执行cmd,再执行mysql自己的mysqldump的命令进行备份即可。

  1. /**
  2. * 备份数据库
  3. * @param username
  4. * @param password
  5. * @param databasename
  6. * @param fileName
  7. * @throws Exception
  8. */
  9. //mysqldump -h端口号 -u用户 -p密码 数据库 > d:/test.sql --备份D盘
  10. //备份
  11. public static void dataBaseDump(String username,String password,String databasename) throws Exception {
  12. File file = new File("D:\\_Document\\fanmini\\backup");
  13. if (!file.exists()) {
  14. file.mkdir();
  15. }
  16. String fileName = databasename + "_" + DateUtils.getDate() + "_backup";
  17. File datafile = new File(file + File.separator + fileName + ".sql");
  18. if (datafile.exists()) {
  19. log.error(fileName + "文件名已存在,请更换");
  20. return;
  21. }
  22. //拼接cmd命令
  23. //此处mysqldump需要为绝对路径,环境变量这里没法识别
  24. String s = "cmd /c D:\\mysql-5.7.31-winx64\\bin\\mysqldump -hlocalhost -u" + username + " -p" + password + " --opt " + databasename + " > " + datafile;
  25. log.info("数据库备份命令:{}", s);
  26. Process exec = Runtime.getRuntime().exec(s);
  27. if (exec.waitFor() == 0) {
  28. log.info("数据库备份成功,备份路径为:" + datafile);
  29. } else {
  30. log.error("数据库备份失败,备份路径为:" + datafile + "备份命令为:" + s);
  31. }
  32. }

参考:Java程序中实现 MySQL数据库的备份与还原

问题
部署到windows服务器后执行,发现对应目录下产生空sql文件
排查后,注意到:

  • 即使已经设置好环境变量,并且手动备份成功,这里java执行仍无法识别mysqldump命令,导致空输入流被导向sql文件,sql文件为空
  • 命令-u后紧跟username,-p后紧跟password,否则命令错误

因此最后执行命令为(-hlocalhost可不写):

  1. rt.exec("cmd /c D:\\mysql-5.7.31-winx64\\bin\\mysqldump -hlocalhost -uroot -p123456 --opt databaseName > d:\\bk.sql");

其中/c意思是执行完其后的命令后关闭cmd窗口,目测一般执行cmd命令都要这么写:

  1. cmd /c dir 是执行完dir命令后关闭命令窗口。
  2. cmd /k dir 是执行完dir命令后不关闭命令窗口。
  3. cmd /c start dir 会打开一个新窗口后执行dir指令,原窗口会关闭。
  4. cmd /k start dir 会打开一个新窗口后执行dir指令,原窗口不会关闭。

定时任务