今天给项目加了个数据库自动备份功能,免得以后都要用工具手动备份挺麻烦的。没用做过相关的,于是上网找下这种的一些解决方案,发现大都大同小异,都是使用Runtime.getRuntime().exec(command),参数传入的是mysql的备份命令,用的是mysql自带的mysqldump.exe执行命令,那么就随便粘了网上的现成做起来,虽然是照这做的,不过过程还是遇到一些问题,所以还是做了一些修改。
这是网上的现成备份代码,用的是定时器备份,这里我只是放了主要的代码,关于定时器的使用请自行百度。
- package cn.edu.pzxx.scampus.utils;
- import java.io.IOException;
- import java.io.InputStream;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import java.util.Properties;
- import java.util.TimerTask;
- public class MySqlExport extends TimerTask{
- @Override
- public void run() {
- //获取当前系统时间
- SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd_HHmmss");
- String date=df.format(new Date());
- try {
- export(getProperties(),date);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- public static void export(Properties properties,String date) throws IOException {
- Runtime runtime = Runtime.getRuntime();
- String command = getExportCommand(properties,date);
- runtime.exec(command);
- }
- private static String getExportCommand(Properties properties,String date) {
- StringBuffer command = new StringBuffer();
- String username = properties.getProperty("jdbc.username");//用户名
- String password = properties.getProperty("jdbc.password");//用户密码
- String exportDatabaseName = properties.getProperty("jdbc.exportDatabaseName");//需要导出的数据库名
- String host = properties.getProperty("jdbc.host");//从哪个主机导出数据库,如果没有指定这个值,则默认取localhost
- String port = properties.getProperty("jdbc.port");//使用的端口号
- String exportPath = properties.getProperty("jdbc.exportPath")+date+"_"+properties.getProperty("jdbc.exportDatabaseName")+".sql";//导出路径
- //这里如果想直接使用mysqldump的话需要在环境变量path下配mysql的bin目录的路径,不然的话就得用绝对路径
- command.append("mysqldump -u").append(username).append(" -p").append(password)//密码是用的小p,而端口是用的大P。
- .append(" -h").append(host).append(" -P").append(port).append(" ").append(exportDatabaseName).append(" -r ").append(exportPath);
- return command.toString();
- }
- public static Properties getProperties(){
- try {
- InputStream is = MySqlImportAndExport.class.getClassLoader().getResourceAsStream("jdbc.properties");
- Properties properties = new Properties();
- properties.load(is);
- return properties;
- } catch (IOException e) {
- e.printStackTrace();
- return null;
- }
- }
- }
- jdbc.username=root
- jdbc.password=root
- jdbc.host=localhost
- jdbc.port=3306
- jdbc.exportDatabaseName=test
- jdbc.exportPath=D\:\\apache-tomcat-8.0.9-windows-x64\\apache-tomcat-8.0.9\\webapps\\pzxxsc\\exportdatabase\\
- jdbc.importDatabaseName=test
- #jdbc.importPath=D\:\\ex8136.sql
这里的代码本身是没有什么问题的,我在myeclipse下调式也是成功可以备份的。但是问题来了,如果通过手动去启动tomcat,执行备份功能竟然会出现错误
这就奇怪了,同样的代码为什么在myeclipse就没问题,手动去启动tomcat就出问题了,难道跟进程间的调用有关系,只是猜测,,无奈之下我只能试试其他数据库的备份命令,后面综合了好几个答案的命令才得出一个真正用的上的命令。修改下命令的拼接代码。
- command.append("cmd /c ").append(mysqldumpPath).append(" -u").append(username).append(" -p").append(password)//密码是用的小p,而端口是用的大P。
- .append(" -h").append(host).append(" -P").append(port).append(" --opt ").append(exportDatabaseName).append(">").append(exportPath);
但是事情还没有完全结束。虽然可以备份出来文件了,但是为什么打开文件,里面竟然是空白的。于是又的上网找答案,看到一前辈也遇到这问题,http://www.cnblogs.com/aDust/archive/2012/10/19/mysqldump.html,大概问题是mysqldump在我安装的Program Files,带有空格导致的,于是果断将mysqldump移到其他地方去了,备份也成功了,这事也算告一段落。
贴出修改后的代码:
- package cn.edu.pzxx.scampus.utils;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.UnsupportedEncodingException;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import java.util.Properties;
- import java.util.TimerTask;
- public class MySqlExport extends TimerTask{
- @Override
- public void run() {
- //获取当前系统时间
- SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd_HHmmss");
- String date=df.format(new Date());
- try {
- export(getProperties(),date);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- public static void export(Properties properties,String date) throws IOException {
- Runtime runtime = Runtime.getRuntime();
- String command = getExportCommand(properties,date);
- runtime.exec(command);
- }
- private static String getExportCommand(Properties properties,String date) {
- StringBuffer command = new StringBuffer();
- String username = properties.getProperty("jdbc.username");//用户名
- String password = properties.getProperty("jdbc.password");//用户密码
- String exportDatabaseName = properties.getProperty("jdbc.exportDatabaseName");//需要导出的数据库名
- String host = properties.getProperty("jdbc.host");//从哪个主机导出数据库,如果没有指定这个值,则默认取localhost
- String port = properties.getProperty("jdbc.port");//使用的端口号
- String exportPath = properties.getProperty("jdbc.exportPath")+date+"_"+properties.getProperty("jdbc.exportDatabaseName")+".sql";//导出路径
- System.out.println(exportPath);
- /*try {
- exportPath=new String(exportPath.getBytes("ISO-8859-1"),"GBK");
- } catch (UnsupportedEncodingException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- System.out.println(exportPath);*/
- String mysqldumpPath=properties.getProperty("jdbc.mysqldumpPath");
- //在tomcat启动运行web应用需要用到这个
- command.append("cmd /c ")
- //mysqldump的路径,这里最好用mysqldump的绝对路径
- .append(mysqldumpPath)
- //密码是用的小p,而端口是用的大P。
- .append(" -u").append(username).append(" -p").append(password)
- //地址端口
- .append(" -h").append(host).append(" -P").append(port)
- /*
- * 这只是一个快捷选项,等同于同时添加
- * --add-drop-table,--add-locks,--create-options,--quick,--extended-insert,
- * --lock-tables,--set-charset,--disable-keys选项。
- * 本选项能让 mysqldump 很快的导出数据,并且导出的数据能很快导回。
- * 该选项默认开启,但可以用 --skip-opt 禁用。
- */
- .append(" --opt ")
- //该选项在导出大表时很有用,它强制 mysqldump 从服务器查询取得记录直接输出而不是取得所有记录后将它们缓存到内存中
- .append("-q ")
- //
- //sbu.append("--lock-all-tables=true ");
- //
- //sbu.append("--complete-insert=false ");
- //每条记录对应一个insert语句
- .append("--extended-insert=false ")
- //定位文件路径
- .append("--result-file=")
- //导出路径
- .append(exportPath)
- //编码方式
- .append(" ").append("--default-character-set=utf8 ")
- //数据库名
- .append(" ").append(exportDatabaseName);
- //导出单个表使用
- //.append(" ").append("hr_teacher");
- System.out.println(command.toString());
- return command.toString();
- }
- public static Properties getProperties(){
- try {
- InputStream is = MySqlImportAndExport.class.getClassLoader().getResourceAsStream("jdbc.properties");
- Properties properties = new Properties();
- properties.load(is);
- return properties;
- } catch (IOException e) {
- e.printStackTrace();
- return null;
- }
- }
- }
这里感谢这两位作者的文章给予了很大的帮助
http://cnhnslhs-163-com.iteye.com/blog/1774508
http://www.wyzc.com/forum/87741.html?tg=LXUK--Zkf
- jdbc.username=root
- jdbc.password=root
- jdbc.host=localhost
- jdbc.port=3306
- jdbc.exportDatabaseName=test
- jdbc.exportPath=D\:\\apache-tomcat-8.0.9-windows-x64\\apache-tomcat-8.0.9\\webapps\\pzxxsc\\exportdatabase\\
- jdbc.importDatabaseName=test
- jdbc.mysqldumpPath=D\:\\apache-tomcat-8.0.9-windows-x64\\mysqldump
- #jdbc.importPath=D\:\\ex8136.sql