first commit

This commit is contained in:
Ray
2026-02-19 03:37:37 +08:00
commit ccfd8c79a4
2813 changed files with 453657 additions and 0 deletions

View File

@@ -0,0 +1,9 @@
#\u5907\u4efd\u6570\u636e\u5e93
db.ip=127.0.0.1
db.port=6306
db.database.name=demo
db.username=root
db.password=2uVS6UkYyV7Do4JbN9zebDUMoF4w88q3CNxanZ0wEnY%3D
db.backup.path=/backup

15
comm/DB/src/db/Constants.java Executable file
View File

@@ -0,0 +1,15 @@
package db;
public class Constants {
/**
* 备份时间格式
*/
public final static String DB_BACKUP_TIME_FORMAT = "yyyyMMddHHmmss-SSS";
/**
* File.separator 正则 "\\"
*/
public static final String FILE_SEPARATOR_REGEX = "\\\\";
}

23
comm/DB/src/db/DBBackup.java Executable file
View File

@@ -0,0 +1,23 @@
package db;
import java.util.Map;
public interface DBBackup {
/**
* <p>Description: 数据库备份 </p>
*
* @param params 参数(若缺省则使用系统默认配置) <pre>
* ip -- IP地址
* port -- 端口
* databaseName -- 数据库名
* username -- 用户名
* password -- 密码
* backupPath -- 备份存储路径</pre>
*
* @param processListener 监听器
* @return 结果
*/
public boolean backup(Map<String, Object> params, OpertProcessListener processListener);
}

View File

@@ -0,0 +1,15 @@
package db;
public interface DBBackupBeanHandler {
/**
* @param backupRecordService The backupRecordService to set.
*/
public void setBackupRecordService(DBBackupRecordService backupRecordService);
/**
* @param operatorEvent The operatorEvent to set.
*/
public void setOperatorEvent(DBOperatorEvent operatorEvent);
}

View File

@@ -0,0 +1,25 @@
package db;
import java.util.HashSet;
import java.util.Set;
public class DBBackupLock {
public static final String ALL_DB_LOCK = "ALL_DB_LOCK";
private static final Set<String> filter = new HashSet<String>();
public static boolean add(String lock) {
if (!filter.add(lock)) {
return false;
} else {
return true;
}
}
public static void remove(String lock) {
filter.remove(lock);
}
public static boolean getLock(String lock) {
return filter.contains(lock);
}
}

View File

@@ -0,0 +1,172 @@
package db;
import java.util.Date;
import db.util.FileUtil;
public class DBBackupRecord {
/**
* UUID
*/
private String uuid;
/**
* 备份名称
*/
private String name;
/**
* 备份时间
*/
private Date backupTime;
/**
* 备份文件路径
*/
private String filePath;
/**
* 备份文件大小(B)
*/
private Long fileSize;
/**
* 备注
*/
private String description;
/**
* Gets the UUID.
*
* @return Returns the uuid.
*/
public String getUuid() {
return uuid;
}
/**
* Sets the UUID.
*
* @param uuid The uuid to set.
*/
public void setUuid(String uuid) {
this.uuid = uuid;
}
/**
* Gets the 备份名称.
*
* @return Returns the name.
*/
public String getName() {
return name;
}
/**
* Sets the 备份名称.
*
* @param name The name to set.
*/
public void setName(String name) {
this.name = name;
}
/**
* Gets the 备份时间.
*
* @return Returns the backupTime.
*/
public Date getBackupTime() {
return backupTime;
}
/**
* Sets the 备份时间.
*
* @param backupTime The backupTime to set.
*/
public void setBackupTime(Date backupTime) {
this.backupTime = backupTime;
}
/**
* Gets the 备份文件路径.
*
* @return Returns the filePath.
*/
public String getFilePath() {
return filePath;
}
/**
* Sets the 备份文件路径.
*
* @param filePath The filePath to set.
*/
public void setFilePath(String filePath) {
this.filePath = filePath;
}
/**
* Gets the 备份文件大小(B).
*
* @return Returns the fileSize.
*/
public Long getFileSize() {
return fileSize;
}
/**
* Sets the 备份文件大小(B).
*
* @param fileSize The fileSize to set.
*/
public void setFileSize(Long fileSize) {
this.fileSize = fileSize;
}
/**
* Gets the 备注.
*
* @return Returns the description.
*/
public String getDescription() {
return description;
}
/**
* Sets the 备注.
*
* @param description The description to set.
*/
public void setDescription(String description) {
this.description = description;
}
@Override
public String toString() {
StringBuffer str = new StringBuffer("\n");
str.append("===============================================================================");
str.append("\n");
str.append("<< ").append(getClass().getSimpleName()).append(" >>");
str.append("\n");
str.append("-------------------------------------------------------------------------------");
str.append("\n");
str.append(" UUID: ").append(getUuid());
str.append("\n");
str.append(" Name: ").append(getName());
str.append("\n");
str.append(" BackupTime: ").append(getBackupTime());
str.append("\n");
str.append(" FilePath: ").append(getFilePath());
str.append("\n");
str.append(" FileSize: ").append(FileUtil.formetFileSize(getFileSize(), null));
str.append("\n");
str.append(" Description: ").append(getDescription());
str.append("\n");
str.append("-------------------------------------------------------------------------------");
return str.toString();
}
}

View File

@@ -0,0 +1,57 @@
package db;
import java.io.Serializable;
import java.util.Collection;
public interface DBBackupRecordService {
/**
* <p>Description: 从缓存中获取所有备份记录信息 </p>
* @return 备份记录信息集合
*/
public Collection<DBBackupRecord> findAll();
/**
* <p>Description: 从缓存中获取备份记录 </p>
* @param uuid 备份记录ID
* @return 备份记录详情
*/
public DBBackupRecord findByUuid(Serializable uuid);
/**
* <p>Description: 添加备份记录信息,要同步添加缓存 </p>
* @param record 备份记录信息
*/
public void add(DBBackupRecord record);
/**
* <p>Description: 删除备份记录,要同步删除缓存和文件 </p>
* @param uuid 备份记录ID
*/
public void delete(Serializable uuid);;
/**
* <p>Description: 批量删除备份,要同步删除缓存和文件 </p>
* @param ids 备份记录ID数组
* @return 删除记录条数
*/
public int deleteByIds(Serializable[] ids);
/**
* <p>Description: 获取最大备份记录保存限值 </p>
* @return 最大备份记录限值
*/
public Integer getMaxLimitNum();
/**
* <p>Description: 设置最大备份记录保存限值 </p>
* @param limitNum 限值
*/
public void setMaxLimitNum(Integer limitNum);
/**
* <p>Description: 初始化 </p>
*/
public void initialize();
}

View File

@@ -0,0 +1,80 @@
package db;
import db.backup.internal.MysqlBackupImpl;
import db.restore.MysqlRestoreImpl;
import db.util.ConfigUtils;
public class DBBeanFactory {
/**
* <p>Description: 创建DBBackup实例 </p>
*
* @param backupRecordService 备份记录信息管理接口
* @param operatorEvent 数据库操作事件
* @return DBBackup实例
*/
public static Object buildBackupBean(DBBackupRecordService backupRecordService, //
DBOperatorEvent operatorEvent) {
SupportDBTypeEnum dbType = ConfigUtils.getCurrentDBType(); // 当前数据库类型
DBBackup backupService = null;
switch (dbType) {
case mysql:
backupService = new MysqlBackupImpl();
break;
// case oracle:
// backupService = new OracleBackupImpl();
// break;
// case postgre:
// backupService = new PostgreBackupImpl();
// break;
// case sqlserver:
// backupService = new SQLServerBackupImpl();
// break;
}
if (backupService == null) {
throw new IllegalArgumentException("The DB backupService can not be NULL");
}
if (backupService instanceof DBBackupBeanHandler) {
((DBBackupBeanHandler) backupService).setBackupRecordService(backupRecordService);
((DBBackupBeanHandler) backupService).setOperatorEvent(operatorEvent);
}
return backupService;
}
/**
* <p>Description: 创建DBRestore实例 </p>
*
* @param operatorEvent 数据库操作事件
* @return DBRestore实例
*/
public static Object buildRestoreBean(DBOperatorEvent operatorEvent) {
SupportDBTypeEnum dbType = ConfigUtils.getCurrentDBType(); // 当前数据库类型
DBRestore restoreService = null;
switch (dbType) {
case mysql:
restoreService = new MysqlRestoreImpl();
break;
// case oracle:
// restoreService = new OracleRestoreImpl();
// break;
// case postgre:
// restoreService = new PostgreRestoreImpl();
// break;
// case sqlserver:
// restoreService = new SQLServerRestoreImpl();
// break;
}
if (restoreService == null) {
throw new IllegalArgumentException("The DB restoreService can not be NULL");
}
if (restoreService instanceof DBRestoreBeanHandler) {
((DBRestoreBeanHandler) restoreService).setOperatorEvent(operatorEvent);
}
return restoreService;
}
}

View File

@@ -0,0 +1,35 @@
package db;
import java.io.File;
import java.util.Map;
public interface DBOperatorEvent {
/**
* 开始备份前
* @param params 参数
*/
public void beforeBackup(Map<String, Object> params);
/**
* 备份后事件
* @param record 备份记录
* @param params 参数
*/
public void afterBackup(DBBackupRecord record, Map<String, Object> params);
/**
* 数据库还原操作前
* @param file 备份文件
* @param params 参数
*/
public void beforeRestore(File file, Map<String, Object> params);
/**
* 数据库还原操作后
* @param file 备份文件
* @param params 参数
*/
public void afterRestore(File file, Map<String, Object> params);
}

41
comm/DB/src/db/DBRestore.java Executable file
View File

@@ -0,0 +1,41 @@
package db;
import java.io.File;
import java.util.Map;
public interface DBRestore {
/**
* <p>Description: 从文件还原数据库 </p>
* @param file 待还原的文件
* @param params 参数(若缺省则使用系统默认配置)<pre>
* ip -- IP地址
* port -- 端口
* databaseName -- 数据库名
* username -- 用户名
* password -- 密码</pre>
*
* @param processListener 监听器
* @return 结果
*/
public boolean restore(File file, Map<String, Object> params, OpertProcessListener processListener);
/**
* <p>Description: 从文件还原数据库 </p>
* @param filePath 待还原的文件路径
* @param params 参数
* @param processListener 监听器
* @return 结果
*/
public boolean restore(String filePath, Map<String, Object> params, OpertProcessListener processListener);
/**
<p>Description: 从备份记录还原数据库 </p>
* @param record 备份记录
* @param params 参数
* @param processListener 监听器
* @return 结果
*/
public boolean restore(DBBackupRecord record, Map<String, Object> params, OpertProcessListener processListener);
}

View File

@@ -0,0 +1,10 @@
package db;
public interface DBRestoreBeanHandler {
/**
* @param operatorEvent The operatorEvent to set.
*/
public void setOperatorEvent(DBOperatorEvent operatorEvent);
}

View File

@@ -0,0 +1,31 @@
package db;
import db.support.MessageOutputListener;
public interface OpertProcessListener {
/**
* <p>Description: 输出信息监听器 </p>
*
* @return 输出信息监听器
*/
public MessageOutputListener getOutputListener();
/**
* <p>Description: 操作结束 </p>
*/
public void onExit();
/**
* <p>Description: 备份操作中止 </p>
*/
public void onInterrupt();
/**
* <p>Description: 操作过程是否结束 </p>
*
* @return 是否结束
*/
public boolean isFinish();
}

View File

@@ -0,0 +1,130 @@
package db;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Properties;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
* 读取Properties综合类,默认绑定到classpath下的config.properties文件。
*/
public class PropertiesUtilDB {
private static Logger logger = LogManager.getLogger(PropertiesUtilDB.class);
private static String CONFIG_FILENAME = "config/db.properties";
private static Properties prop = null;
public PropertiesUtilDB() {
if (prop == null) {
loadProperties();
}
};
private synchronized static void loadProperties() {
byte buff[] = null;
try {
// Open the props file
InputStream is = PropertiesUtilDB.class.getResourceAsStream("/" + CONFIG_FILENAME);
prop = new Properties();
// Read in the stored properties
prop.load(is);
} catch (Exception e) {
System.err.println("读取配置文件失败!!!");
prop = null;
logger.error(e.getMessage(), e);
}
}
/**
* 得到属性值
*
* @param key
* @return
*/
public static String getProperty(String key) {
if (prop == null) {
loadProperties();
}
String value = prop.getProperty(key);
if (value == null) {
return null;
}
return value.trim();
}
/**
* 得到内容包含汉字的属性值
*
* @param key
* @return
*/
public static String getGBKProperty(String key) {
String value = getProperty(key);
try {
value = new String(value.getBytes("ISO8859-1"), "GBK");
} catch (UnsupportedEncodingException e) {
}
if (value == null) {
return null;
}
return value.trim();
}
/**
* 得到属性值,
*
* @param key
* @param defaultValue
* @return
*/
public static String getProperty(String key, String defaultValue) {
if (prop == null) {
loadProperties();
}
String value = prop.getProperty(key, defaultValue);
if (value == null) {
return null;
}
return value.trim();
}
/**
* 得到内容包含汉字的属性值,如果不存在则使用默认值
*
* @param key
* @return
*/
public static String getGBKProperty(String key, String defaultValue) {
try {
defaultValue = new String(defaultValue.getBytes("GBK"), "ISO8859-1");
String value = getProperty(key, defaultValue);
value = new String(value.getBytes("ISO8859-1"), "GBK");
if (value == null) {
return null;
}
return value.trim();
} catch (UnsupportedEncodingException e) {
return null;
}
}
public static String getUTFProperty(String key, String defaultValue) {
try {
defaultValue = new String(defaultValue.getBytes("UTF-8"), "ISO8859-1");
String value = getProperty(key, defaultValue);
value = new String(value.getBytes("ISO8859-1"), "UTF-8");
if (value == null) {
return null;
}
return value.trim();
} catch (UnsupportedEncodingException e) {
return null;
}
}
}

View File

@@ -0,0 +1,52 @@
package db;
public enum SupportDBTypeEnum {
/**
* MySQL数据库
*/
mysql,
/**
* Oracle数据库
*/
oracle,
/**
* Postgre数据库
*/
postgre,
/**
* SQLServer数据库
*/
sqlserver;
/**
* @param type 数据库类型名
* @return support DBType
*/
public static SupportDBTypeEnum getEnum(String type) {
if (type == null || "".equals(type = type.trim())) {
throw new IllegalArgumentException("The database type can not be NULL");
}
SupportDBTypeEnum result = null;
try {
result = SupportDBTypeEnum.valueOf(type);
return result;
} catch (Throwable e) {
// ignore
}
for (SupportDBTypeEnum supportType : SupportDBTypeEnum.values()) {
if (supportType.name().equalsIgnoreCase(type)) {
return supportType;
}
}
if (result == null) {
throw new IllegalArgumentException("The database type with name '" + type + "' is not support");
}
return result;
}
}

View File

@@ -0,0 +1,234 @@
package db.backup.internal;
import java.io.FileNotFoundException;
import java.text.DateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.logging.log4j.Level;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import db.Constants;
import db.DBBackup;
import db.DBBackupBeanHandler;
import db.DBBackupRecord;
import db.DBBackupRecordService;
import db.DBOperatorEvent;
import db.OpertProcessListener;
import db.support.DBBackupRecordServiceImpl;
import db.util.FileUtil;
import db.util.PathUtil;
import db.util.UUIDGenerator;
import kernel.util.DateUtils;
import kernel.util.StringUtils;
public abstract class AbstractBackupImpl implements DBBackup, DBBackupBeanHandler {
/**
* logger
*/
private final Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* 默认备份路径
*/
protected final static String DEFAULT_BACKUP_PATH = PathUtil.getDbBackupPath();
/**
* 事件通知
*/
protected DBOperatorEvent operatorEvent;
/**
* 数据库备份记录信息管理接口
*/
protected DBBackupRecordService backupRecordService = new DBBackupRecordServiceImpl();
@Override
public boolean backup(Map<String, Object> params, OpertProcessListener processListener) {
if (params == null) {
params = new HashMap<String, Object>();
}
params = parserMapParams(params); // 解析参数
// operatorEvent.beforeBackup(params); // 备份前事件通知
boolean result = false;
DBBackupRecord record = null;
backupRecordService = new DBBackupRecordServiceImpl();
try {
if (doEnvironmentCheck(params, processListener)) {
Date backupTime = new Date(); // 备份时间
params.put("backupTime", backupTime);
String backupName = (String) params.get("backupName"); // 备份名称
if (backupName == null) {
String databaseName = (String) params.get("databaseName");
DateFormat sdf = DateUtils.createDateFormat(Constants.DB_BACKUP_TIME_FORMAT);
backupName = databaseName + "_" + sdf.format(backupTime);
params.put("backupName", backupName);
}
result = doBackup(params, processListener); // 执行备份操作
record = createNewBackupRecord(params); // 新建备份记录
backupRecordService.add(record); // 保存备份文件信息
}
} catch (Throwable e) {
result = false;
logger.error("backup database error", e);
// throw new FastFailException(e);
throw new RuntimeException(e);
} finally {
String msg = "Finished - " + (result ? "Successfully" : "Failed");
try {
onOutputAndLog(processListener, msg, Level.INFO);
} catch (InterruptedException e) {
// ignore
}
if (processListener != null) {
processListener.onExit();
}
clearAfterBackup(params); // 备份后清理
}
params.put("result", result); // 结果
// operatorEvent.afterBackup(record, params); // 备份后事件通知
return result;
}
/**
* <p>Description: 备份清理工作(清除临时目录、不完整备份文件等操作) </p>
* <p>Create Time: 2013-2-20 </p>
* @author weiminghua
* @param params 参数
*/
protected void clearAfterBackup(Map<String, Object> params) {
// default do nothing
}
/**
* 备份文件后缀
* @return 备份文件后缀名
*/
protected abstract String getBackupFileSuffix();
/**
* 解析参数
*
* @param params 参数
* @return 参数
*/
protected abstract Map<String, Object> parserMapParams(Map<String, Object> params);
/**
* 运行环境检测
* @param params 参数
* @param processListener 监听器
* @return 结果
*/
protected abstract boolean doEnvironmentCheck(Map<String, Object> params, OpertProcessListener processListener);
/**
* 执行备份
* @param params 参数
* @param processListener 监听器
* @return 结果
* @throws InterruptedException 中断异常
*/
protected abstract boolean doBackup(Map<String, Object> params, OpertProcessListener processListener)
throws InterruptedException;
/**
* @param operatorEvent The operatorEvent to set.
*/
public void setOperatorEvent(DBOperatorEvent operatorEvent) {
this.operatorEvent = operatorEvent;
}
/**
* @param backupRecordService The backupRecordService to set.
*/
public void setBackupRecordService(DBBackupRecordService backupRecordService) {
this.backupRecordService = backupRecordService;
}
/**
* 生成备份记录
* @param params 参数
* @return 备份记录
*/
protected DBBackupRecord createNewBackupRecord(Map<String, Object> params) {
DBBackupRecord record = new DBBackupRecord();
record.setUuid(UUIDGenerator.getUUID());
String backupName = (String) params.get("backupName");
record.setName(backupName);
record.setBackupTime((Date) params.get("backupTime")); // 备份时间
String description = (String) params.get("description"); // 备份描述
record.setDescription(description);
String backupPath = (String) params.get("backupPath"); // 备份存储路径
String filePath = backupPath + "/" + backupName + getBackupFileSuffix(); // 备份文件路径
record.setFilePath(filePath);
try {
record.setFileSize(FileUtil.getFileSize(filePath));
} catch (FileNotFoundException e) {
logger.error("get backup file[" + filePath + "] size error");
throw new RuntimeException(e);
}
return record;
}
/**
* 输出监听,同时添加日志信息
* @param processListener 过程监听
* @param msg 日志信息
* @param log4jLevel 日志级别
* @throws InterruptedException 备份中断异常
*/
protected void onOutputAndLog(OpertProcessListener processListener, String msg, Level log4jLevel)
throws InterruptedException {
if (StringUtils.isNullOrEmpty(msg)) {
return;
}
if (processListener != null) {
if (processListener.isFinish()) {
throw new InterruptedException("interrupt databse backup"); // 备份中断
}
if (processListener.getOutputListener() != null) {
processListener.getOutputListener().onOutput(msg);
}
}
if (log4jLevel == null) {
try {
Thread.sleep(200); // 延迟加载信息
} catch (InterruptedException e) {
// ignore
}
return;
}
// 输出日志信息
if (Level.ERROR.equals(log4jLevel)) {
logger.error(msg);
}
else if (Level.WARN.equals(log4jLevel)) {
logger.warn(msg);
}
else if (Level.INFO.equals(log4jLevel)) {
logger.info(msg);
}
else if (Level.DEBUG.equals(log4jLevel)) {
logger.debug(msg);
}
}
}

View File

@@ -0,0 +1,302 @@
package db.backup.internal;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.List;
import java.util.Map;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.logging.log4j.Level;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.util.Assert;
import com.jcraft.jsch.SftpException;
import db.Constants;
import db.DBBackup;
import db.OpertProcessListener;
import db.PropertiesUtilDB;
import db.util.CMDUtil;
import db.util.FileUtil;
import db.util.SFTPUtil;
import db.util.ZipUtils;
import db.util.jdbc.DBTools;
import db.util.jdbc.MysqlTools;
public class MysqlBackupImpl extends AbstractBackupImpl {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
protected String getBackupFileSuffix() {
return ".zip";
}
@Override
protected Map<String, Object> parserMapParams(Map<String, Object> params) {
Assert.notNull(params);
// 读取参数
if (params.get("ip") == null) {
// String ip = System.getProperty(DBPorperties.ENV_IP, MySQLConfig.DEFAULT_IP);
String ip = PropertiesUtilDB.getProperty("db.ip");
params.put("ip", ip);
}
if (params.get("port") == null) {
// String port = System.getProperty(DBPorperties.ENV_PORT, MySQLConfig.DEFAULT_PORT);
String port = PropertiesUtilDB.getProperty("db.port");
params.put("port", port);
}
if (params.get("databaseName") == null) {
// String databaseName = System.getProperty(DBPorperties.ENV_DBNAME, MySQLConfig.DEFAULT_DBNAME);
String databaseName = PropertiesUtilDB.getProperty("db.databaseName");
params.put("databaseName", databaseName);
}
if (params.get("username") == null) {
// String username = System.getProperty(DBPorperties.RUIJIE_JDBC_USERNAME);
String username = PropertiesUtilDB.getProperty("db.username");
params.put("username", username);
}
if (params.get("password") == null) {
// String password = System.getProperty(DBPorperties.RUIJIE_JDBC_PASSWORD);
String password = PropertiesUtilDB.getProperty("db.password");
params.put("password", password);
}
// 备份存储路径
if (params.get("backupPath") == null) {
String backupPath = DEFAULT_BACKUP_PATH;
params.put("backupPath", backupPath);
}
return params;
}
@Override
protected boolean doEnvironmentCheck(Map<String, Object> params, OpertProcessListener processListener) {
Assert.notNull(params);
// TODO:doEnvironmentCheck
return true;
}
@Override
protected boolean doBackup(Map<String, Object> params, OpertProcessListener processListener)
throws InterruptedException {
Assert.notNull(params);
onOutputAndLog(processListener, "Starting backup...", Level.INFO);
String backupPath = (String) params.get("backupPath"); // 备份路径
String backupName = (String) params.get("backupName");
String realBackupPath = backupPath + "/" + backupName; // 实际备份路径
FileUtil.deleteDir(realBackupPath, false); // 删除旧备份
File backUpdir = new File(realBackupPath);
if (!backUpdir.exists()) {
backUpdir.mkdirs();
}
// 备份数据库结构
// backupDBStruct(params, realBackupPath, processListener);
// 备份数据库表数据
// backupDBData(params, realBackupPath, processListener);
backupDBDataByShell(params, realBackupPath, processListener);
// 压缩备份文件
String zipName = backupName + getBackupFileSuffix(); // 备份文件名
String filePath = backupPath + "/" + zipName;
ZipUtils.createZip(filePath, realBackupPath);
// String zip="zip -m "+filePath+" "+realBackupPath;
sftp(filePath);
// onOutputAndLog(processListener, "Finished - Successfully", Level.INFO);
return true;
}
@Override
protected void clearAfterBackup(Map<String, Object> params) {
String backupPath = (String) params.get("backupPath"); // 备份路径
String backupName = (String) params.get("backupName"); // 备份名称
String realBackupPath = backupPath + "/" + backupName;
// 生成压缩文件后,删除临时目录
FileUtil.deleteDir(realBackupPath, true);
}
/**
* 导出数据库结构
* @param params 参数
* @param realPath 实际备份路径
* @param processListener 监听器
* @throws InterruptedException 中断异常
*/
private void backupDBStruct(Map<String, Object> params, String realPath, OpertProcessListener processListener)
throws InterruptedException {
onOutputAndLog(processListener, "backup database struct...", Level.INFO);
StringBuffer cmdBuf = new StringBuffer();
cmdBuf.append(DBTools.formatDBClientCmd("mysqldump", "exe")); // 客户端命令
cmdBuf.append(" -h ").append((String) params.get("ip"));
cmdBuf.append(" -P ").append((String) params.get("port"));
cmdBuf.append(" --user=").append((String) params.get("username"));
cmdBuf.append(" --password=").append((String) params.get("password"));
cmdBuf.append(" --opt "); // 同--quick --add-drop-table --add-locks --extended-insert --lock-tables。
cmdBuf.append(" --no-data "); // 不备份表数据
// cmdBuf.append(" --add-drop-database "); //
cmdBuf.append(" --result-file=")//
.append(DBTools.formatRuntimeCmdPath(realPath)) // 处理空格
.append("/db_struct.sql");
String databaseName = (String) params.get("databaseName");
cmdBuf.append(" ").append(databaseName);
try {
// if (processListener == null || processListener.getOutputListener() == null) {
// RuntimeExecutorResult result = RuntimeExecutor.execute(cmdBuf.toString(), "GB2312");
// if (logger.isDebugEnabled()) {
// logger.debug(result.getOutput());
// logger.debug(result.getError());
// }
// }
// else {
// MessageOutputListener outputListener = new MessageOutputListener();
// RuntimeExecutor.execute(cmdBuf.toString(), "GB2312", outputListener);
// while (!outputListener.isFinish()) {
// onOutputAndLog(processListener, outputListener.getOutputString(), null);
// }
// onOutputAndLog(processListener, outputListener.getOutputString(), null);
// }
logger.info(cmdBuf.toString());
String cmdResult = CMDUtil.runCMD(cmdBuf.toString());
logger.info("result:"+cmdResult);
} catch (Exception e) {
logger.error("backup DataBase Struct error");
// throw new RuntimeException(e);
}
}
/**
* 导出数据库结构
* @param params 参数
* @param realPath 实际备份路径
* @param processListener 监听器
* @throws InterruptedException 中断异常
*/
private String backupDBDataByShell(Map<String, Object> params, String realPath, OpertProcessListener processListener)
throws InterruptedException {
onOutputAndLog(processListener, "backup database struct...", Level.INFO);
StringBuffer cmdBuf = new StringBuffer();
cmdBuf.append(DBTools.formatDBClientCmd("mysqldump", "exe")); // 客户端命令
cmdBuf.append(" -h ").append((String) params.get("ip"));
cmdBuf.append(" -P ").append((String) params.get("port"));
cmdBuf.append(" -u").append((String) params.get("username"));
cmdBuf.append(" -p").append("'"+(String) params.get("password")+"'");
cmdBuf.append(" ").append((String) params.get("databaseName"));
// cmdBuf.append(" --opt "); // 同--quick --add-drop-table --add-locks --extended-insert --lock-tables。
// cmdBuf.append(" --no-data "); // 不备份表数据
// cmdBuf.append(" --add-drop-database "); //
cmdBuf.append(" > ")//
.append(DBTools.formatRuntimeCmdPath(realPath)) // 处理空格
.append("/home") // 处理空格
.append("//")
.append((String) params.get("databaseName"))
.append(".sql");
// String databaseName = (String) params.get("databaseName");
// cmdBuf.append(" ").append(databaseName);
try {
// if (processListener == null || processListener.getOutputListener() == null) {
// RuntimeExecutorResult result = RuntimeExecutor.execute(cmdBuf.toString(), "GB2312");
// if (logger.isDebugEnabled()) {
// logger.debug(result.getOutput());
// logger.debug(result.getError());
// }
// }
// else {
// MessageOutputListener outputListener = new MessageOutputListener();
// RuntimeExecutor.execute(cmdBuf.toString(), "GB2312", outputListener);
// while (!outputListener.isFinish()) {
// onOutputAndLog(processListener, outputListener.getOutputString(), null);
// }
// onOutputAndLog(processListener, outputListener.getOutputString(), null);
// }
logger.info(cmdBuf.toString());
String cmdResult = CMDUtil.runCMD(cmdBuf.toString());
logger.info("result:"+cmdResult);
} catch (Exception e) {
logger.error("backup DataBase error");
throw new RuntimeException(e);
}
return cmdBuf.toString();
}
/**
* 导出数据
* @param params 参数
* @param realPath 实际备份路径
* @param processListener 监听器
* @throws InterruptedException 中断异常
*/
private void backupDBData(Map<String, Object> params, String realPath, OpertProcessListener processListener)
throws InterruptedException {
onOutputAndLog(processListener, "Prepare writing data...", Level.INFO);
String ip = (String) params.get("ip");
String port = (String) params.get("port");
String databaseName = (String) params.get("databaseName");
String username = (String) params.get("username");
String password = (String) params.get("password");
// 获取所有数据库表
List<String> tables = MysqlTools.findAllDBTables(ip, port, databaseName, username, password);
onOutputAndLog(processListener, "Writing data...", Level.INFO);
String rootPath = realPath.replaceAll(Constants.FILE_SEPARATOR_REGEX, "/");
BasicDataSource ds = MysqlTools.createDataSource(ip, port, databaseName, username, password);
JdbcTemplate jt = new JdbcTemplate(ds);
for (int index = 0; index < tables.size(); index++) {
String tableName = tables.get(index);
String fileName = rootPath + "/" + tableName + ".txt";
onOutputAndLog(processListener, "Writing table " + tableName + " data...", Level.INFO);
StringBuffer sqlBuf = new StringBuffer();
sqlBuf.append("select * from ").append(tableName);
sqlBuf.append(" INTO OUTFILE \"").append(fileName).append("\" ");
sqlBuf.append(" FIELDS TERMINATED BY ',' ENCLOSED BY '\\\"'");
jt.execute(sqlBuf.toString());
}
}
public void sftp(String filePath) {
String sftpBackupPath= PropertiesUtilDB.getProperty("sftp.backup.path");
String sftpUsername= PropertiesUtilDB.getProperty("sftp.username");
String sftpPassword= PropertiesUtilDB.getProperty("sftp.password");
String sftpIp= PropertiesUtilDB.getProperty("sftp.ip");
int sftpPort= Integer.valueOf(PropertiesUtilDB.getProperty("sftp.port"));
SFTPUtil sftp = new SFTPUtil(sftpUsername, sftpPassword, sftpIp, sftpPort);
sftp.login(SFTPUtil.SFTP);
try {
sftp.upload(sftpBackupPath, filePath);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SftpException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
sftp.logout();
}
public static void main(String[] args) throws Exception {
DBBackup dbBack = new MysqlBackupImpl();
dbBack.backup(null, null);
}
}

View File

@@ -0,0 +1,67 @@
package db.job;
import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import db.DBBackupLock;
import db.util.BackupUtil;
import kernel.util.DateUtils;
import project.log.SysLogService;
import project.syspara.SysparaService;
public class BackupJob {
private Logger log = LoggerFactory.getLogger(BackupJob.class);
protected SysLogService sysLogService;
protected SysparaService sysparaService;
public void taskJob() {
try {
// log.info("BackupJob taskJob start,time:"+DateUtils.dateToStr(new Date(), DateUtils.DF_yyyyMMddHHmmss)+",isBackup:"+isBackup()+",lock:"+DBBackupLock.getLock(DBBackupLock.ALL_DB_LOCK));
//未被锁
if(isBackup() && !DBBackupLock.getLock(DBBackupLock.ALL_DB_LOCK)) {
BackupUtil.backupPart(sysLogService,sysparaService);
}
log.info("BackupJob taskJob end");
}catch (Throwable t) {
log.error("BackupJob taskJob fail t:"+t);
}
}
/**
* 当前是否执行局部备份true开启false不开启
* @return
*/
private boolean isBackup() {
//例如, 01:55-02:35,04:00-05:08,13:55-14:45 表示多个时间段内不备份
try {
String not_part_backup_times = sysparaService.find("not_part_backup_times").getValue();
String[] times = not_part_backup_times.split(",");
Date now = new Date();
String nowDate = DateUtils.getDateStr(now);
for (int i = 0; i < times.length; i++) {
String[] timePart = times[i].split("-");
Date startTime = DateUtils.strToDate(nowDate+" "+timePart[0]);
Date endTime = DateUtils.strToDate(nowDate+" "+timePart[1]);
if(now.after(startTime)&&now.before(endTime)) {
return false;
}
}
}catch (Exception e) {
// TODO: handle exception
log.error("BackupJob isBackup fail,e:",e);
}
return true;
}
public void setSysLogService(SysLogService sysLogService) {
this.sysLogService = sysLogService;
}
public void setSysparaService(SysparaService sysparaService) {
this.sysparaService = sysparaService;
}
}

View File

@@ -0,0 +1,95 @@
package db.map;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class CacheMap<K, V> {
/**
* map cache
*/
private final Map<K, V> map = Collections.synchronizedMap(new ConcurrentHashMap<K, V>());
// private final Map<K, V> map = new ConcurrentHashMap<K, V>();
/**
* Associates the specified value with the specified key in this map
*
* @param key key with which the specified value is to be associated
* @param value value to be associated with the specified key
*/
public void put(K key, V value) {
map.put(key, value);
}
/**
* Removes the mapping for a key from this map if it is present
*
* @param key key whose mapping is to be removed from the map
*/
public void remove(K key) {
map.remove(key);
}
/**
* Returns the number of key-value mappings in this map.
*
* @return the size of map
*/
public int size() {
return map.size();
}
/**
* Removes all of the mappings from this map.
*/
public void clear() {
map.clear();
}
/**
* Returns a {@link Collection} view of the values contained in this map.
*
* @return a collection view of the values contained in this map
*/
public Collection<V> values() {
return map.values();
}
/**
* Copy a the values contained in this map to a list.
*
* @return a list of the values contained in this map
*/
public List<V> valuesCopy() {
Collection<V> values = map.values();
return new ArrayList<V>(values);
}
/**
* Returns the value to which the specified key is mapped
*
* @param key the key whose associated value is to be returned
* @return the value to which the specified key is mapped, or
* {@code null} if this map contains no mapping for the key
*/
public V get(K key) {
return map.get(key);
}
/**
* Returns <tt>true</tt> if this map contains a mapping for the specified
* key.
* @param key key whose presence in this map is to be tested
* @return <tt>true</tt> if this map contains a mapping for the specified
* key
*/
public boolean containsKey(K key) {
return map.containsKey(key);
}
}

View File

@@ -0,0 +1,182 @@
package db.restore;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import org.apache.logging.log4j.Level;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;
import db.DBBackupRecord;
import db.DBOperatorEvent;
import db.DBRestore;
import db.DBRestoreBeanHandler;
import db.OpertProcessListener;
import kernel.util.StringUtils;
public abstract class AbstractRestoreImpl implements DBRestore, DBRestoreBeanHandler {
/**
* logger
*/
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* 事件通知
*/
protected DBOperatorEvent operatorEvent;
/**
* 备份文件后缀
* @return 备份文件后缀名
*/
protected abstract String getBackupFileSuffix();
@Override
public boolean restore(File file, Map<String, Object> params, OpertProcessListener processListener) {
if (params == null) {
params = new HashMap<String, Object>();
}
params = parserMapParams(params); // 解析参数
// operatorEvent.beforeRestore(file, params); // 操作前事件通知
boolean result = false;
try {
if (doEnvironmentCheck(file, params, processListener)) {
result = doResotre(file, params, processListener); // 执行还原操作
}
} catch (Throwable e) {
result = false;
logger.error("restore database error", e);
throw new RuntimeException(e);
} finally {
if (processListener != null) {
processListener.onExit();
}
clearAfterRestore(file, params); // 还原后清理
}
String msg = "Finished - " + (result ? "Successfully" : "Failed");
onOutputAndLog(processListener, msg, (result ? Level.INFO : Level.ERROR));
params.put("result", result); // 结果
// operatorEvent.afterRestore(file, params);
return result;
}
/**
* 还原清理工作(清除临时目录、临时文件等操作
* @param file 备份文件
* @param params 参数
*/
protected void clearAfterRestore(File file, Map<String, Object> params) {
// default do nothing
}
@Override
public boolean restore(String filePath, Map<String, Object> params, OpertProcessListener processListener) {
return restore(new File(filePath), params, processListener);
}
@Override
public boolean restore(DBBackupRecord record, Map<String, Object> params, OpertProcessListener processListener) {
Assert.isTrue(record != null && record.getFilePath() != null);
return restore(new File(record.getFilePath()), params, processListener);
}
/**
* <p>Description: 解析参数 </p>
* <p>Create Time: 2013-2-7 </p>
* @author weiminghua
* @param params 参数
* @return 参数
*/
protected abstract Map<String, Object> parserMapParams(Map<String, Object> params);
/**
* 运行环境检测
* @param file 待还原的文件
* @param params 参数
* @param processListener 监听器
* @return 结果
*/
protected boolean doEnvironmentCheck(File file, Map<String, Object> params, OpertProcessListener processListener) {
Assert.isTrue(params != null && file != null);
// TODO:doEnvironmentCheck
if (!file.exists()) {
logger.error("restore database failed for file[" + file.getPath() + "] not exists");
return false;
}
String suffix = getBackupFileSuffix();
if (-1 == file.getPath().indexOf(suffix)) {
logger.error("The file[" + file.getPath() + "] not end of [" + suffix + "]");
return false;
}
return true;
}
/**
* 执行备份
* @param file 待还原的文件
* @param params 参数
* @param processListener 监听器
* @return 结果
*/
protected abstract boolean doResotre(File file, Map<String, Object> params, OpertProcessListener processListener);
/**
* @param operatorEvent The operatorEvent to set.
*/
public void setOperatorEvent(DBOperatorEvent operatorEvent) {
this.operatorEvent = operatorEvent;
}
/**
* 输出监听,同时添加日志信息
* @param processListener 过程监听
* @param msg 日志信息
* @param log4jLevel 日志级别
*/
protected void onOutputAndLog(OpertProcessListener processListener, String msg, Level log4jLevel) {
if (StringUtils.isNullOrEmpty(msg)) {
return;
}
if (processListener != null) {
// 不支持中断
if (processListener.getOutputListener() != null) {
processListener.getOutputListener().onOutput(msg);
}
}
if (log4jLevel == null) {
try {
Thread.sleep(200); // 延迟加载信息
} catch (InterruptedException e) {
// ignore
}
return;
}
// 输出日志信息
if (Level.ERROR.equals(log4jLevel)) {
logger.error(msg);
}
else if (Level.WARN.equals(log4jLevel)) {
logger.warn(msg);
}
else if (Level.INFO.equals(log4jLevel)) {
logger.info(msg);
}
else if (Level.DEBUG.equals(log4jLevel)) {
logger.debug(msg);
}
}
}

View File

@@ -0,0 +1,241 @@
package db.restore;
import java.io.File;
import java.util.List;
import java.util.Map;
import org.apache.logging.log4j.Level;
import org.springframework.util.Assert;
import db.Constants;
import db.DBRestore;
import db.OpertProcessListener;
import db.PropertiesUtilDB;
import db.util.CMDUtil;
import db.util.FileUtil;
import db.util.ZipUtils;
import db.util.jdbc.DBTools;
import db.util.jdbc.MysqlTools;
public class MysqlRestoreImpl extends AbstractRestoreImpl {
@Override
protected String getBackupFileSuffix() {
return ".zip";
}
@Override
protected Map<String, Object> parserMapParams(Map<String, Object> params) {
Assert.notNull(params);
// 读取参数
if (params.get("ip") == null) {
// String ip = System.getProperty(DBPorperties.ENV_IP, MySQLConfig.DEFAULT_IP);
String ip = PropertiesUtilDB.getProperty("db.ip");
params.put("ip", ip);
}
if (params.get("port") == null) {
// String port = System.getProperty(DBPorperties.ENV_PORT, MySQLConfig.DEFAULT_PORT);
String port = PropertiesUtilDB.getProperty("db.port");
params.put("port", port);
}
if (params.get("databaseName") == null) {
// String databaseName = System.getProperty(DBPorperties.ENV_DBNAME, MySQLConfig.DEFAULT_DBNAME);
String databaseName = PropertiesUtilDB.getProperty("db.databaseName");
params.put("databaseName", databaseName);
}
if (params.get("username") == null) {
// String username = System.getProperty(DBPorperties.RUIJIE_JDBC_USERNAME);
String username = PropertiesUtilDB.getProperty("db.username");
params.put("username", username);
}
if (params.get("password") == null) {
// String password = System.getProperty(DBPorperties.RUIJIE_JDBC_PASSWORD);
String password = PropertiesUtilDB.getProperty("db.password");
params.put("password", password);
}
return params;
}
@Override
protected boolean doResotre(File file, Map<String, Object> params, OpertProcessListener processListener) {
Assert.notNull(params);
onOutputAndLog(processListener, "Starting restore...", Level.INFO);
String filePath = file.getAbsolutePath();
String restorePath = formatFilePath(filePath);
FileUtil.deleteDir(restorePath, true);
// 解压备份文件
ZipUtils.unZip(filePath, file.getParent() + File.separator);
// 删除旧数据
// clearOldData(params, processListener);
// 还原数据库结构
// restoreDBStruct(params, restorePath, processListener);
// 还原数据库表数据
restoreDBData(params, restorePath, processListener);
return true;
}
@Override
protected void clearAfterRestore(File file, Map<String, Object> params) {
// 数据库还原后,删除临时目录
FileUtil.deleteDir(formatFilePath(file.getAbsolutePath()), true);
}
/**
* 格式化待还原文件路径
* @param filePath 待还原文件路径
* @return 路径
*/
private String formatFilePath(String filePath) {
String restorePath = filePath.substring(0, filePath.indexOf(getBackupFileSuffix()));
restorePath = restorePath.replaceAll(Constants.FILE_SEPARATOR_REGEX, "/");
return restorePath;
}
/**
* 清除旧数据(防止数据冲突)
* @param params 参数
* @param processListener 监听器
*/
private void clearOldData(Map<String, Object> params, OpertProcessListener processListener) {
onOutputAndLog(processListener, "Clear old database data...", Level.INFO);
StringBuffer cmdBuf = new StringBuffer();
cmdBuf.append(DBTools.formatDBClientCmd("mysql", "exe"));
cmdBuf.append(" -h ").append((String) params.get("ip"));
cmdBuf.append(" -P ").append((String) params.get("port")); // 端口
cmdBuf.append(" --user=").append((String) params.get("username")); // 用户名
cmdBuf.append(" --password=").append((String) params.get("password")); // 密码
// cmdBuf.append(" --verbose -v "); // 详情信息模式
String dbName = (String) params.get("databaseName");
cmdBuf.append(" ").append("-e \"DROP DATABASE IF EXISTS ").append(dbName).append(";");
cmdBuf.append("CREATE DATABASE ").append(dbName).append(" DEFAULT CHARACTER SET utf8; \" ");
executeRuntimeCmd(cmdBuf.toString(), processListener);
}
/**
* 还原数据库结构
* @param params 参数
* @param restorePath 备份文件目录
* @param processListener 监听器
*/
private void restoreDBStruct(Map<String, Object> params, String restorePath, OpertProcessListener processListener) {
onOutputAndLog(processListener, "Restore database structs...", Level.INFO);
StringBuffer cmdBuf = new StringBuffer();
cmdBuf.append(DBTools.formatDBClientCmd("mysql", "exe"));
cmdBuf.append(" -h ").append((String) params.get("ip"));
cmdBuf.append(" -P ").append((String) params.get("port")); // 端口
cmdBuf.append(" --user=").append((String) params.get("username")); // 用户名
cmdBuf.append(" --password=").append((String) params.get("password")); // 密码
// cmdBuf.append(" --verbose -v "); // 详情信息模式
String databaseName = (String) params.get("databaseName");
cmdBuf.append(" ").append(databaseName);
cmdBuf.append(" ").append("-e \"SET FOREIGN_KEY_CHECKS=0;");
cmdBuf.append("SOURCE ").append(restorePath).append("/db_struct.sql ; \" ");
executeRuntimeCmd(cmdBuf.toString(), processListener); // 执行CMD
onOutputAndLog(processListener, "restore Structs finished", Level.DEBUG);
}
/**
* 还原数据库数据
* @param params 参数
* @param restorePath 备份文件目录
* @param processListener 监听器
*/
private void restoreDBData(Map<String, Object> params, String restorePath, OpertProcessListener processListener) {
onOutputAndLog(processListener, "Importing Data...", Level.INFO);
String ip = (String) params.get("ip");
String port = (String) params.get("port");
String databaseName = (String) params.get("databaseName");
String username = (String) params.get("username");
String password = (String) params.get("password");
StringBuffer preCmd = new StringBuffer();
preCmd.append(DBTools.formatDBClientCmd("mysql", "exe"));
preCmd.append(" -h ").append(ip);
preCmd.append(" -P ").append(port); // 端口
preCmd.append(" --user=").append(username); // 用户名
preCmd.append(" --password=").append(password); // 密码
// preCmd.append(" --verbose -v "); // 详情信息模式
preCmd.append(" ").append(databaseName);
preCmd.append(" ").append("-e ");
// 获取数据库表
List<String> tables = MysqlTools.findAllDBTables(ip, port, databaseName, username, password);
for (int index = 0; index < tables.size(); index++) {
String tableName = tables.get(index);
onOutputAndLog(processListener, "Table Restored: " + tableName, Level.INFO);
String tableDataFilePath = restorePath + "/" + tableName + ".txt";
StringBuilder cmdBuf = new StringBuilder();
cmdBuf.append(preCmd);
cmdBuf.append(" \"LOCK TABLES " + tableName + " WRITE;"); // 锁表
cmdBuf.append("SET FOREIGN_KEY_CHECKS=0;"); // 不进行外键检查
// 导入表数据
cmdBuf.append("LOAD DATA INFILE '");
cmdBuf.append(tableDataFilePath).append("'");
cmdBuf.append("INTO TABLE ").append(tableName);
cmdBuf.append(" FIELDS TERMINATED BY ',' ENCLOSED BY '\\\"';");
cmdBuf.append(" UNLOCK TABLES;").append(" \" "); // 解锁表
// cmdBuf.append("\n");
executeRuntimeCmd(cmdBuf.toString(), processListener); // 执行CMD
}
onOutputAndLog(processListener, "Importing Data finished", Level.DEBUG);
}
/**
* 执行CMD
* @param cmd cmd命令
* @param processListener 监听器
*/
private void executeRuntimeCmd(String cmd, OpertProcessListener processListener) {
try {
// if (processListener == null || processListener.getOutputListener() == null) {
// RuntimeExecutorResult result = RuntimeExecutor.execute(cmd, "GB2312");
// if (logger.isDebugEnabled()) {
// logger.debug(result.getOutput());
// logger.debug(result.getError());
// }
// }
// else {
// MessageOutputListener outputListener = new MessageOutputListener();
// RuntimeExecutor.execute(cmd, "GB2312", outputListener);
// while (!outputListener.isFinish()) {
// onOutputAndLog(processListener, outputListener.getOutputString(), null);
// }
// onOutputAndLog(processListener, outputListener.getOutputString(), null);
// }
logger.info(cmd);
String cmdResult = CMDUtil.runCMD(cmd);
logger.info("result:"+cmdResult);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) throws Exception {
DBRestore dbBack = new MysqlRestoreImpl();
String filePath = "C:\\e\\backup\\blockchain_nes_20201030161757-734.zip";
dbBack.restore(filePath, null, null);
}
}

View File

@@ -0,0 +1,302 @@
package db.support;
import java.io.File;
import java.io.FileInputStream;
import java.io.Serializable;
import java.text.DateFormat;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.Element;
import db.Constants;
import db.DBBackupRecord;
import db.DBBackupRecordService;
import db.map.CacheMap;
import db.util.ConfigUtils;
import db.util.HandleXML;
import db.util.IOUtil;
import kernel.util.DateUtils;
public class DBBackupRecordServiceImpl implements DBBackupRecordService {
/**
* LOG
*/
private Logger logger = LogManager.getLogger(this.getClass().getName());
/**
* 备份信息XML存储路径
*/
private final static String BACKUP_RECORD_XML_PATH = ConfigUtils.getBackupRecordXMLPath();
/**
* 文件锁
*/
private ReadWriteLock lock = new ReentrantReadWriteLock();
/**
* 备份信息缓存
*/
private static CacheMap<Serializable, DBBackupRecord> BKRECORD_CACHE = new CacheMap<Serializable, DBBackupRecord>();
/**
* 备份文件保存个数最大限值
*/
private static Integer MAX_LIMIT_NUM;
/**
* 默认备份文件个数最大限值
*/
private static Integer DEFAULT_MAX_LIMITNUM = 20;
@Override
public Integer getMaxLimitNum() {
if (MAX_LIMIT_NUM == null) {
MAX_LIMIT_NUM = DEFAULT_MAX_LIMITNUM;
}
return MAX_LIMIT_NUM;
}
@Override
public void setMaxLimitNum(Integer limitNum) {
if (limitNum == null) {
throw new RuntimeException("database_maxLimitNum_setting_null");
}
MAX_LIMIT_NUM = limitNum;
lock.writeLock().lock();
FileInputStream fis = null;
try {
File file = new File(BACKUP_RECORD_XML_PATH);
if (!file.exists()) {
file.createNewFile();
}
fis = new FileInputStream(BACKUP_RECORD_XML_PATH);
Document document = HandleXML.getDocument(fis, "DbBackupRecordList");
Element maxLimitNumE = (Element) document.selectSingleNode("/DbBackupRecordList/maxLimitNum");
if (maxLimitNumE == null) {
maxLimitNumE = document.getRootElement().addElement("maxLimitNum");
}
maxLimitNumE.setText(String.valueOf(MAX_LIMIT_NUM));
HandleXML.writeToXML(document, BACKUP_RECORD_XML_PATH);
} catch (Exception e) {
logger.error("error", e);
} finally {
IOUtil.closeQuietly(fis);
lock.writeLock().unlock();
}
}
@Override
public Collection<DBBackupRecord> findAll() {
return BKRECORD_CACHE.values();
}
@Override
public DBBackupRecord findByUuid(Serializable uuid) {
if (uuid == null) {
throw new RuntimeException("database_backuprecord_uuid_null");
// throw new FastFailException(MessageFormat.format("database_backuprecord_uuid_null"));
}
return BKRECORD_CACHE.get(uuid);
}
@Override
public void add(DBBackupRecord record) {
if (record == null) {
throw new RuntimeException("database_backuprecord_add_null");
// throw new FastFailException(MessageFormat.format("database_backuprecord_add_null"));
}
lock.writeLock().lock();
FileInputStream fis = null;
try {
fis = new FileInputStream(BACKUP_RECORD_XML_PATH);
Document document = HandleXML.getDocument(fis, "DbBackupRecordList");
Element root = document.getRootElement();
Element recordNode = root.addElement("DbBackupRecord");
String uuid = record.getUuid();
recordNode.addAttribute("uuid", uuid != null ? uuid : "");
Element nameNode = recordNode.addElement("name");
nameNode.setText(record.getName() != null ? record.getName() : "");
Element filePathNode = recordNode.addElement("filePath");
filePathNode.setText(record.getFilePath() != null ? record.getFilePath() : "");
DateFormat sdf = DateUtils.createDateFormat(Constants.DB_BACKUP_TIME_FORMAT);
Element timePathNode = recordNode.addElement("backupTime");
timePathNode.setText(record.getBackupTime() != null ? sdf.format(record.getBackupTime()) : "");
Element fileSizeNode = recordNode.addElement("fileSize");
fileSizeNode.setText(String.valueOf(record.getFileSize()));
Element descriptionNode = recordNode.addElement("description");
String description = record.getDescription();
descriptionNode.setText(description == null ? "" : description);
// 超过最大限制值,去除旧备份
if (BKRECORD_CACHE.size() >= getMaxLimitNum()) {
HandleXML.deleteFirstNode("/DbBackupRecordList/DbBackupRecord", document);
}
HandleXML.writeToXML(document, BACKUP_RECORD_XML_PATH);
} catch (Exception e) {
logger.error("error", e);
} finally {
IOUtil.closeQuietly(fis);
lock.writeLock().unlock();
}
putBackupRecordCache(record);
}
@Override
public void delete(Serializable uuid) {
if (uuid == null) {
throw new RuntimeException("database_backuprecord_delete_null");
// throw new FastFailException(MessageFormat.format("database_backuprecord_delete_null"));
}
DBBackupRecord record = BKRECORD_CACHE.get(uuid);
if (record == null) {
throw new RuntimeException("database_backuprecord_delete_null");
// throw new FastFailException(MessageFormat.format("database_backuprecord_delete_null"));
}
// 删除备份文件
File file = new File(record.getFilePath());
if (file.exists()) {
if (file.delete()) {
String msg = MessageFormat.format("database_backuprecord_delete_file_failed", file.getAbsoluteFile());
throw new RuntimeException(msg);
// throw new FastFailException(msg);
}
}
lock.writeLock().lock();
FileInputStream fis = null;
try {
fis = new FileInputStream(BACKUP_RECORD_XML_PATH);
Document document = HandleXML.getDocument(fis, "DbBackupRecordList");
String xpathExpression = "/DbBackupRecordList/DbBackupRecord[@uuid=\"" + uuid + "\"]";
Element ele = (Element) document.selectSingleNode(xpathExpression);
if (ele != null) {
ele.getParent().remove(ele);
}
HandleXML.writeToXML(document, BACKUP_RECORD_XML_PATH);
} catch (Exception e) {
logger.error("error", e);
} finally {
IOUtil.closeQuietly(fis);
lock.writeLock().unlock();
}
removeBackupRecordCache(uuid);
}
@Override
public int deleteByIds(Serializable[] ids) {
int count = 0;
for (Serializable id : ids) {
delete(id);
count++;
}
return count;
}
/**
* <p>Description: 存入缓存 </p>
* <p>Create Time: 2013-2-5 </p>
* @author weiminghua
* @param record 备份记录
*/
private void putBackupRecordCache(DBBackupRecord record) {
BKRECORD_CACHE.put(record.getUuid(), record);
}
/**
* <p>Description: 从缓存中删除数据 </p>
* <p>Create Time: 2013-2-5 </p>
* @author weiminghua
* @param uuid 备份记录ID
*/
private void removeBackupRecordCache(Serializable uuid) {
BKRECORD_CACHE.remove(uuid);
}
@Override
public void initialize() {
lock.readLock().lock();
FileInputStream fis = null;
try {
File file = new File(BACKUP_RECORD_XML_PATH);
if (!file.exists()) {
file.createNewFile();
}
fis = new FileInputStream(BACKUP_RECORD_XML_PATH);
Document document = HandleXML.getDocument(fis, "DbBackupRecordList");
Element maxLimitNumE = (Element) document.selectSingleNode("/DbBackupRecordList/maxLimitNum");
if (maxLimitNumE != null) {
MAX_LIMIT_NUM = Integer.parseInt(maxLimitNumE.getText());
}
// 读取已有备份信息
List<?> list = document.selectNodes("/DbBackupRecordList/DbBackupRecord");
Iterator<?> iter = list.iterator();
DateFormat sdf = DateUtils.createDateFormat(Constants.DB_BACKUP_TIME_FORMAT);
while (iter.hasNext()) {
Element e = (Element) iter.next();
DBBackupRecord record = new DBBackupRecord();
record.setUuid(e.attribute("uuid").getValue());
Element nameE = e.element("name");
if (nameE != null) {
record.setName(nameE.getText());
}
Element backupTimeE = e.element("backupTime");
if (backupTimeE != null) {
record.setBackupTime(sdf.parse(backupTimeE.getText()));
}
Element filePathE = e.element("filePath");
if (filePathE != null) {
record.setFilePath(filePathE.getText());
}
Element fileSizeE = e.element("fileSize");
if (fileSizeE != null) {
record.setFileSize(Long.valueOf(fileSizeE.getText()));
}
Element descriptionE = e.element("description");
if (descriptionE != null) {
record.setDescription(descriptionE.getText());
}
putBackupRecordCache(record); // 加入缓存
}
} catch (Exception e) {
logger.error("error", e);
} finally {
IOUtil.closeQuietly(fis);
lock.readLock().unlock();
}
}
}

View File

@@ -0,0 +1,44 @@
package db.support;
import db.OpertProcessListener;
public class DefaultOpertProcessListener implements OpertProcessListener {
/**
* 输出信息监听器
*/
private MessageOutputListener outputListener = new MessageOutputListener();
/**
* 是否结束
*/
private boolean isFinish = false;
/**
* @return 输出信息监听器
*/
@Override
public MessageOutputListener getOutputListener() {
return outputListener;
}
@Override
public void onInterrupt() {
onExit();
}
@Override
public void onExit() {
isFinish = true;
outputListener.onExit();
}
/**
* @return 是否中止
*/
@Override
public boolean isFinish() {
return isFinish;
}
}

View File

@@ -0,0 +1,63 @@
package db.support;
public class MessageOutputListener {
/**
* 输出信息缓存
*/
private StringBuffer sb = new StringBuffer();
/**
* 是否结束
*/
private boolean isFinish;
// @Override
public void onOutput(String line) {
if (sb.length() != 0) {
sb.append("\n");
}
sb.append(line);
}
public void onExit() {
this.isFinish = true;
}
/**
*
* <p>Description: 是否已经结束 </p>
* <p>Create Time: 2012-12-24 </p>
* @author wangyongdi
* @return true or false
*/
public boolean isFinish() {
return isFinish;
}
/**
*
* <p>Description: 获取输出信息以增量的形式输出。当之前的对象已经取出之后就不再保留。若执行已经结束且所有信息已经取走返回null若没有信息返回空串</p>
* <p>Create Time: 2012-12-24 </p>
* @author wangyongdi
* @return 输出的信息
*/
public String getOutputString() {
if (isFinish && sb.length() == 0) {
return null;
}
else {
String str;
if (sb.length() == 0) {
str = "";
}
else {
str = sb.toString();
sb = new StringBuffer();
}
return str;
}
}
}

View File

@@ -0,0 +1,368 @@
package db.util;
import java.io.IOException;
import java.io.InputStream;
import java.text.DateFormat;
import java.util.Date;
import java.util.Iterator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import db.Constants;
import db.PropertiesUtilDB;
import db.util.jdbc.DBTools;
import kernel.util.DateUtils;
import kernel.util.Endecrypt;
import kernel.util.StringUtils;
import kernel.util.ThreadUtils;
import project.log.SysLog;
import project.log.SysLogService;
import project.syspara.SysparaService;
public class BackupUtil {
private static transient Logger log = LoggerFactory.getLogger(BackupUtil.class);
private static String KEY = "Roj6#@08SDF87323FG00%jjsd";
/**
* 局部备份
*/
public static String TYPE_PART = "part";
/**
* 全局备份
*/
public static String TYPE_ALL = "all";
/**
* 局部+全局备份
*/
public static String TYPE_BOTH = "both";
private static Endecrypt endecrypt = new Endecrypt();
public static void main(String[] args) {
// backup(null);
// backupPart(null);
}
public static String executeLinuxCmd(String cmd) {
// System.out.println("got cmd job : " + cmd);
Runtime run = Runtime.getRuntime();
try {
Process process = null;
if(cmd.indexOf(">")!=-1||cmd.indexOf("|")!=-1||cmd.indexOf("\\")!=-1) {
String[] command = { "/bin/sh", "-c", cmd};
process = run.exec(command);
}else {
process = run.exec(cmd);
}
// Process process = run.exec(cmd);
InputStream in = process.getInputStream();
// BufferedReader bs = new BufferedReader(new InputStreamReader(in));
// System.out.println("[check] now size \n"+bs.readLine());
StringBuffer out = new StringBuffer();
byte[] b = new byte[8192];
for (int n; (n = in.read(b)) != -1;) {
out.append(new String(b, 0, n));
}
// System.out.println("job result [" + out.toString() + "]");
in.close();
// process.waitFor();
process.destroy();
return out.toString();
} catch (IOException e) {
log.error("exec cmd fail e:",e);
e.printStackTrace();
}
return null;
}
public static void backup(SysLogService sysLogService, SysparaService sysparaService) {
try {
log.info("进入全局备份 backup...");
boolean backup_all_button = sysparaService.find("backup_all_button").getBoolean();
if (!backup_all_button) {
return;
}
/**
* 保留n天的备份之前清除
*/
String backup_stay_days = sysparaService.find("backup_stay_days").getValue();
String backupType = TYPE_ALL;
log.info("开始备份...");
DateFormat sdf = DateUtils.createDateFormat(Constants.DB_BACKUP_TIME_FORMAT);
String backupName = PropertiesUtilDB.getProperty("db.database.name") + "_" + sdf.format(new Date());
executeLinuxCmd("mkdir " + PropertiesUtilDB.getProperty("db.backup.path"));
// 开始备份sql
String backupDB = backupDB(backupName);
String backResult = executeLinuxCmd(backupDB);
log.info(backResult);
// 开始压缩zip
String zip = zip(backupName);
log.info(zip);
String zipResult = executeLinuxCmd(zip);
log.info(zipResult);
// 保留n天,删除之前的zip
String clearBackup = clearBackup(backup_stay_days, backupType);
log.info(clearBackup);
String clearBackupResult = executeLinuxCmd(clearBackup);
log.info(clearBackupResult);
ThreadUtils.sleep(2000);// 等待备份完成
handleSftp(sysparaService, PropertiesUtilDB.getProperty("db.backup.path") + "/" + backupName + ".zip",
backupType, backup_stay_days);
log.info("备份完成...");
} catch (Exception e) {
// TODO: handle exception
log.error(DateUtils.format(new Date(), DateUtils.DF_yyyyMMddHHmmss) + " backup fail e:", e);
SysLog entity = new SysLog();
entity.setLevel(SysLog.level_error);
entity.setCreateTime(new Date());
entity.setLog("数据库备份失败 e:" + e);
sysLogService.saveAsyn(entity);
}
}
/**
* 备份文件发送到配置的服务
*
* @param filePath 指定文件目录
* @param sysparaService
*/
public static void handleSftp(SysparaService sysparaService, String filePath, String backupType,
String backupStayDays) throws Exception {
// String backup_server_param="[{\"ip\":\"127.0.0.1\",\"port\":\"22\",\"username\":\"root\",\"password\":\"g5xkwp8ET2WCTbtb5aAxeq2%2FQsWR3j35MbsW2bpXDhp0NsW%2BNNfzSA%3D%3D\",\"path\":\"/backup\",\"type\":\"part\"},{\"ip\":\"127.0.0.1\",\"port\":\"22\",\"username\":\"root\",\"password\":\"g5xkwp8ET2WCTbtb5aAxeq2%2FQsWR3j35MbsW2bpXDhp0NsW%2BNNfzSA%3D%3D\",\"path\":\"/backup\",\"type\":\"part\"}]";
String backup_server_param = sysparaService.find("backup_server_param").getValue();
if (StringUtils.isEmptyString(backup_server_param)) {
return;
}
JSONArray jsonArray = JSON.parseArray(backup_server_param);
Iterator<Object> iterator = jsonArray.iterator();
while (iterator.hasNext()) {
JSONObject next = (JSONObject) iterator.next();
String type = next.getString("type");
if (!type.equals(TYPE_BOTH) && !backupType.equals(type)) {
continue;
}
String sftpIp = next.getString("ip");
int sftpPort = next.getInteger("port");
String sftpUsername = next.getString("username");
String sftpPassword = endecrypt.get3DESDecrypt(next.getString("password"), KEY);
String sftpBackupPath = next.getString("path");
try {
sftp(filePath, sftpIp, sftpPort, sftpUsername, sftpPassword, sftpBackupPath, backupStayDays, backupType);
}catch (Exception e) {
// TODO: handle exception
log.error("ip:"+sftpIp+" sftp fail. e:",e);
}
}
}
/**
* 备份文件发送到指定服务
*
* @param filePath
* @param sftpIp
* @param sftpPort
* @param sftpUsername
* @param sftpPassword
* @param sftpBackupPath
* @throws Exception
*/
public static void sftp(String filePath, String sftpIp, int sftpPort, String sftpUsername, String sftpPassword,
String sftpBackupPath, String backupStayDays, String backupType) throws Exception {
SFTPUtil sftp = new SFTPUtil(sftpUsername, sftpPassword, sftpIp, sftpPort);
//1.传输中途中断2.未连接上
if(TYPE_ALL.equals(backupType)) {//全局备份
int times = 0;//次数
long start = System.currentTimeMillis();
long end = System.currentTimeMillis();
long limit = 1000 * 60 * 5;
while(true) {
try {
sftp.login(SFTPUtil.SFTP);
sftp.upload(sftpBackupPath, filePath);
break;
}catch (Exception e) {
// TODO: handle exception
times++;
end = System.currentTimeMillis();
if(times>5||(end-start)>limit) {//尝试5分钟或尝试次数大于五
log.error("尝试时间大于五分钟,或尝试次数大于五,无法传输成功",times);
throw new RuntimeException(e);
}else {
log.error("全局备份传输失败,尝试第{}次。。。",times);
}
}finally {
sftp.logout();
}
}
}else {
sftp.login(SFTPUtil.SFTP);
sftp.upload(sftpBackupPath, filePath);
sftp.logout();
}
// 保留n天删除之前的zip
String clearBackup = clearBackup(backupStayDays, backupType);
log.info("sftp:" + clearBackup);
String clearBackupResult = SFTPUtil.execCmd(sftpIp, sftpUsername,sftpPort, sftpPassword, clearBackup);
log.info(clearBackupResult);
}
/**
* 局部备份
*
* @param sysLogService
*/
public static void backupPart(SysLogService sysLogService, SysparaService sysparaService) {
try {
// log.info("进入局部备份 backupPart...");
boolean backup_part_button = sysparaService.find("backup_part_button").getBoolean();
if (!backup_part_button) {
return;
}
/**
* 保留n天的备份之前清除
*/
String backup_stay_days = sysparaService.find("backup_stay_days").getValue();
String backup_part_notable = sysparaService.find("backup_part_notable").getValue();
String backupType = TYPE_PART;
// log.info("开始局部备份...");
DateFormat sdf = DateUtils.createDateFormat(Constants.DB_BACKUP_TIME_FORMAT);
String backupName = PropertiesUtilDB.getProperty("db.database.name") + "_part_" + sdf.format(new Date());
executeLinuxCmd("mkdir " + PropertiesUtilDB.getProperty("db.backup.path"));
// 开始备份sql
String backupDB = backupPartDB(backupName, backup_part_notable);
String backResult = executeLinuxCmd(backupDB);
// log.info(backResult);
// 开始压缩zip
String zip = zip(backupName);
// log.info(zip);
String zipResult = executeLinuxCmd(zip);
// log.info(zipResult);
// 保留n天删除之前的zip
String clearBackup = clearBackup(backup_stay_days, backupType);
// log.info(clearBackup);
String clearBackupResult = executeLinuxCmd(clearBackup);
// log.info(clearBackupResult);
ThreadUtils.sleep(2000);// 等待备份完成
handleSftp(sysparaService, PropertiesUtilDB.getProperty("db.backup.path") + "/" + backupName + ".zip",
backupType, backup_stay_days);
log.info("备份完成...");
} catch (Exception e) {
// TODO: handle exception
log.error(DateUtils.format(new Date(), DateUtils.DF_yyyyMMddHHmmss) + " backup fail e:", e);
SysLog entity = new SysLog();
entity.setLevel(SysLog.level_error);
entity.setCreateTime(new Date());
entity.setLog("数据库备份失败 e:" + e);
sysLogService.saveAsyn(entity);
}
}
public static String backupDB(String backupName) {
StringBuffer cmdBuf = new StringBuffer();
cmdBuf.append(DBTools.formatDBClientCmd("mysqldump", "exe")); // 客户端命令
cmdBuf.append(" -h ").append(PropertiesUtilDB.getProperty("db.ip"));
cmdBuf.append(" -P ").append(PropertiesUtilDB.getProperty("db.port"));
cmdBuf.append(" -u").append(PropertiesUtilDB.getProperty("db.username"));
cmdBuf.append(" -p")
.append("'" + endecrypt.get3DESDecrypt(PropertiesUtilDB.getProperty("db.password"), KEY) + "'");
cmdBuf.append(" ").append(PropertiesUtilDB.getProperty("db.database.name"));
cmdBuf.append(" > ")//
// .append(DBTools.formatRuntimeCmdPath(realPath)) // 处理空格
.append(PropertiesUtilDB.getProperty("db.backup.path")).append("/").append(backupName).append(".sql");
return cmdBuf.toString();
}
public static String backupPartDB(String backupName, String noTable) {
StringBuffer cmdBuf = new StringBuffer();
cmdBuf.append(DBTools.formatDBClientCmd("mysqldump", "exe")); // 客户端命令
cmdBuf.append(" -h ").append(PropertiesUtilDB.getProperty("db.ip"));
cmdBuf.append(" -P ").append(PropertiesUtilDB.getProperty("db.port"));
cmdBuf.append(" -u").append(PropertiesUtilDB.getProperty("db.username"));
cmdBuf.append(" -p")
.append("'" + endecrypt.get3DESDecrypt(PropertiesUtilDB.getProperty("db.password"), KEY) + "'");
cmdBuf.append(" --skip-opt");// 运行中的数据库谨慎备份,忽略部分表结构参数
cmdBuf.append(" ").append(PropertiesUtilDB.getProperty("db.database.name"));
// String notable = PropertiesUtilDB.getProperty("backup.part.notable");
if (StringUtils.isNotEmpty(noTable)) {
String baseCmd = "--ignore-table=" + PropertiesUtilDB.getProperty("db.database.name") + ".";
for (String t : noTable.split(",")) {
cmdBuf.append(" ").append(baseCmd + t);
}
}
cmdBuf.append(" > ")//
// .append(DBTools.formatRuntimeCmdPath(realPath)) // 处理空格
.append(PropertiesUtilDB.getProperty("db.backup.path")).append("/").append(backupName).append(".sql");
return cmdBuf.toString();
}
public static String zip(String backupName) {
// String zip="zip -m /home/demo7.zip /home/demo7.sql";
StringBuffer cmdBuf = new StringBuffer();
cmdBuf.append("zip"); // 客户端命令
cmdBuf.append(" -m ").append(PropertiesUtilDB.getProperty("db.backup.path")).append("/").append(backupName)
.append(".zip");
cmdBuf.append(" ").append(PropertiesUtilDB.getProperty("db.backup.path")).append("/").append(backupName)
.append(".sql");
return cmdBuf.toString();
}
/**
* 清除超时备份
*
* @param days 备份保留时间
* @return
*/
public static String clearBackup(String days, String backupType) {
// find /backup/test -mtime +2 -type f -name *.txt -exec rm {} \;
// StringBuffer cmdBuf = new StringBuffer("find /backup -mmin +120 -type f -name *.zip -exec rm {} \\;");
StringBuffer cmdBuf = new StringBuffer();
cmdBuf.append(" find ").append(PropertiesUtilDB.getProperty("db.backup.path"));
cmdBuf.append(" -mtime ").append("+" + days);
String dbName = PropertiesUtilDB.getProperty("db.database.name") + "_part_";
if (backupType.equals(TYPE_ALL)) {// 优先处理part全局的匹配了再处理
dbName = PropertiesUtilDB.getProperty("db.database.name") + "_";
}
cmdBuf.append(" -type f -name '" + dbName + "*.zip' -exec rm {} \\; ");
return cmdBuf.toString();
}
// public static void sftpPart(String filePath) throws Exception {
// String sftpBackupPath = PropertiesUtilDB.getProperty("sftp.backup.path");
// String sftpUsername = PropertiesUtilDB.getProperty("sftp.username");
// String sftpPassword = endecrypt.get3DESDecrypt(PropertiesUtilDB.getProperty("sftp.password"), KEY);
// String sftpIp = PropertiesUtilDB.getProperty("sftp.ip");
// int sftpPort = Integer.valueOf(PropertiesUtilDB.getProperty("sftp.port"));
// SFTPUtil sftp = new SFTPUtil(sftpUsername, sftpPassword, sftpIp, sftpPort);
// sftp.login(SFTPUtil.SFTP);
// sftp.upload(sftpBackupPath, filePath);
// sftp.logout();
//
// // 保留n天删除之前的zip
// String clearBackup = clearBackup(2,);
// log.info("sftp:" + clearBackup);
// String clearBackupResult = SFTPUtil.execCmd(sftpIp, sftpUsername, sftpPassword, clearBackup);
// log.info(clearBackupResult);
// }
}

View File

@@ -0,0 +1,52 @@
package db.util;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class CMDUtil {
public static String runCMD(String cmd) throws IOException {
// ProcessBuilder是一个用于创建操作系统进程的类它的start()方法用于启动一个进行
ProcessBuilder processBuilder = new ProcessBuilder(cmd);
// 启动进程
Process process = processBuilder.start();
// 解析输出
String result = convertStreamToStr(process.getInputStream());
// System.out.println(result);
return result;
}
public static String runCMD(List<String> commandList) throws IOException {
// 创建命令集合
// ProcessBuilder是一个用于创建操作系统进程的类它的start()方法用于启动一个进行
ProcessBuilder processBuilder = new ProcessBuilder(commandList);
// 启动进程
Process process = processBuilder.start();
// 解析输出
String result = convertStreamToStr(process.getInputStream());
// System.out.println(result);
return result;
}
public static String convertStreamToStr(InputStream is) throws IOException {
if (is != null) {
Writer writer = new StringWriter();
char[] buffer = new char[1024];
try {
Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
int n;
while ((n = reader.read(buffer)) != -1) {
writer.write(buffer, 0, n);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
is.close();
}
return writer.toString();
} else {
return "";
}
}
}

View File

@@ -0,0 +1,52 @@
package db.util;
import java.io.File;
import db.SupportDBTypeEnum;
public class ConfigUtils {
/**
* 当前数据库类型
*/
private static SupportDBTypeEnum CURRENT_DB_TYPE = null;
/**
* 当前数据库类型(默认mysql)
*
* @return The current database type
*/
public static SupportDBTypeEnum getCurrentDBType() {
if (CURRENT_DB_TYPE == null) {
String dbName = System.getProperty("components.ha.database.DBType", //
SupportDBTypeEnum.mysql.name()); // 默认mysql
CURRENT_DB_TYPE = SupportDBTypeEnum.getEnum(dbName);
}
return CURRENT_DB_TYPE;
}
/**
* 数据库备份信息XML路径(文件数据库)
* @return 文件数据库路径
*/
public static String getBackupRecordXMLPath() {
String databasePath = PathUtil.getDatabasePath();
String backupRecordXML = System.getProperty("components.ha.database.backupRecordXML", "");
if ("".equals(backupRecordXML)) {
backupRecordXML = databasePath + File.separator + "backupRecords.xml";
}
return backupRecordXML;
}
/**
* 数据库客户端程序安装bin目录支持空格
*
* @return The installation directory
*/
public static String getDBInstalledPath() {
return System.getProperty("components.ha.database.installedPath", null);
}
}

150
comm/DB/src/db/util/FileUtil.java Executable file
View File

@@ -0,0 +1,150 @@
package db.util;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.DecimalFormat;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class FileUtil {
/**
* Member Description
*/
private static Logger logger = LogManager.getLogger(FileUtil.class);
/** .
* 文件字符集
*/
private static final String CHARSET_NAME = "UTF-8";
/**
* <p>Description: 将内容写入指定文件 </p>
* <p>Create Time: </p>
* @param fileContent 内容
* @param filePath 文件路径
*/
public static void string2File(String fileContent, String filePath) {
FileOutputStream fos = null;
try {
File outFile = new File(filePath);
if (!outFile.exists()) {
outFile.createNewFile();
}
fos = new FileOutputStream(outFile);
fos.write(fileContent.getBytes(CHARSET_NAME), 0, fileContent.getBytes(CHARSET_NAME).length);
} catch (Exception e) {
logger.error("The string2File[" + filePath + "] ERROR", e);
} finally {
IOUtil.closeQuietly(fos);
}
}
/**
* 读取文件
* @param ins 文件流
* @return 文件内容
* @throws Exception 异常
*/
public static String readStringAndClose(InputStream ins) throws Exception {
StringBuilder buf = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(ins, "UTF-8"));
String lineStr = null;
while ((lineStr = br.readLine()) != null) {
buf.append(lineStr).append("\n");
}
if (br != null) {
br.close();
}
if (ins != null) {
ins.close();
}
return buf.toString();
}
/**
* 删除目录下的文件
* @param path 目录名
* @param isDeleteSelf 是否删除目录自身
*/
public static void deleteDir(String path, boolean isDeleteSelf) {
File dir = new File(path);
// 检查参数
if (dir == null || !dir.exists() || !dir.isDirectory()) {
return;
}
for (File file : dir.listFiles()) {
if (file.isFile()) {
// 删除所有文件
file.delete();
}
else if (file.isDirectory()) {
// 递规的方式删除文件夹
deleteDir(file.getPath(), true);
}
}
// 删除目录本身
if (isDeleteSelf) {
dir.delete();
}
}
/**
* 获取文件大小
* @param filePath 文件路径
* @return 文件大小
* @throws FileNotFoundException 文件不存在
*/
public static long getFileSize(String filePath) throws FileNotFoundException {
File file = new File(filePath);
long size = 0;
if (file.exists()) {
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
size = fis.available();
} catch (Exception e) {
} finally {
IOUtil.closeQuietly(fis);
}
} else {
throw new FileNotFoundException();
}
return size;
}
/**
* 转换文件大小格式
* @param fileSize 文件大小
* @param df 格式
* @return 文件大小格式
*/
public static String formetFileSize(long fileSize, DecimalFormat df) {
if (df == null) {
df = new DecimalFormat("#.000");
}
String result = "";
if (fileSize < 1024) {
result = df.format((double) fileSize) + "B";
}
else if (fileSize < 1048576) { // 1024*1024
result = df.format((double) fileSize / 1024) + "K";
}
else if (fileSize < 1073741824) { // 1024*1024*1024
result = df.format((double) fileSize / 1048576) + "M";
}
else { // 1024*1024*1024*1024
result = df.format((double) fileSize / 1073741824) + "G";
}
return result;
}
}

View File

@@ -0,0 +1,92 @@
package db.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.List;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
public class HandleXML {
/**
* logger
*/
private static Logger logger = LogManager.getLogger(HandleXML.class);
/**
* <p>Description: XML Document 写入文件 </p>
* <p>Create Time: </p>
* @param document XML Document
* @param filePath 文件路径
* @throws Exception 异常
*/
public static void writeToXML(Document document, String filePath) throws Exception {
OutputStream os = null;
try {
File file = new File(filePath);
if (!file.exists()) {
file.createNewFile();
}
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8"); // 设置XML文件的编码格式
os = new FileOutputStream(filePath);
XMLWriter xmlout = new XMLWriter(os, format);
xmlout.write(document);
xmlout.close();
} catch (Exception e) {
logger.error("write to xml [" + filePath + "] error", e);
throw new Exception(e);
} finally {
IOUtil.closeQuietly(os);
}
}
/**
* <p>Description: Get XML Document </p>
* <p>Create Time: 2013-2-6 </p>
* @param fis 文件输入流
* @param rootName 根节点名称
* @return XML Document
*/
public static Document getDocument(FileInputStream fis, String rootName) {
Document document = null;
try {
SAXReader saxReader = new SAXReader();
document = saxReader.read(fis);
} catch (DocumentException e) {
document = DocumentHelper.createDocument();
document.addElement(rootName); // root
}
return document;
}
/**
* <p>Description: 删除XML Document查找到的第一条记录 </p>
* <p>Create Time: 2013-2-6 </p>
* @author weiminghua
* @param xpathExpression 匹配正则
* @param document XML Document
* @return 删除结果
*/
public static boolean deleteFirstNode(String xpathExpression, Document document) {
List<?> list = document.selectNodes(xpathExpression);
if (list.size() > 0) {
Element e = (Element) list.get(0);
return e.getParent().remove(e);
}
return false;
}
}

40
comm/DB/src/db/util/IOUtil.java Executable file
View File

@@ -0,0 +1,40 @@
package db.util;
import java.io.InputStream;
import java.io.OutputStream;
public class IOUtil {
/**
* <p>Description: 关闭输入流 </p>
* @param is inputStream
*/
public static void closeQuietly(InputStream is) {
if (is == null) {
return;
}
try {
is.close();
} catch (Throwable e) {
// do nothing
}
}
/**
* <p>Description: 关闭输出流 </p>
* @param os outputStream
*/
public static void closeQuietly(OutputStream os) {
if (os == null) {
return;
}
try {
os.close();
} catch (Throwable e) {
// do nothing
}
}
}

View File

@@ -0,0 +1,96 @@
package db.util;
import java.io.File;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import db.PropertiesUtilDB;
public class PathUtil {
/**
* logger
*/
private static Logger logger = LogManager.getLogger(PathUtil.class);
/**
* database组件操作路径
*/
private static String DATABASE_PATH;
/**
* 数据库备份文件存储路径
*/
private static String DB_BACKUP_PATH;
/**
* 数据库备份的工具路径
*/
private static String DB_TOOLS_PATH;
/**
* database组件操作目录下tools路径
*
* @return Returns the databasePath.
*/
public static String getDatabasePath() {
if (DATABASE_PATH == null) {
// DATABASE_PATH = getAppRootPath() + File.separator + "database";
// DATABASE_PATH = File.separator + "database";
// DATABASE_PATH = "C:\\e";
DATABASE_PATH = PropertiesUtilDB.getProperty("db.backup.path");
File f = new File(DATABASE_PATH);
if (!f.exists()) {
f.mkdirs();
}
if (logger.isDebugEnabled()) {
logger.debug("DatabasePath = " + DATABASE_PATH);
}
}
return DATABASE_PATH;
}
/**
* 数据库备份文件存储路径
*
* @return Returns the dbBackupPath.
*/
public static String getDbBackupPath() {
if (DB_BACKUP_PATH == null) {
DB_BACKUP_PATH = getDatabasePath() + File.separator + "backup";
File f = new File(DB_BACKUP_PATH);
if (!f.exists()) {
f.mkdirs();
}
if (logger.isDebugEnabled()) {
logger.debug("Database backupPath = " + DB_BACKUP_PATH);
}
}
return DB_BACKUP_PATH;
}
/**
* database组件操作目录下tools路径
*
* @return dbToolsPath
*/
public static String getDbToolsPath() {
if (DB_TOOLS_PATH == null) {
DB_TOOLS_PATH = getDatabasePath() + File.separator + "tools";
File f = new File(DB_TOOLS_PATH);
if (!f.exists()) {
f.mkdir();
}
if (logger.isDebugEnabled()) {
logger.debug("Database toolsPath = " + DB_TOOLS_PATH);
}
}
return DB_TOOLS_PATH;
}
}

441
comm/DB/src/db/util/SFTPUtil.java Executable file
View File

@@ -0,0 +1,441 @@
package db.util;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Properties;
import java.util.Vector;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
public class SFTPUtil {
private transient Logger log = LoggerFactory.getLogger(this.getClass());
private ChannelSftp sftp;
private ChannelExec exec;
public static final String SFTP = "sftp";
public static final String SHELL = "exec";
private Session session;
/** FTP 登录用户名 */
private String username;
/** FTP 登录密码 */
private String password;
/** 私钥 */
private String privateKey;
/** FTP 服务器地址IP地址 */
private String host;
/** FTP 端口 */
private int port;
/**
* 构造基于密码认证的sftp对象
*
* @param userName
* @param password
* @param host
* @param port
*/
public SFTPUtil(String username, String password, String host, int port) {
this.username = username;
this.password = password;
this.host = host;
this.port = port;
}
/**
* 构造基于秘钥认证的sftp对象
*
* @param userName
* @param host
* @param port
* @param privateKey
*/
public SFTPUtil(String username, String host, int port, String privateKey) {
this.username = username;
this.host = host;
this.port = port;
this.privateKey = privateKey;
}
public SFTPUtil() {
}
/**
* 连接sftp服务器
*
* @throws Exception
*/
public void login(String type) {
try {
JSch jsch = new JSch();
if (privateKey != null) {
jsch.addIdentity(privateKey);// 设置私钥
// log.info("sftp connect,path of private key file{}" , privateKey);
}
// log.info("sftp connect by host:{} username:{}",host,username);
session = jsch.getSession(username, host, port);
// log.info("Session is build");
if (password != null) {
session.setPassword(password);
}
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
// log.info("Session is connected");
Channel channel = session.openChannel(type);
channel.connect();
if (SFTP.equals(type)) {
log.info("sftp channel is connected");
sftp = (ChannelSftp) channel;
} else if (SHELL.equals(type)) {
log.info("shell channel is connected");
exec = (ChannelExec) channel;
}
// Channel channel = session.openChannel("sftp");
// log.info(String.format("sftp server host:[%s] port:[%s] is connect successfull", host, port));
} catch (JSchException e) {
// log.error("Cannot connect to specified sftp server : {}:{} \n Exception message is: {}", new Object[]{host, port, e.getMessage()});
log.error("Cannot connect to specified sftp server \n Exception message is: {}",
new Object[] { e.getMessage() });
}
}
/**
* 关闭连接 server
*/
public void logout() {
if (sftp != null) {
if (sftp.isConnected()) {
sftp.disconnect();
log.info("sftp is closed already");
}
}
if (session != null) {
if (session.isConnected()) {
session.disconnect();
log.info("sshSession is closed already");
}
}
}
/**
* 将输入流的数据上传到sftp作为文件
*
* @param directory 上传到该目录
* @param sftpFileName sftp端文件名
* @param in 输入流
* @throws SftpException
* @throws Exception
*/
public void upload(String directory, String sftpFileName, InputStream input) throws SftpException {
try {
sftp.cd(directory);
} catch (SftpException e) {
log.warn("directory is not exist");
sftp.mkdir(directory);
sftp.cd(directory);
}
sftp.put(input, sftpFileName);
log.info("file:{} is upload successful", sftpFileName);
}
/**
* 上传单个文件
*
* @param directory 上传到sftp目录
* @param uploadFile 要上传的文件,包括路径
* @throws FileNotFoundException
* @throws SftpException
* @throws Exception
*/
public void upload(String directory, String uploadFile) throws FileNotFoundException, SftpException {
File file = new File(uploadFile);
upload(directory, file.getName(), new FileInputStream(file));
}
/**
* 将byte[]上传到sftp作为文件。注意:从String生成byte[]是,要指定字符集。
*
* @param directory 上传到sftp目录
* @param sftpFileName 文件在sftp端的命名
* @param byteArr 要上传的字节数组
* @throws SftpException
* @throws Exception
*/
public void upload(String directory, String sftpFileName, byte[] byteArr) throws SftpException {
upload(directory, sftpFileName, new ByteArrayInputStream(byteArr));
}
/**
* 将字符串按照指定的字符编码上传到sftp
*
* @param directory 上传到sftp目录
* @param sftpFileName 文件在sftp端的命名
* @param dataStr 待上传的数据
* @param charsetName sftp上的文件按该字符编码保存
* @throws UnsupportedEncodingException
* @throws SftpException
* @throws Exception
*/
public void upload(String directory, String sftpFileName, String dataStr, String charsetName)
throws UnsupportedEncodingException, SftpException {
upload(directory, sftpFileName, new ByteArrayInputStream(dataStr.getBytes(charsetName)));
}
/**
* 下载文件
*
* @param directory 下载目录
* @param downloadFile 下载的文件
* @param saveFile 存在本地的路径
* @throws SftpException
* @throws FileNotFoundException
* @throws Exception
*/
public void download(String directory, String downloadFile, String saveFile)
throws SftpException, FileNotFoundException {
if (directory != null && !"".equals(directory)) {
sftp.cd(directory);
}
File file = new File(saveFile);
sftp.get(downloadFile, new FileOutputStream(file));
log.info("file:{} is download successful", downloadFile);
}
/**
* 下载文件
*
* @param directory 下载目录
* @param downloadFile 下载的文件名
* @return 字节数组
* @throws SftpException
* @throws IOException
* @throws Exception
*/
public byte[] download(String directory, String downloadFile) throws SftpException, IOException {
if (directory != null && !"".equals(directory)) {
sftp.cd(directory);
}
InputStream is = sftp.get(downloadFile);
byte[] fileData = IOUtils.toByteArray(is);
log.info("file:{} is download successful", downloadFile);
return fileData;
}
/**
* 删除文件
*
* @param directory 要删除文件所在目录
* @param deleteFile 要删除的文件
* @throws SftpException
* @throws Exception
*/
public void delete(String directory, String deleteFile) throws SftpException {
sftp.cd(directory);
sftp.rm(deleteFile);
}
/**
* 列出目录下的文件
*
* @param directory 要列出的目录
* @param sftp
* @return
* @throws SftpException
*/
public Vector<?> listFiles(String directory) throws SftpException {
return sftp.ls(directory);
}
public String execCmd(String cmd) {
String result = null;
try {
// 获取输入流和输出流
InputStream in = exec.getInputStream();
exec.setCommand(cmd);
exec.connect();
byte[] tmp = new byte[1024];
while (true) {
while (in.available() > 0) {
int i = in.read(tmp, 0, 1024);
if (i < 0)
break;
result = new String(tmp, 0, i);
}
if (exec.isClosed()) {
break;
}
try {
Thread.sleep(1000);
} catch (Exception e) {
result = e.toString();
}
}
} catch (Exception e) {
e.printStackTrace();
// log.error(e.getMessage(), e);
}
return result;
}
/**
* 执行远程命令
*
* @param ip
* @param user
* @param psw
* @throws Exception
*/
public static String execCmd(String ip, String user, String psw, String cmd) throws Exception {
// 连接服务器,采用默认端口
JSch jsch = new JSch();
Session session = jsch.getSession(user, ip);
Channel channel = connect(session, psw, SHELL);
String result = null;
try {
ChannelExec channelExec = (ChannelExec) channel;
// 获取输入流和输出流
InputStream in = channel.getInputStream();
channelExec.setCommand(cmd);
channelExec.connect();
byte[] tmp = new byte[1024];
while (true) {
while (in.available() > 0) {
int i = in.read(tmp, 0, 1024);
if (i < 0)
break;
result = new String(tmp, 0, i);
}
if (channel.isClosed()) {
break;
}
try {
Thread.sleep(1000);
} catch (Exception e) {
result = e.toString();
}
}
} catch (Exception e) {
e.printStackTrace();
// log.error(e.getMessage(), e);
} finally {
session.disconnect();
channel.disconnect();
}
return result;
}
/**
* 执行远程命令
*
* @param ip
* @param user
* @param psw
* @throws Exception
*/
public static String execCmd(String ip, String user, int port, String psw, String cmd) throws Exception {
// 连接服务器,采用默认端口
JSch jsch = new JSch();
Session session = jsch.getSession(user, ip, port);
Channel channel = connect(session, psw, SHELL);
String result = null;
try {
ChannelExec channelExec = (ChannelExec) channel;
// 获取输入流和输出流
InputStream in = channel.getInputStream();
channelExec.setCommand(cmd);
channelExec.connect();
byte[] tmp = new byte[1024];
while (true) {
while (in.available() > 0) {
int i = in.read(tmp, 0, 1024);
if (i < 0)
break;
result = new String(tmp, 0, i);
}
if (channel.isClosed()) {
break;
}
try {
Thread.sleep(1000);
} catch (Exception e) {
result = e.toString();
}
}
} catch (Exception e) {
e.printStackTrace();
// log.error(e.getMessage(), e);
} finally {
session.disconnect();
channel.disconnect();
}
return result;
}
/**
* 连接服务器
*
* @param session
* @param psw
* @param type
* @return
* @throws Exception
*/
private static Channel connect(Session session, String psw, String type) throws Exception {
// 如果服务器连接不上,则抛出异常
if (session == null) {
throw new Exception("session is null");
}
// 设置登陆主机的密码
session.setPassword(psw);// 设置密码
// 设置第一次登陆的时候提示,可选值:(ask | yes | no)
session.setConfig("StrictHostKeyChecking", "no");
// 设置登陆超时时间
session.connect(30000);
// 创建通信通道
return session.openChannel(type);
}
public static void main(String[] args) throws Exception {
// String sftpUsername= PropertiesUtilDB.getProperty("backup.username");
// String sftpPassword= PropertiesUtilDB.getProperty("backup.password");
// String sftpIp= PropertiesUtilDB.getProperty("backup.ip");
// int sftpPort= Integer.valueOf(PropertiesUtilDB.getProperty("backup.port"));
// SFTPUtil sftp = new SFTPUtil(sftpUsername, sftpPassword, sftpIp, sftpPort);
// sftp.login(SFTPUtil.SHELL);
// sftp.execCmd(cmd);
// sftp.logout();
}
}

View File

@@ -0,0 +1,20 @@
package db.util;
import org.hibernate.id.UUIDHexGenerator;
public class UUIDGenerator {
/**
* UUID生成器
*/
private static UUIDHexGenerator UUID_GENERATOR = new UUIDHexGenerator();
/**
* <p>Description: 生成UUID </p>
* @return UUID
*/
public static String getUUID() {
return (String) UUID_GENERATOR.generate(null, null);
}
}

132
comm/DB/src/db/util/ZipUtils.java Executable file
View File

@@ -0,0 +1,132 @@
package db.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class ZipUtils {
/**
* logger
*/
private static Logger logger = LogManager.getLogger(ZipUtils.class);
/**
* <p>Description: 压缩文件 </p>
*
* @param zname 生成文件名
* @param source 待压缩文件
*/
public static void createZip(String zname, String source) {
logger.info("start compressing backup files...");
try {
File filezip = new File(zname);
if (!filezip.exists()) {
filezip.createNewFile();
}
ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(zname));
compressFile(zout, "", new File(source));
zout.close();
logger.info("compress backup files finished");
} catch (Exception e) {
logger.error("compress backup files error", e);
}
}
/**
* <p>Description: 压缩文件 </p>
*
* @param zout ZipOutputStream
* @param dir 相对路径
* @param source 源文件
* @throws IOException ioException
*/
private static void compressFile(ZipOutputStream zout, String dir, File source) throws IOException {
if (logger.isDebugEnabled()) {
logger.debug("do compressing file:" + source);
}
if (source.isDirectory()) {
File[] fs = source.listFiles();
dir = dir + (dir.length() == 0 ? "" : "/") + source.getName();
for (File f : fs) {
compressFile(zout, dir, f);
}
}
else {
dir = dir.length() == 0 ? "" : dir + "/" + source.getName();
ZipEntry entry = new ZipEntry(dir);
// ZipEntry entry = new ZipEntry(source.getName());
zout.putNextEntry(entry);
FileInputStream fin = new FileInputStream(source);
int size = 0;
byte[] buf = new byte[10240];
while ((size = fin.read(buf, 0, 10240)) != -1) {
zout.write(buf, 0, size);
}
fin.close();
}
}
/**
* <p>Description: 解压文件 </p>
*
* @param source 源文件
* @param destdir 目的目录
*/
public static void unZip(String source, String destdir) {
try {
logger.info("start decompressing backup files...");
FileInputStream fin = new FileInputStream(source);
ZipInputStream zin = new ZipInputStream(fin);
ZipEntry entry = null;
while ((entry = zin.getNextEntry()) != null) {
File filename = new File(destdir + entry.getName());
if (logger.isDebugEnabled()) {
// System.out.println("正在解压" + entry.getName());
logger.debug("do decompressing file:" + entry.getName());
}
File path = new File(filename.getParentFile().getPath()); // 确认目标目录存在、解压文件夹存在
if (entry.isDirectory()) {
if (!filename.exists()) {
filename.mkdirs();
}
zin.closeEntry();
continue;
}
if (!path.exists()) {
path.mkdirs();
}
FileOutputStream fout = new FileOutputStream(filename); // 得到目标文件流
int size = 0;
byte[] buf = new byte[256];
while ((size = zin.read(buf)) != -1) { // 每个entry都有一个文件末尾的标识
fout.write(buf, 0, size);
}
zin.closeEntry();
fout.close();
}
fin.close();
zin.close();
// System.out.println("解压完成!");
logger.info("decompress backup files finished");
} catch (Exception e) {
logger.error("decompress backup files error", e);
}
}
}

View File

@@ -0,0 +1,39 @@
package db.util.jdbc;
import db.util.ConfigUtils;
import kernel.util.StringUtils;
public class DBTools {
/**
* 处理有配置数据库安装目录情况、(通用方法)
* <pre>说明不适用于SQL Server</pre>
*
* @param cmd 客户端命令
* @param suffix 客户端程序后缀
* @return 客户端命令 with 执行路径
*/
public static String formatDBClientCmd(String cmd, String suffix) {
String installedPath = ConfigUtils.getDBInstalledPath();
if (StringUtils.isNullOrEmpty(installedPath)) {
return cmd;
}
return new StringBuffer(formatRuntimeCmdPath(installedPath)) // 空格处理
.append("/").append(cmd).append(".").append(suffix).toString();
}
/**
* Runtime CMD 空格路径处理
*
* @param path 路径
* @return 空格前后加\" \"
*/
public static String formatRuntimeCmdPath(String path) {
if (path.indexOf(" ") != -1) {
path = path.replaceAll(" ", "\" \""); // 空格处理
}
return path;
}
}

View File

@@ -0,0 +1,64 @@
package db.util.jdbc;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowCallbackHandler;
public class MysqlTools {
/**
* 获取所有数据库表(BASE TABLE)
* @param ip 数据库IP地址
* @param port 数据库端口
* @param databaseName 数据库名
* @param username 用户名
* @param password 密码
* @return 数据库中的所有表
*/
public static List<String> findAllDBTables(String ip, String port, String databaseName, String username,
String password) {
final List<String> tables = new ArrayList<String>();
String sql = "select TABLE_NAME from TABLES where TABLE_SCHEMA = '" + databaseName
+ "' and TABLE_TYPE ='BASE TABLE'";
JdbcTemplate jt = new JdbcTemplate(createDataSource(ip, port, "information_schema", username, password));
jt.query(sql, new RowCallbackHandler() {
public void processRow(ResultSet rs) throws SQLException {
if (rs != null) {
tables.add(rs.getString(1));
}
}
});
return tables;
}
/**
* 建立数据库连接
* jdbc:mysql://${db.host}:3306
* @param ip 数据库IP地址
* @param port 数据库端口
* @param databaseName 数据库名
* @param username 用户名
* @param password 密码
* @return 数据库连接
*/
public static BasicDataSource createDataSource(String ip, String port, String databaseName, String username,
String password) {
BasicDataSource ds = new BasicDataSource();
// ds.setDriverClassName(MySQLConfig.DRIVERCLASSNAME);
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://" + ip + ":" + port + "/" + databaseName + "?characterEncoding=utf8");
ds.setUsername(username);
ds.setPassword(password);
ds.setTestOnBorrow(true);
ds.setValidationQuery("select 1 ");
return ds;
}
}