此文章是基於javascript
1. 搭建Jquery+SpringMVC+Spring+Hibernate+MySQL平臺html
2. jquery+springMVC實現文件上傳java
一. 簡介mysql
備份和導入是一個互逆的過程。
備份:程序調用mysql的備份命令,讀出控制檯輸入流信息,寫入.sql文件;
導入:程序調用mysql的導入命令,把從.sql文件中讀出的信息寫入控制檯的輸出流
注意:用Java執行,每次只能執行一條command命令,重定向符">"和"<"是不能用的jquery
二. 相關程序代碼介紹web
1. BackupRestoreBSImpl.javaajax
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; } }
2. DataBaseBSImpl.java,可設置要備份的數據庫名稱,如:sysspring
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; } }
3. TestController.javasql
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"); } }
4. backupRestore.jsp數據庫
<!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>
三. 測試
訪問:http://localhost:8080/ims/test/backupRestore.do
1. 備份:點擊 備份 按鈕,瀏覽器會下載壓縮後的備份文件,格式如:2017-03-16_backup.zip
2. 還原:選擇剛下載的壓縮後的備份文件,點擊 還原 按鈕,數據庫被成功還原