Java实现MySQL数据库备份
在Java中实现MySQL数据库备份,可以通过多种方式完成,以下是几种常用的方法:
使用Runtime.exec()执行mysqldump命令
import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MySQLBackup {
public static void backupDatabase(String host, String port, String user, String password, String database, String backupPath) {
try {
// 创建备份文件名
String fileName = "backup_" + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + ".sql";
String filePath = backupPath + File.separator + fileName;
// 构建mysqldump命令
String command = "mysqldump -h" + host + " -P" + port + " -u" + user +
(password != null && !password.isEmpty() ? " -p" + password : "") +
" " + database + " > " + filePath;
// 执行命令
Process process = Runtime.getRuntime().exec(command);
// 读取输出
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
int exitCode = process.waitFor();
if (exitCode == 0) {
System.out.println("数据库备份成功,备份文件位置: " + filePath);
} else {
System.out.println("数据库备份失败,退出码: " + exitCode);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
String host = "localhost";
String port = "3306";
String user = "root";
String password = "yourpassword";
String database = "yourdatabase";
String backupPath = "C:\\backups"; // Windows示例
// String backupPath = "/var/backups"; // Linux示例
backupDatabase(host, port, user, password, database, backupPath);
}
}
使用ProcessBuilder执行命令(更推荐)
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class MySQLBackupProcessBuilder {
public static void backupDatabase(String host, String port, String user, String password, String database, String backupPath) {
try {
// 创建备份文件名
String fileName = "backup_" + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + ".sql";
String filePath = backupPath + File.separator + fileName;
// 构建命令参数列表
List<String> command = new ArrayList<>();
command.add("mysqldump");
command.add("-h" + host);
command.add("-P" + port);
command.add("-u" + user);
if (password != null && !password.isEmpty()) {
command.add("-p" + password);
}
command.add(database);
// 使用ProcessBuilder执行命令
ProcessBuilder processBuilder = new ProcessBuilder(command);
processBuilder.redirectOutput(new File(filePath));
Process process = processBuilder.start();
int exitCode = process.waitFor();
if (exitCode == 0) {
System.out.println("数据库备份成功,备份文件位置: " + filePath);
} else {
System.out.println("数据库备份失败,退出码: " + exitCode);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
String host = "localhost";
String port = "3306";
String user = "root";
String password = "yourpassword";
String database = "yourdatabase";
String backupPath = "C:\\backups"; // Windows示例
// String backupPath = "/var/backups"; // Linux示例
backupDatabase(host, port, user, password, database, backupPath);
}
}
使用Java JDBC直接导出数据
import java.io.*;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MySQLBackupJDBC {
public static void backupDatabase(String host, String port, String user, String password, String database, String backupPath) {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
FileWriter fw = null;
try {
// 创建备份文件名
String fileName = "backup_" + new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()) + ".sql";
String filePath = backupPath + File.separator + fileName;
// 建立数据库连接
String url = "jdbc:mysql://" + host + ":" + port + "/" + database;
conn = DriverManager.getConnection(url, user, password);
// 获取所有表名
stmt = conn.createStatement();
rs = stmt.executeQuery("SHOW TABLES");
fw = new FileWriter(filePath);
// 写入数据库创建语句
fw.write("CREATE DATABASE IF NOT EXISTS " + database + ";\n");
fw.write("USE " + database + ";\n\n");
// 遍历所有表
while (rs.next()) {
String tableName = rs.getString(1);
fw.write("-- Table structure for " + tableName + "\n");
// 写入表结构
stmt = conn.createStatement();
ResultSet tableRs = stmt.executeQuery("SHOW CREATE TABLE " + tableName);
if (tableRs.next()) {
fw.write(tableRs.getString(2) + ";\n\n");
}
// 写入表数据
fw.write("-- Data for " + tableName + "\n");
tableRs = stmt.executeQuery("SELECT * FROM " + tableName);
ResultSetMetaData metaData = tableRs.getMetaData();
int columnCount = metaData.getColumnCount();
while (tableRs.next()) {
fw.write("INSERT INTO " + tableName + " VALUES (");
for (int i = 1; i <= columnCount; i++) {
if (i > 1) fw.write(", ");
Object value = tableRs.getObject(i);
if (value == null) {
fw.write("NULL");
} else if (value instanceof String) {
fw.write("'" + escapeString(value.toString()) + "'");
} else {
fw.write(value.toString());
}
}
fw.write(");\n");
}
fw.write("\n");
}
System.out.println("数据库备份成功,备份文件位置: " + filePath);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (fw != null) fw.close();
if (rs != null) rs.close();
if (stmt != null) stmt.close();
if (conn != null) conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
private static String escapeString(String input) {
return input.replace("\\", "\\\\")
.replace("'", "\\'")
.replace("\"", "\\\"")
.replace("\0", "\\0")
.replace("\n", "\\n")
.replace("\r", "\\r")
.replace("\t", "\\t")
.replace("\b", "\\b")
.replace("\f", "\\f");
}
public static void main(String[] args) {
String host = "localhost";
String port = "3306";
String user = "root";
String password = "yourpassword";
String database = "yourdatabase";
String backupPath = "C:\\backups"; // Windows示例
// String backupPath = "/var/backups"; // Linux示例
backupDatabase(host, port, user, password, database, backupPath);
}
}
注意事项
-
mysqldump方法:
- 需要系统已安装MySQL客户端工具
- 需要确保Java进程有执行mysqldump命令的权限
- 在Windows和Linux上的路径处理可能不同
-
JDBC方法:
- 不需要系统安装MySQL客户端
- 对于大型数据库,性能可能不如mysqldump
- 需要处理各种数据类型的转义
-
安全考虑:
- 不要将密码直接写在代码中,应使用配置文件或环境变量
- 考虑加密敏感信息
-
错误处理:
- 添加适当的异常处理
- 记录备份日志
-
定时备份:
- 可以结合Java的Timer或ScheduledExecutorService实现定时备份
- 也可以考虑使用操作系统的定时任务(如cron)
选择哪种方法取决于你的具体需求和环境,对于大多数场景,使用mysqldump的方法更可靠且高效。
