java实现mysql的备份和还原

package com.ims.service.sys.impl;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ims.service.sys.DataBaseBS;
import com.ims.common.DateUtil;
import com.ims.common.FileUtil;
import com.ims.service.sys.BackupRestoreBS;

@Service("backupRestoreBS")
public class BackupRestoreBSImpl implements BackupRestoreBS{
    private static Log logger = LogFactory.getLog(BackupRestoreBSImpl.class);
    
    private static final String uploadPath = System.getProperty("webapp.root")+"uploadFile\\backupRestore\\";
    
    @Autowired
    public DataBaseBS dataBaseBS;
    
    /**
     * 备份单个数据库
     * @param dbName 数据库名称
     * @return 备份成功或者失败
     */
    @Override
    public boolean backup(String dbName){    
        InputStream in = null;
        InputStreamReader inReader = null;
        BufferedReader br = null;
        OutputStreamWriter writer = null;
        FileOutputStream fout = null;
    
        try {
            logger.info(dbName + "开始备份!");
            // mysqldump的安装路径,支持带空格
            String cmd = "\"\" \""+dataBaseBS.getInstallPath() +"bin\\mysqldump\" -hlocalhost -uroot -p123456 " + dbName;
            // cmd命令在后台执行,没有命令窗口出现或者一闪而过的情况
            Process process = Runtime.getRuntime().exec("cmd /c start /b " + cmd);
            // 把进程执行中的控制台输出信息写入.sql文件,即生成了备份文件。
            // 注:如果不对控制台信息进行读出,则会导致进程堵塞无法运行   
            in = process.getInputStream();// 控制台的输出信息作为输入流                             
            inReader = new InputStreamReader(in, "utf8");// 设置输出流编码为utf8。这里必须是utf8,否则从流中读入的是乱码   
               
            String inStr;   
            StringBuffer sb = new StringBuffer("");   
            String outStr;   
            // 组合控制台输出信息字符串   
            br = new BufferedReader(inReader);   
            while ((inStr = br.readLine()) != null) {   
                sb.append(inStr + "\r\n");   
            }   
            outStr = sb.toString();   
               
            // 要用来做导入用的sql目标文件:   
            fout = new FileOutputStream(uploadPath + dbName + ".sql");   
            writer = new OutputStreamWriter(fout, "utf8");   
            writer.write(outStr);   
            // 注:这里如果用缓冲方式写入文件的话,会导致中文乱码,用flush()方法则可以避免   
            writer.flush();   
             
        } catch (Exception e) {   
            logger.error(dbName + "备份失败!",e);
            return false;   
        } finally{
            // 别忘记关闭输入输出流   
            try {
                in.close();
                inReader.close();   
                br.close();   
                writer.close();   
                fout.close(); 
            } catch (Exception e) {
                logger.error(dbName + "备份失败!",e);
                return false;   
            }              
        }
        logger.info(dbName + "备份成功!");
        return true;
    }
    
    /**
     * 备份所有的数据库
     */
    @Override
    public Map<String, Object> backupAll(){
        Map<String, Object> result = new HashMap<String, Object>();
        String[] dataBases = dataBaseBS.getDataBases();    
        if(FileUtil.deleteAll(uploadPath)){
            File[] srcfile = new File[dataBases.length];
            for(int i=0;i<dataBases.length;i++){            
                if(backup(dataBases[i])){
                    srcfile[i] = new File(uploadPath+dataBases[i]+".sql");
                }else{
                    result.put("status", false);
                    result.put("msg", dataBases[i] + "数据备份失败");
                    return result;                    
                }
            }
            String filename = DateUtil.getCurrDate() + "_backup.zip";
            File zipfile = new File(uploadPath + filename);
            if(FileUtil.zip(srcfile, zipfile)){
                result.put("status", true);
                result.put("msg", filename);
            }else{
                result.put("status", false);
                result.put("msg", "文件压缩失败");                
            }            
        }else{
            result.put("status", false);
            result.put("msg", "文件夹清空失败");
        }
        return result;
    }
    
    /**
     * 还原单个数据库
     * @param dbName 数据库名称
     * @return 还原成功或者失败
     */
    @Override
    public boolean restore(String dbName){
        OutputStream out = null;
        BufferedReader br = null;
        OutputStreamWriter writer = null;
        
        try {
            logger.info(dbName + "开始还原!");
            // mysql的安装路径,支持带空格
            String cmd = "\"\" \""+dataBaseBS.getInstallPath() +"bin\\mysql\" -hlocalhost -uroot -p123456 " + dbName;
            // cmd命令在后台执行,没有命令窗口出现或者一闪而过的情况
            Process process = Runtime.getRuntime().exec("cmd /c start /b " + cmd);  
            out = process.getOutputStream();//控制台的输入信息作为输出流   
            String inStr;   
            StringBuffer sb = new StringBuffer("");   
            String outStr;   
            br = new BufferedReader(new InputStreamReader(   
                    new FileInputStream(uploadPath + dbName + ".sql"), "utf8"));   
            while ((inStr = br.readLine()) != null) {   
                sb.append(inStr + "\r\n");   
            }   
            outStr = sb.toString();   
   
            writer = new OutputStreamWriter(out, "utf8");   
            writer.write(outStr);   
            // 注:这里如果用缓冲方式写入文件的话,会导致中文乱码,用flush()方法则可以避免   
            writer.flush();   
        } catch (Exception e) {
            logger.error(dbName + "还原失败!",e);
            return false;
        } finally {
            // 别忘记关闭输入输出流                
            try {
                out.close();
                br.close();
                writer.close();   
            } catch (IOException e) {
                logger.error(dbName + "还原失败!",e);
                return false;
            }              
        }
        logger.info(dbName + "还原成功!");
        return true;
    }
    
    /**
     * 还原所有的数据库
     */
    @Override
    public Map<String, Object> restoreAll(String zipFile){
        Map<String, Object> result = new HashMap<String, Object>();
        String[] dataBases = dataBaseBS.getDataBases();
        if(zipFile.length()>0&&checkFile(zipFile)){
            if(FileUtil.unZip(new File(uploadPath+zipFile), uploadPath)){
                for(int i=0;i<dataBases.length;i++){
                    if(!restore(dataBases[i])){                        
                        result.put("status", false);
                        result.put("msg", dataBases[i] + "数据还原失败");
                        return result;                    
                    }
                }
                System.gc();// 强制回收内存垃圾,否则zip文件一直被占用删除不了
                result.put("status", true);
                result.put("msg", "数据还原成功");
            }else{
                result.put("status", false);
                result.put("msg", "解压缩包失败");
            }
        }else{
            result.put("status", false);
            result.put("msg", "没有找到可还原的数据压缩文件");
        }
        return result;
    }
    
    /**
     * 根据文件名验证文件是否合法
     * @param fileName
     * @return
     */
    public boolean checkFile(String fileName){
        String[] strs = fileName.split("_");
        if(strs.length>1){
            String checkStr = strs[strs.length-1];
            if("backup.zip".equals(checkStr)){
                return true;
            }else{
                return false;
            }
        }else{
            return false;
        }
    }
    
    @Override
    public String getUploadpath() {
        return uploadPath;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值