博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java程序使用cmd备份和恢复数据库
阅读量:6967 次
发布时间:2019-06-27

本文共 9084 字,大约阅读时间需要 30 分钟。

hot3.png

项目中需要提供程序上去备份数据库,基础代码来自网上,但是却留了个坑,好不容易才趟过去……

直接上代码:

一、备份(2018/01/03 )

/**      * 备份mysql数据库      * @param root  mysql登录名      * @param rootPass  登录密码      * @param dbName  要备份的数据库名称      * @param backupsPath  备份的路径      * @param backupsSqlFileName  备份文件的名字      * @return      */      public static String dbBackUp(String root,String rootPass,String dbName,String backupsPath,String backupsSqlFileName)      {          //生成临时备份文件  //      SimpleDateFormat sd=new SimpleDateFordckupsSqlFileName;          String pathSql = backupsPath+backupsSqlFileName;          try {              File fileSql = new File(pathSql);              if(!fileSql.exists()){                  fileSql.createNewFile();              }              StringBuffer sbs = new StringBuffer();              sbs.append(CMDPrefix+"mysqldump ");              sbs.append(" -h 127.0.0.1 ");              sbs.append(" -u ");              sbs.append(root+" ");              sbs.append("-p"+rootPass+" ");              sbs.append(dbName);              sbs.append(" --default-character-set=utf8 ");  //          sbs.append(">"+pathSql);              sbs.append(" --result-file="+pathSql);              System.out.println("cmd命令为:——>>>"+sbs.toString());              Runtime runtime = Runtime.getRuntime();              Process child = runtime.exec(sbs.toString());                            //读取备份数据并生成临时文件              InputStream in = child.getInputStream();              OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(pathSql), "utf8");              BufferedReader reader = new BufferedReader(new InputStreamReader(in, "utf8"));              String line=reader.readLine();              while (line != null) {                  writer.write(line+"\n");                  line=reader.readLine();                  System.out.println(line);             }               writer.flush();               System.out.println("数据库已备份到——>>"+pathSql);          } catch (Exception e) {                        }          return pathSql;      }

注意这里的--default-character-set=utf8设置了编码

二、恢复

出现坑的地方--default-character-set=utf8设置了编码,如果不加这一句,很有可能出现通道关闭的错误提示,另外,流的关闭顺序也要注意 

            writer.close();    

            br.close();    
            out.close();  

代码:

public static boolean load() {//还原            try {              String fPath = "e:/emaster2000DB_20180103151600.sql";                Runtime rt = Runtime.getRuntime();                        // 调用 mysql 的 cmd:                Process child = rt.exec(CMDPrefix+"mysql -uroot -ptime emaster2000 --default-character-set=utf8 ");                OutputStream out = child.getOutputStream();//控制台的输入信息作为输出流                String inStr;                StringBuffer sb = new StringBuffer("");                String outStr;                BufferedReader br = new BufferedReader(new InputStreamReader(                        new FileInputStream(fPath), "utf8"));                OutputStreamWriter writer = new OutputStreamWriter(out, "utf8");              int i=0;            while ((inStr = br.readLine()) != null) {             	sb.append(inStr+"\r\n");                System.out.println(inStr);                            }                outStr = sb.toString();                writer.write(outStr);                       // 别忘记关闭输入输出流                writer.close();                br.close();                out.close();                                System.out.println("/* Load OK! */");            } catch (Exception e) {                e.printStackTrace();            }            return true;        }

 

三、补充(2018/01/08)

    1.补充的原因:备份的方式没有问题,但是恢复的方式会有一定的问题,当备份出来的SQL文件很大时,在恢复时,由于代码是将SQL文件全部转成流发送给cmd命令窗口,这样会导致内存溢出。解决方式将SQL文件一部分一部分的写,也就是使用缓存,但是由于SQL执行的原因,个人很担心会出现SQL执行问题(本人未测试),另外一种方式是使用类似我们在cmd下执行mysql的source + SQL文件路径 这样的命令,此处选择第二种方式。

2.备份

/**	 * 备份mysql数据库	 * 	 * @param root	 *            mysql登录名	 * @param rootPass	 *            登录密码	 * @param dbName	 *            要备份的数据库名称	 * @param backupsPath	 *            备份的路径	 * @param backupsSqlFileName	 *            备份文件的名字	 * @return	 */	public static String dbBackUp(String root, String rootPass, String dbName, String host,String CMDPrefix, String backupsPath,			String backupsSqlFileName) {		  try {			Runtime rt = Runtime.getRuntime();		    Process pro = rt.exec(getBackupCommand(root, rootPass, dbName, host, CMDPrefix, backupsPath, backupsSqlFileName));		    BufferedReader br = new BufferedReader(new InputStreamReader(pro.getErrorStream()));		    String errorLine = null;		    while ((errorLine = br.readLine()) != null) {		        logger.error("####################"+errorLine+"##################");		    }		    br.close();		    int result = pro.waitFor();		    if (result != 0) {		    	logger.error("####################数据库备份失败##################");		    }		} catch (IOException e) {			logger.error("####################数据库备份失败,"+e.getMessage()+"##################");		} catch (InterruptedException e) {			logger.error("####################数据库备份失败,"+e.getMessage()+"##################");		} catch (Exception e) {			logger.error("####################数据库备份失败,"+e.getMessage()+"##################");		}		return backupsSqlFileName;	}		/**	 * 	 * (Javadoc) 	 * @Title: getBackupCommand 	 * @Description:  	 * @param @param root 数据库用户名	 * @param @param rootPass 数据库用户密码	 * @param @param dbName 数据库名称	 * @param @param host 主机好	 * @param @param CMDPrefix 命令前缀 最后需要加上\\	 * @param @param backupsPath 备份路径	 * @param @param backupsSqlFileName SQL文件名称	 * @param @return  	 * @return String[]  	 * @throws	 */	private static String[] getBackupCommand(String root, String rootPass, String dbName, String host,String CMDPrefix, String backupsPath,			String backupsSqlFileName) {		BackupsDB.CMDPrefix=CMDPrefix;	    String[] cmd = new String[3];	    String os = System.getProperties().getProperty("os.name");	    if (os.startsWith("Win")) {	        cmd[0] = "cmd.exe";	        cmd[1] = "/c";	    } else {	        cmd[0] = "/bin/sh";	        cmd[1] = "-c";	    }	    StringBuilder arg = new StringBuilder();	    arg.append(BackupsDB.CMDPrefix+"mysqldump ");	    arg.append("-u");	    arg.append(root);	    arg.append(" -p");	    arg.append(rootPass);	    arg.append(" --default-character-set=");	    arg.append(CHARSET);	  //  arg.append(" --skip-opt ");	    arg.append(" --add-drop-database ");	   // arg.append("--routines ");	    arg.append("--triggers ");	    //arg.append("--compress ");	    arg.append("-r ");	    arg.append(backupsPath);	    arg.append(backupsSqlFileName);	    arg.append(".sql ");	    arg.append("--databases ");	    arg.append(dbName);	    cmd[2] = arg.toString();	    return cmd;	}

3.恢复

/**	 * 	 * @param root	 *            数据库用户名	 * @param rootPass	 *            数据库密码	 * @param backupsPath	 *            备份文件路径	 * @param dbName	 *            数据库名	 * @return true 备份成功,false 备份失败	 */	public static boolean load(String root, String rootPass, String host,String CMDPrefix,String backupsPath, String dbName) {// 还原		//BackupsDB.CMDPrefix=CMDPrefix;				Runtime rt = Runtime.getRuntime();	    try {			Process pro = rt.exec(getLoadCommand(root, rootPass, host, CMDPrefix, backupsPath, dbName));			BufferedReader br = new BufferedReader(new InputStreamReader(pro.getErrorStream()));			String errorLine = null;			while ((errorLine = br.readLine()) != null) {			    System.out.println(errorLine);			}			br.close();			int result = pro.waitFor();			if (result != 0) {				logger.error("####################数据库恢复失败##################");				return false;			}			return true;		} catch (IOException e) {			e.printStackTrace();			logger.error("####################数据库恢复失败,"+e.getMessage()+"##################");		} catch (InterruptedException e) {			logger.error("####################数据库恢复失败,"+e.getMessage()+"##################");		} catch (Exception e) {			logger.error("####################数据库恢复失败,"+e.getMessage()+"##################");		}		return false;	}	/**	 * 	 * (Javadoc) 	 * @Title: getLoadCommand 	 * @Description:  	 * @param @param root 数据库用户名	 * @param @param rootPass 数据库密码	 * @param @param host 数据库主机好	 * @param @param CMDPrefix 命令前缀路径	 * @param @param backupsPath SQL文件路径	 * @param @param dbName 数据库名	 * @param @return  	 * @return String[]  	 * @throws	 */	private static String[] getLoadCommand(String root, String rootPass, String host,String CMDPrefix,String backupsPath, String dbName) {	    String[] cmd = new String[3];	    String os = System.getProperties().getProperty("os.name");	    if (os.startsWith("Win")) {	        cmd[0] = "cmd.exe";	        cmd[1] = "/c";	    } else {	        cmd[0] = "/bin/sh";	        cmd[1] = "-c";	    }	    StringBuilder arg = new StringBuilder();	    arg.append(BackupsDB.CMDPrefix+"mysql ");	    arg.append("-u");	    arg.append(root);	    arg.append(" -p");	    arg.append(rootPass);	    arg.append(" --default-character-set=");	    arg.append(CHARSET);	    arg.append(" ");	    arg.append(dbName);	    arg.append(" <");	    arg.append(backupsPath);	    cmd[2] = arg.toString();	    return cmd;	}

注意点:1.CMDPrefix 命令前缀路径一定是你的mysqldump和mysql的路径

            2.此处命令执行的写法是有原因的(主要指我们使用 < 这个符号,在java中没有这个定向符,cmd中是有的,所有就算拼接好的命令使用java执行和使用cmd执行是不一样的),

            3.备份和恢复,都要设置相同的字符编码

转载于:https://my.oschina.net/u/2528990/blog/1601187

你可能感兴趣的文章
洛谷 P1865 A % B Problem[筛素数/前缀和思想/区间质数个数]
查看>>
动态规划题库
查看>>
[30期] 第一个项目
查看>>
[31期] 第一个项目结束之际-->俺很高调但很真诚地感谢一个人-->涛爷
查看>>
回头再看第一次项目
查看>>
sql 50题
查看>>
Unity3D编辑器之重写Hierarchy的右键菜单
查看>>
有无关键字new的区别
查看>>
svn idea使用
查看>>
Hashmap,Set,Map,List,ArrayList的区别
查看>>
3.Linux 文件的压缩与打包
查看>>
JAVA分布式架构
查看>>
如何把使用到android res文件夹下面资源(R.xx.xx)的工程打包成jar文件,供其它项目使用...
查看>>
删除Referencing outlet
查看>>
三、hbase JavaAPI
查看>>
Maximum Subarray
查看>>
Android ProGuard使用要点
查看>>
导入自定义模块model
查看>>
Python之初识函数(Day11)
查看>>
[LeetCode] NO.383 Ransom Note
查看>>