前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >java实现定时备份/手动备份还原mysql数据库

java实现定时备份/手动备份还原mysql数据库

作者头像
洋仔聊编程
发布2019-01-15 16:45:35
6.2K2
发布2019-01-15 16:45:35
举报

定时备份与还原

  • 简介:配置一个时间监听器,通过util中的日期类和定时器控件解析相关的时间数据,在相应的时间调用备份数据库的方法. 备份数据库的方法使用了mysql自带的mysqldump进行备份,得到数据库的sql文件,完成备份. 下面是具体的实现
  • 首先,相关配置文件,放在文件类路径下 (dbBackUpRecover.properties)
代码语言:javascript
复制
#smysql备份功能路径与数据库用户名和密码
#//usr//bin 为mysql服务bin目录的地址  -u后为用户名 -p后为密码  最后一个字符串为需要备份的数据库名称
sqlurl = //usr//bin//mysqldump -uroot -plyy504677 dk_qj_db
#备份的sql保存路径  注意:必须手动在服务器相应文件夹下创建文件夹:LeaveDatabase   
path = //usr//LeaveDatabase//dkxy_db-.sql
#备份相隔时间24 * 60 * 60 * 1000=86400000  此为一天时间
distancetime = 1296000000    #15天备份一次
#备份的具体的时间
backuptime = 2:30:00     #造成两点半备份一次
  • 得到配置文件中相应数据的读取文件类 (GetProperties.java)
代码语言:javascript
复制
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public abstract class   GetProperties {

    private static  String sqlurl = "";
    private static  String path = "";
    private static long distancetime = 0;
    private static  String backuptime = "";

    static {
        /**通过这个方法只能读取类路径下的properties文件*/
        Properties properties = new Properties();
        // 使用ClassLoader加载properties配置文件生成对应的输入流
        InputStream in = GetProperties.class.getClassLoader().getResourceAsStream("dbBackUpRecover.properties");
        // 使用properties对象加载输入流
        try {
            properties.load(in);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //获取key对应的value值
        sqlurl = properties.getProperty("sqlurl");
        path = properties.getProperty("path");
        distancetime = Long.parseLong(properties.getProperty("distancetime"));
        backuptime = properties.getProperty("backuptime");
    }

    public static String getSqlurl() {
        return sqlurl;
    }

    public static void setSqlurl(String sqlurl) {
        GetProperties.sqlurl = sqlurl;
    }

    public static String getPath() {
        return path;
    }

    public static void setPath(String path) {
        GetProperties.path = path;
    }

    public static long getDistancetime() {
        return distancetime;
    }

    public static void setDistancetime(long distancetime) {
        GetProperties.distancetime = distancetime;
    }

    public static String getBackuptime() {
        return backuptime;
    }

    public static void setBackuptime(String backuptime) {
        GetProperties.backuptime = backuptime;
    }
}
  • 定时时间的详细设置,调用util包中的日历,启动定时器控件(TimerManager.java)
代码语言:javascript
复制
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;

/**
 * 定时时间详细设置
 */
public class TimerManager {

    //时间间隔 1天时间
    private static final long PERIOD_DAY = GetProperties.getDistancetime();

    //构造函数进行
    public TimerManager() throws IOException {
        //获取并处理配置文件中的时间
        /**备份的确切时间*/
        String backuptime=GetProperties.getBackuptime();

        String[] time=backuptime.split(":");
        int hours=Integer.parseInt(time[0]);
        int minute=Integer.parseInt(time[1]);
        int second=Integer.parseInt(time[2]);

        //调用util包中的日历,设置时间
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY,hours);
        calendar.set(Calendar.MINUTE, minute);
        calendar.set(Calendar.SECOND, second);

        Date date=calendar.getTime(); //第一次执行定时任务的时间

        //如果第一次执行定时任务的时间 小于 当前的时间
        //此时要在 第一次执行定时任务的时间 加一天,以便此任务在下个时间点执行。如果不加一天,任务会立即执行。
        if (date.before(new Date())) {
            date = this.addDay(date, 1);
        }

        //启动定时器控件
        Timer timer = new Timer();

        OperationTimer task = new OperationTimer();
        //安排指定的任务在指定的时间开始进行重复的固定延迟执行。
        timer.schedule(task,date,PERIOD_DAY);
    }

    // 增加或减少天数
    public Date addDay(Date date, int num) {
        Calendar startDT = Calendar.getInstance();
        startDT.setTime(date);
        startDT.add(Calendar.DAY_OF_MONTH, num);
        return startDT.getTime();
    }
}
  • 时间监听器,用于启动定时备份数据库操作 (OperationListener.java)
代码语言:javascript
复制
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.io.IOException;

/**
 * 时间监听器,用于定时备份数据库
 */
public class OperationListener implements ServletContextListener {

    public void contextInitialized(ServletContextEvent servletContextEvent) {

        try {
            new TimerManager();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void contextDestroyed(ServletContextEvent servletContextEvent) {

    }
}
  • 设置执行内容类 (OperationTimer.java)
代码语言:javascript
复制
import java.io.IOException;
import java.util.TimerTask;

public class OperationTimer extends TimerTask {
    /**
     * The action to be performed by this timer task.
     */
    //所要执行内容
    public void run() {
        try {
            new DatabaseBackUpRecoverTime();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 定时备份数据库的实际操作类 (DatabaseBackUpRecoverTime)
代码语言:javascript
复制
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;

import static com.qihang.util.TableConstants.sqlNum;


/**
 * 定时备份数据库
 */

public class DatabaseBackUpRecoverTime {

    //读取配置文件中的信息
    //MySql的安装bin目录路径和dump等参数
    static String sqlurl=GetProperties.getSqlurl();
    //保存备份文件的路径及名称
    static String path=GetProperties.getPath();

    public DatabaseBackUpRecoverTime() throws IOException {
        backup(); // 备份数据库
        System.out.println("备份数据库成功!");
    }

    public static void backup(){
        try {
            //返回与当前的Java应用程序的运行时对象
            Runtime rt =Runtime.getRuntime();
            // 调用 调用mysql的安装目录的命令
            Process child = rt.exec(sqlurl);
            // 设置导出编码为utf-8。这里必须是utf-8
            // 把进程执行中的控制台输出信息写入.sql文件,即生成了备份文件。注:如果不对控制台信息进行读出,则会导致进程堵塞无法运行
            InputStream in = child.getInputStream();// 控制台的输出信息作为输入流
            InputStreamReader xx = new InputStreamReader(in, "utf-8");
            // 设置输出流编码为utf-8。这里必须是utf-8,否则从流中读入的是乱码
            String inStr;
            StringBuffer sb = new StringBuffer("");
            String outStr;
            // 组合控制台输出信息字符串
            BufferedReader br = new BufferedReader(xx);
            while ((inStr = br.readLine()) != null) {
                sb.append(inStr + "\r\n");
            }
            outStr = sb.toString();
            // 要用来做导入用的sql目标文件:
            Date date = new Date();
            SimpleDateFormat f = new SimpleDateFormat("MM-dd");
            //注意:sqlNum为一个自定义工具类中的static类型的Date变量,自己设置即可
            sqlNum = f.format(date);
            path = path.split("-")[0]+"-"+sqlNum+".sql";
            FileOutputStream fout = new FileOutputStream(path);
            OutputStreamWriter writer = new OutputStreamWriter(fout, "utf-8");
            writer.write(outStr);
            writer.flush();
            in.close();
            xx.close();
            br.close();
            writer.close();
            fout.close();
            System.out.println("");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
  • 在web.xml中配置监听器
代码语言:javascript
复制
<!--配置定时备份数据库的监听器-->
  <listener>
    <listener-class>
      com.qihang.controller.databaseBackUpRecover.OperationListener
    </listener-class>
  </listener>
  • 若想在本模块添加手动还原数据库的方法,参考下一个模块即可
  • 该代码已在项目中通过测试,有什么问题,评论该博客即可

手动备份与还原数据库

  • 因为做的项目中使用的是定时的备份,所以手动的备份只是测试了一下,并没有进行相关细节的完善,如果想使用本模块,对应定时备份的实现修改即可
  • 具体实现类
代码语言:javascript
复制
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

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;

/**
 * 备份与还原数据库
 */

@Controller
public class DatabaseBackUpRecover {
//    public static void main(String[] args) throws IOException{
//        backup("d:\\d.sql");
//        //recover("d:\\d.sql");
//    }

    @RequestMapping(value = "/backupDatabase")
    public void backupDatabase() throws IOException {
        backup("d://d.sql");
    }
    public static void backup(String path) throws IOException{
        Runtime runtime = Runtime.getRuntime();
        //-u后面是用户名,-p是密码-p后面最好不要有空格,-family是数据库的名字
        Process process = runtime.exec("C://Program Files//MySQL//MySQL Server 5.5//bin//mysqldump -uroot -p12345 dk_qj_db");
        InputStream inputStream = process.getInputStream();//得到输入流,写成.sql文件
        InputStreamReader reader = new InputStreamReader(inputStream);
        BufferedReader br = new BufferedReader(reader);
        String s = null;
        StringBuffer sb = new StringBuffer();
        while((s = br.readLine()) != null){
            sb.append(s+"\r\n");
        }
        s = sb.toString();
        System.out.println(s);
        File file = new File(path);
        file.getParentFile().mkdirs();
        FileOutputStream fileOutputStream = new FileOutputStream(file);
        fileOutputStream.write(s.getBytes());
        fileOutputStream.close();
        br.close();
        reader.close();
        inputStream.close();
    }
    public static void recover(String path) throws IOException{
        Runtime runtime = Runtime.getRuntime();
        //-u后面是用户名,-p是密码-p后面最好不要有空格,-family是数据库的名字,--default-character-set=utf8,这句话一定的加
        //我就是因为这句话没加导致程序运行成功,但是数据库里面的内容还是以前的内容,最好写上完成的sql放到cmd中一运行才知道报错了
        //错误信息:
        //mysql: Character set 'utf-8' is not a compiled character set and is not specified in the '
        //C:\Program Files\MySQL\MySQL Server 5.5\share\charsets\Index.xml' file ERROR 2019 (HY000): Can't
        // initialize character set utf-8 (path: C:\Program Files\MySQL\MySQL Server 5.5\share\charsets\),
        //又是讨人厌的编码问题,在恢复的时候设置一下默认的编码就可以了。
        Process process = runtime.exec("mysql -u root -pmysql --default-character-set=utf8 goldenwing");
        OutputStream outputStream = process.getOutputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(path)));
        String str = null;
        StringBuffer sb = new StringBuffer();
        while((str = br.readLine()) != null){
            sb.append(str+"\r\n");
        }
        str = sb.toString();
        System.out.println(str);
        OutputStreamWriter writer = new OutputStreamWriter(outputStream,"utf-8");
        writer.write(str);
        writer.flush();
        outputStream.close();
        br.close();
        writer.close();
    }
}
  • 该代码已在项目中通过测试,有什么问题,评论该博客即可
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年03月06日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 定时备份与还原
  • 手动备份与还原数据库
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档