java实现mysql的备份还原

此作品是按照

     
作为一名屌丝giser的本人,刚接触gis专业是二〇〇七年的大一,好悲催,当时gis这多少个正式是被调剂的,我压根都不晓得gis为啥物,这时候gis冷门的一逼,报名这一个专业的屈指可数。记得这时候得知被调剂到那一个标准的时候,心绪失落到极点,曾一度打算舍弃就读,回去复读一年,以为gis是要到野外跑的这种,前边经过上网百度搜索gis以及查找本科高校的gis专业,才了然并不是这么一次事。本科院校把gis安排在微机大学上边,那是比较少有的,重假诺偏向gis开发方面,有点类似百度地图的电子地图之类,最近背后的庆幸,当初从不抛弃,不然就从未有过前面的点点滴滴gis经历,更不曾前日的我。从二零零七年接触gis以来,我没悟出一起的话这么多年,一向守候着gis,跟gis作伴,中间起关键效用的是读研的三年(仍然是gis专业),其中许多本科同学毕业之后倘若弄java或者C#开发,要是就是转行了,遵守gis的很少很少,毕竟二零一一年本科毕业的时候,gis依旧是那么的冷门,屌丝一枚。

  1. 搭建Jquery+SpringMVC+Spring+Hibernate+MySQL平台

     
大一大二两年都是盲目中走过,属于混日子的,应付式的考查,顺利的拿到学分就了事,学了一大推的gis基础课,都是死记硬背,比如经济地经济学(1,2),地理音信类别导论,地图学,遥感导论等等,现在自己已经忘光了,幸好还学了电脑编程C语言以及C++,让自家自己多少编程的底子,为日后学习gis开发打下了根基,即使后边做gis二次开发的时候不是用c、c++来编写的。除了电脑编程语言之外,还有就是数据结构以及数据库,这两门课程对自身的增援也挺大,尤其是对开发者来说。期间还谈了三遍婚恋,不过并从未什么样鸟用,傻乎乎的,谈了跟没谈一样,来也匆匆去也匆匆,如过客一般的存在,并不知道为啥恋爱,也就是经验过如此一回事罢了,当时也有跟风的因素在吗。

  2. jquery+springMVC实现公文上传

     
大学的契机在于大二暑假,从前虽说学习了总结机的要旨语言,不过尚未系统化的读书上机操作,更从未经过项目标实战,刚好暑假有如此一个机遇,这里我要谢谢我的好基友小黄,当时要不是没有她的积极向上向导师提议我,让我跟他一块参预导师的体系来说,我也没有机会进来。小黄也是gis的,他编程能力特强,在业内是非凡的,我的gis编程之路就是在他的引路下,渐渐的入门,逐步的熟练起来的。记得及时非常项目是按照遥感印象内容的物色,属于遥感影象识另外,简单的来说就是以一幅影象来匹配印象库相似度的前20的影象图,我们落实的是依照二种方法来探寻,分别是基于文本、基于印象的纹理特征值以及基于印象的形状搜索。其中,我肩负相比较简单的遵照文本和基于影象的纹理特征值,小黄负责的是复杂度较高的依据影象形状特征检索。那一套是用C++来实现,用到MFC,当时觉的用MFC形式设计界面形式好便宜,初学者都是爱好这种拖拉控件布局界面吧,虽说我实现的职能,相对来说蛮简单的,不过对登时的自己来说,也折腾的很久,不断的请教小黄,还有就是积极的上网物色资源,百度搜索,csdn,这时候不清楚有新浪,是小黄推荐csdn。我在csdn论坛里面问了很多题材,里面的大神回答的也挺积极的,从中,我找到了化解问题的方案依然思路,真的挺管用的。

 

     
这些暑假真忙,中地MapGIS来到我们高校培训MapGIS开发,培训学生出席他们组办的MapGIS大赛,当时又是小黄,拉我,还有两位同学合伙创造一个社团参与培训。这是首先次接触C#和.Net,MapGIS的塑造内容就是。net平台,开发语言是C#
的二次开发,MapGIS是自家接触的首先个GIS软件,当时觉的装置MapGIS好劳顿,安装时候360是要禁用的,不然安装不上,还有就是我们不得不用学习版本,试用期是一个月,满期之后要重复注册,当时也没想那么多,而且觉的。net平台设计界面真的好便宜,培训用的是windowform,间接就是简单拖拉来布局界面,当时搭建的界面真的不敢恭维。本次的MapGIS培训接触的学识,一切都是那么的陌生,幸好当时有个队长指点大家,也正是当时的公司氛围够自己,一起交换座谈,一起化解技术难题。当时的我们是何其的GIS菜鸟,现在回想起来又想笑又觉的好囧,记得我们立马公司加盟到一个mapgis群里,培训时候他俩给的,刚最先大家许多的都不懂mapgis,也没怎么经验,境遇不懂的,直接跑去群里问,不论mapgis软件仍旧gis编程问题,比如地图加载出不来,图层间接报错为空对象,甚至刚开首连断点跟踪都不会,不知情程序哪步出错了,唉,问的多了,群里的他俩都厌倦了咱们,说怎么不去百度先找找一下,咋的咋的……可是大家依旧渐渐的入门了,懂的了vs软件的调式,断点跟踪,排错,也清楚了,遭受题目,先仔细分析,利用网络资源搜索,实在非凡再到群里请教,逐步的也知根知底了mapgis
api的调用。经过这一次培训的积攒以及我们公司的全力,在前面的mapgis全国大赛,我们组拿到了高级开发组二等奖,作品的主旨是学校地理音讯连串平台,哈哈,当时我们的团社团还很小风光了一把,学校挂起了横幅,还让老大我们去给GIS的师弟师妹做讲座,传授我们的心体面会以及学习GIS开发的措施。

一. 简介

     
让自己想不到的是,自从进入大三的话,我几乎都没用过C++,一向到前天,这点相比遗憾,大三到研三,都是在跟C#以及。net平台打交道了。自从出席MapGIS大赛之后,自己的编程能力得到进一步的升官,对MapGIS软件以及软件的采纳有早晚的垂询和左右,本认为自己会一贯做mapgis二次开发,不过一回的偶尔机会,接触了arcgis之后,竟然前面与mapgis越行越远,后边一直绝缘了,转向arcgis。这是一位研三的师兄的毕业设计,他协调忙可是来,然后请我们还原匡助,顺便教我们,携带我们做她的毕业设计,这一点我非凡感激他,那么的耐性的指引我们。师兄的毕业设计主题室关于地震紧急疏散路径的探究,里面的算法是他协调弄的,GIS基本效用交给我们来促成,但是正如好的是他自己先搭建好了系统的框架,基于arcgis
for
silverlight的webgis,当时师兄还努力的引荐大家去读书silverlight,还真别说,当时2010时候,silverlight挺火的,什么人知道前面几年它夭折了,唉,说起来就是坑啊,害自己后边几年阅读一贯都是做arcgis
for
silverlight。不过当下着实是被silverlight做的界面吸引到了,做的那么炫酷,动态效果,还有就是webgis这种形式,bs的,不是前面mapgis学的cs情势。通过师兄的毕业设计,自己学会了安装arcgis
desktop以及arcgis
server,这时候是9.3.1本子,安装arcgis环境还挺勤奋的,尤其是新手,不像现在安装这么简单了。学会了arcgis
api for
silverlight的地形图基本功用以及一些简练的gis分析,比如地图缩放,属性查询,空间查询,buffer分析以及最短路径分析等等。这一年也有六个gis专业的开支教程,关于webgis和arcgis
engine的,当时webgis有flex方向以及js方向,后悔没选取js的。通过arcgis
engine的学科,自己用vs2008开发工具操练搭建了一个简易的arcgis
engine桌面系统,实现了一部分简便的地图开发效益,相比较的拖沓控件布局界面。全体而言,大二暑假和大三这段时日过的比较充实。

  备份和导入是一个互逆的进程。 
  备份:程序调用mysql的备份命令,读出控制台输入流音讯,写入.sql文件; 
  导入:程序调用mysql的导入命令,把从.sql文件中读出的信息写入控制台的输出流 
  在意:用Java执行,每趟只可以执行一条command命令,重定向符”>”和”<“是不可能用的

     
进入大四的自己,面临找工作或者考研的挑三拣四,当时没悟出有保研的名额,结果大于我意料之外,争取到一名保研GIS的名额,在这以前自己也面试了几家GIS的信用社,比如维也纳奥格,圣地亚哥诚信所,都市圈,当时结果不太好听,当时众多同室都转行了,或者是做总括机编程,比如前边提到的小黄,有些女子做gis应用的,显而易见做gis开发的相比少。综合考虑了一下,仍旧采纳保研继续求学去了,延续自己的GIS旅途……大四的这一年,没有课程可学,不是找工作就是编制毕业杂文的准备,其中还帮师妹师弟指导一下他们的gis技术问题,他们的gis课程设计需要拔取,哈哈,记得及时有个师妹貌似特别敬佩我一般,通常找我解决问题,时不时邀请自己联合进餐的,有时候去散散步什么的,感觉高校生活都是那么的光明,出来工作才察觉,唉!

 

     
就如此的渡过了我的四年gis生活,没有多大的心胸,没有多大的精良和期待,一切都是的那么的平庸,等待进入学士的gis生活……

二. 相关程序代码介绍

      

  1. BackupRestoreBSImpl.java

图片 1图片 2

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;
    }
}

View Code

  2. DataBaseBSImpl.java,可设置要备份的数据库名称,如:sys

图片 3图片 4

package com.ims.service.sys.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ims.persistence.base.SqlXmlParser;
import com.ims.persistence.dao.sys.DataBaseDao;
import com.ims.service.sys.DataBaseBS;

@Service("dataBaseBS")
public class DataBaseBSImpl implements DataBaseBS{
    private static final String sqlXml = "sys/dataBase.xml";
    private static final String[] dataBases = new String[]{"sys"};

    @Autowired
    private DataBaseDao dataBaseDao;

    @Override
    public String getInstallPath() {        
        String installPath = (String)dataBaseDao.findUniqueResultBySql(new SqlXmlParser(sqlXml).parse("installPath", null));
        return installPath;
    }

    @Override
    public String[] getDataBases() {
        return dataBases;
    }
}

View Code

  3. TestController.java

图片 5图片 6

package com.ims.web.controller;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSON;
import com.ims.common.FileUtil;
import com.ims.service.sys.BackupRestoreBS;

@Controller
@RequestMapping("test")
public class TestController extends BaseController{
    @Autowired
    private BackupRestoreBS backupRestoreBS;

    @RequestMapping("view")
    public ModelAndView test(){
        ModelAndView view = new ModelAndView("test.jsp");
        return view;
    }

    @RequestMapping("backupRestore!backup")
    public void backup(){
        Map<String, Object> result = backupRestoreBS.backupAll();            
        ajaxJson((Boolean)result.get("status")?STATUS_SUCCESS:STATUS_ERROR, result.get("msg"));
    }

    @RequestMapping("backupRestore!download")
    public void download(@RequestParam Map<String, Object> params){
        InputStream in=null;  
        OutputStream out=null; 
        String fileName = (String)params.get("fileName");
        try{
            response.setContentType("application/x-download;charset=GBK");
            response.setHeader("Content-Disposition", "attachment;filename="+new String(fileName.getBytes("GBK"),"ISO8859_1"));  
            out=response.getOutputStream();  
            //将内容写入输出流并把缓存的内容全部发出去  
            in=new BufferedInputStream(new FileInputStream(backupRestoreBS.getUploadpath()+fileName));   
            int len = 0;  
            byte[] buffer = new byte[1024];                
            while((len = in.read(buffer)) > 0) {  
                out.write(buffer,0,len);  
            }                  
            out.flush();  
        }catch(Exception e){
            ajaxJson(STATUS_ERROR, "文件下载失败");
        }finally{
            if(in!=null){
                try{                
                    in.close();
                }catch(IOException e){
                    ajaxJson(STATUS_ERROR, "输入流关闭失败");
                }
            }

            if(out!=null){
                try{
                    out.close();
                }catch(IOException e){
                    ajaxJson(STATUS_ERROR, "输出流关闭失败");
                }
            }                        
        }
    }

    @RequestMapping("backupRestore!restore")
    public void restore(@RequestParam Map<String, String> params,
            MultipartHttpServletRequest multipartRequest){
        Map<String, Object> result = new HashMap<String, Object>();
        try {
            if(FileUtil.deleteAll(backupRestoreBS.getUploadpath())){
                MultipartFile restoreFile = multipartRequest.getFile("restoreFile");
                String fileName = restoreFile.getOriginalFilename();
                if(FileUtil.saveFileFromInputStream(restoreFile.getInputStream(), 
                        backupRestoreBS.getUploadpath()+fileName)){
                    Map<String, Object> restoreResult = backupRestoreBS.restoreAll(fileName);
                    result.put("status", STATUS_SUCCESS);
                    result.put("message", restoreResult.get("msg"));                            
                }else{
                    result.put("status", STATUS_ERROR);
                    result.put("message", "文件保存失败");
                }
            }else{
                result.put("status", STATUS_ERROR);
                result.put("message", "文件夹清空失败");
            }            
        } catch (IOException e) {
            result.put("status", STATUS_ERROR);
            result.put("message", "数据还原失败");
        }    
        ajax(JSON.toJSONString(result),"text/html");    
    }
}

View Code

 

  4. backupRestore.jsp

图片 7图片 8

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
 <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>测试</title>
    <%@ include file="/common/basePath.jsp"%>
 </head>
 <body>
 ~~~~~~~~~~~~~~~~~~~~~~mysql数据库的备份与还原~~~~~~~~~~~~~~~~~~~~~~~~
 <br><br>
   数据备份:<button type="button" onclick="backup();">备份</button>
 <br><br>
   数据选择:<input type="file" id="restoreFile" style="width: 350px;"/>
 <br><br>
   导入还原:<button type="button" onclick="restore();">还原</button>
 <br><br><br>
 <script type="text/javascript" src="content/js/jquery/jquery-1.8.1.min.js"></script>
 <script type="text/javascript" src="content/js/core/utils.js"></script>
 <script type="text/javascript" src="content/js/core/common.js"></script>
 <script type="text/javascript" src="content/js/jquery-plugin/fileUpload/jquery.ajaxFileUpload.js"></script>
 <script type="text/javascript">

    function backup(){
        $.ajax({
            async:true,
            url: rootPath+"/test/backupRestore!backup.do",
            success: function (d) {    
                if(d.status=='success'){            
                    var exporter = com.exporter();
                    exporter.params.action = rootPath+"/test/backupRestore!download.do?fileName="+d.message;
                    exporter.download('zip');
                    alert("备份成功!"); 
                } else { 
                    alert(d.message);
                }
            }
        });
    }

    function restore() {
        $.ajaxFileUpload({  
            url:rootPath+"/test/backupRestore!restore.do",
            secureuri:false,
            fileElementId: ['restoreFile'], 
            dataType: 'json',
            success: function (data){  
                if(data.status=='success'){  
                    alert('还原成功!');  
                } else {
                    alert(data.message);  
                }                          
            },
            error: function(data){
            }
        });          
    }
 </script>
 </body>
</html>

View Code

三. 测试

  访问:http://localhost:8080/ims/test/backupRestore.do

图片 9

  1. 备份:点击 备份
按钮,浏览器会下载压缩后的备份文件,格式如:2017-03-16_backup.zip

  2. 回升:采纳刚下载的回落后的备份文件,点击 还原
按钮,数据库被成功还原