简介:配置一个时间监听器,通过util中的日期类和定时器控件解析相关的时间数据,在相应的时间调用备份数据库的方法.
备份数据库的方法使用了mysql自带的mysqldump进行备份,得到数据库的sql文件,完成备份.
下面是具体的实现
首先,相关配置文件,放在文件类路径下 (dbBackUpRecover.properties)
#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 #造成两点半备份一次
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;
}
}
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();
}
}
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) {
}
}
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();
}
}
}
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();
}
}
}
<listener>
<listener-class>
com.qihang.controller.databaseBackUpRecover.OperationListener
listener-class>
listener>
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();
}
}