项目实训10——对特定数据库的备份

  一个具有使用价值的数据整理系统应该具有数据库的备份功能。数据库管理软件例如Navicat就可以很简单地备份,并且可以提取备份的sql文件存在本地。项目具有删除用户数据库之前备份和用户数据库定时备份的功能,本篇博客先来讨论删除数据库之前如何备份。
  备份数据库的命令为mysqldump -u用户名 -p密码 数据库名 > 路径\\文件名,其中mysqldump是MySQL Server的bin目录下的一个exe可执行文件,在命令行执行备份语句时要先把工作目录转到bin目录下,且密码位置省略以保证数据安全,回车后执行命令再输入密码。在Java代码中不能再用JDBC执行备份命令,可以使用Runtime.getRuntime().exec(command);调用执行cmd命令。前面我提到在命令行执行备份命令时要转到MySQL Server的bin目录,所以在Java代码中也要转到此目录下后再执行语句。可在mysqldump前加上bin目录的地址,也可在项目目录中新建一个文件夹,将mysqldump.exe复制进去。目录前还要加上cmd /c,cmd /c dir 是执行完dir命令后关闭命令窗口,不加上则命令不会执行。具体代码在serviceImpl文件中,如下所示:

    //删除之前先备份!
    @Override
    public int backupDB(int id) throws IOException {
        DB db=dbMapper.findDBById(id);
        String dbName=db.getDBEN();
        System.out.println(dbName);

        String user = "root";
        String password = "xxxxxxxx";

        logger.info("系统对将要删除的数据库备份");
        // 当前时间 年月日格式
        LocalDate localDate = LocalDate.now();
        // 备份文件名称
        String fileName = dbName+localDate.toString() + ".sql";
        String outFilePath = "D:\\backup\\"+fileName;
        String command="cmd /c D:\\mysql\\mysqldump -u" + user + " -p" + password +" "+ dbName+ " > " +outFilePath;
        Runtime.getRuntime().exec(command);

        System.out.println("备份完毕!");

        return 1;
    }

  在实现备份功能时我遇到了很多错误。

  1. mysqldump命令的执行环境必须在MySQL Server的bin目录下,还必须有cmd /c,而且命令中不能有多余的空格,“>”后的文件名要加上绝对路径,一方面出现问题就可能获得0KB的文件。
  2. 网上的许多教程都偏向于Runtime对象执行命令后存入一个Process对象,然后再将此对象以InputStream输入流的格式存入BufferedReader对象中,最后生成一个文件输出流将备份内容写入新创建的文件中。这么做不仅麻烦,而且无效,会得到一个0KB的文件。直接将命令中“>”后的文件名改为绝对路径+文件名,后缀为.sql,就可以直接得到备份内容的sql文件。
  3. 得到的备份文件缺乏表结构和表数据。解决了上述两个问题后,我得到了一个非0KB的sql文件,但是打开后只有数据库名信息和一些注释,没有数据库中的表结构和数据。我反复尝试后发现,只要在执行备份命令后进行删除数据库操作,得到的sql文件就只有注释。可能是语句执行顺序出现偏差。所以我选择改变一下逻辑,在删除数据库界面增添了一个备份按钮,可以选择先备份再删除,如果直接点击删除按钮,会提示可以先备份。这样就可以解决sql文件缺乏表结构和数据的问题了。
      经过测试,备份后的数据库可通过命令行恢复其表结构和表数据。注意要先建立同名数据库再执行命令!命令为mysql -u用户名 -p 数据库名 < 绝对路径\\文件名,同样要在bin目录下执行命令。
      controller层代码为:
    //备份数据库
    @RequestMapping("/backupDB/{id}")
    public Map<String, Object> backupDB(@PathVariable int id) throws Exception {
        Map<String, Object> map = new HashMap<>();
        //先备份!
        System.out.println("传到后端的id:"+id);
        int bu=db.backupDB(id);
        System.out.println("备份用户数据库的结果:"+bu);

        if (bu>0) {
            map.put("state", true);
            map.put("msg", "删除成功!");
        } else {
            map.put("state", false);
            map.put("msg", "删除失败!");
        }

        return map;
    }

  前端页面展示:
前端页面

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值