项目中需要提供年度结算功能,年结操作时需要创建下一年度的数据库并将本年度部分数据表的数据保存到下一年度的数据库
项目中使用到了HuTools部分工具类
1. 表结构、存储过程、函数备份:
mysqldump -u[用户名] -d -R [数据库名] [需要备份的表名称,空格隔开] > [备份文件路径]
* 示例: mysqldump -uroot -p123 -R test t1 t2 > ~/structure.sql
* 参数: -d 仅备份结构 -R 备份存储过程及函数
* 解释: 备份test库t1、t2表结构、存储过程、函数到当前用户目录下的structure.sql文件
2. 表结构、表数据备份:
mysqldump -u[用户名] -p[密码] [数据库名] [需要备份的表名称,空格隔开] > [备份文件路径]
* 示例: mysqldump -uroot -p123 test t3 t4 > ~/data.sql
* 解释: 备份test库t3、t4表的结构和数据到当前用户目录下的data.sql文件
3. 创建数据库:
mysqladmin -u[用户名] -p[密码] create [数据库名]
* 示例: mysqladmin -uroot -p123 create test1
* 解释: 创建test1数据库
4. 数据库还原:
mysql -u[用户名] -p[密码] [数据库名] < [备份文件路径]
* 示例: mysql -uroot -p123 test1 < ~/script.sql
* 解释: 将当前用户目录下的script.sql文件的内容导入到test1库
import cn.apcinfo.base.exception.ApcServiceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class BinBashUtil {
private static final Logger log = LoggerFactory.getLogger(BinBashUtil.class);
private static final String SYSTEM_TYPE = System.getProperty("os.name");
/**
* 执行指定命令
*/
public static int execute(String cmd){
String[] command;
if("linux".equalsIgnoreCase(SYSTEM_TYPE)){
command = new String[]{"/bin/sh","-c",cmd};
} else if("windows".equalsIgnoreCase(SYSTEM_TYPE)){
command = new String[]{"cmd","/c",cmd};
} else {
throw new ApcServiceException("操作系统类型不在受支持的范围内!");
}
// 执行命令
try {
Process process = Runtime.getRuntime().exec(command);
return process.waitFor();
} catch (Exception e) {
log.error("执行操作系统命令失败!",e);
throw new ApcServiceException("执行操作系统命令失败!");
}
}
}
private void mergeSQLFile(String currentFilePath,BufferedWriter targetWriter) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(currentFilePath));
String line = null;
while((line = br.readLine()) != null){
// 跳过空行、注释行
if("".equals(line.trim()) || line.startsWith("/*") || line.startsWith("--")){
continue;
}
targetWriter.write(line);
targetWriter.write(System.lineSeparator());
}
br.close();
}
// 准备基础参数,此处只考虑本机,如果需要操作外部服务器请提供 -h参数,并准备外部服务器host
String password = properties.getPassword();
String username = properties.getUsername();
String folderName = UUID.randomUUID().toString().replaceAll("-","");
String folderPath = StrUtil.format("{}{}{}{}",rootPath,backUpPath,folderName,File.separator);
File folder = new File(folderPath);
if(!folder.exists()){
folder.mkdirs();
}
String onlyStructureBackUpTableStr = CollUtil.join(onlyStructureTableList," ");
String dataAndStructureBackUpTableStr = CollUtil.join(dataAndStructureTableList," ");
// 准备文件存储路径
String onlyStructureBackUpScriptFilePath = StrUtil.format("{}{}.sql",folderPath,UUID.randomUUID().toString().replaceAll("-",""));
String dataAndStructureBackUpScriptFilePath = StrUtil.format("{}{}.sql",folderPath,UUID.randomUUID().toString().replaceAll("-",""));
String completeBackUpScriptFilePath = StrUtil.format("{}{}.sql",folderPath,UUID.randomUUID().toString().replaceAll("-",""));
// 准备binbash命令
String onlyStructureBackUpCommand = StrUtil.format("mysqldump -u{} -d -R {} {} > {}",username,currentDbName,onlyStructureBackUpTableStr,onlyStructureBackUpScriptFilePath);
String dataAndStructureBackupCommand = StrUtil.format("mysqldump -u{} -p{} {} {} > {}",username,password,currentDbName,dataAndStructureBackUpTableStr,dataAndStructureBackUpScriptFilePath);
String createNextDbCommand = StrUtil.format("mysqladmin -u{} -p{} create {}",username,password,nextDbName);
String reduceCommand = StrUtil.format("mysql -u{} -p{} {} < {}",username,password,nextDbName,completeBackUpScriptFilePath);
int result = -1;
// 执行binbash命令备份数据库
try{
result = BinBashUtil.execute(onlyStructureBackUpCommand);
if(result != 0){
throw new ApcServiceException("备份当前数据库失败,请稍候重试!");
}
result = BinBashUtil.execute(dataAndStructureBackupCommand);
if(result != 0){
throw new ApcServiceException("备份当前数据库失败,请稍候重试!");
}
} catch (ApcServiceException ex){
throw new ApcServiceException("备份当前数据库失败,请稍候重试!");
}
// 合并备份文件
try {
BufferedWriter bw = new BufferedWriter(new FileWriter(completeBackUpScriptFilePath));
mergeSQLFile(onlyStructureBackUpScriptFilePath,bw);
mergeSQLFile(dataAndStructureBackUpScriptFilePath,bw);
bw.close();
// 清理原文件
FileUtil.del(onlyStructureBackUpScriptFilePath);
FileUtil.del(dataAndStructureBackUpScriptFilePath);
} catch (IOException e) {
log.error("合并备份文件失败!",e);
throw new ApcServiceException("合并备份文件失败!");
}
// 执行创建数据库命令
result = BinBashUtil.execute(createNextDbCommand);
if(result != 0){
throw new ApcServiceException("创建下年度数据库失败,请稍候重试!");
}
// 执行数据库还原命令
result = BinBashUtil.execute(reduceCommand);
if(result != 0){
throw new ApcServiceException("重置下年度数据库数据失败,请稍候重试!");
}
至此,java备份还原mysql数据库完成
感谢如下博客:
mysql备份还原命令