通过Java备份Oracle数据库和还原Oracle的方法
2015-11-27 17:56
661 查看
一、通过Java备份数据库
1、定义DBContext接口
public interface DBContext { /** * 解析JdbcUrl * * @param url * @param info */ public void parseJdbcUrl(String url, DataSourceInfo info); /** * 备份数据库 * * @param userName * 数据库用户名 * @param password * 数据密码 * @param dbName * 数据库实例名 * @param host * 连接数据库的ip * @param dumpFile * 备份文件名(全路径) * @param tableNameList * 待备份的数据库表名 * @return void * @throws Exception */ public void backupDB(String userName, String password, String dbName, String host, String dumpFile, List<String> tableNameList) throws Exception; /** * 还原数据库 * * @param userName * 数据库用户名 * @param password * 数据密码 * @param dbName * 数据库实例名 * @param host * 连接数据库的ip * @param backupFile * 已备份的数据库文件(全路径) * @param ignoreTables * 待备份的数据库表名 * @return void * @throws Exception */ public void restoreDB(String userName, String password, String dbName, String host, String backupFile) throws Exception; }
2、DBContext实现类
public class OracleDBContext implements DBContext { // 日志 Logger log = Logger.getLogger(OracleDBContext.class); /** * 解析oracle连接jdbc的url * * @return void */ public void parseJdbcUrl(String url, DataSourceInfo info) { int end = url.indexOf("?"); end = (end == -1) ? url.length() : end; url = url.substring(0, end); int start = url.lastIndexOf(":"); String dbName = url.substring(start + 1); url = url.substring(0, start); url = url.substring(url.lastIndexOf("@") + 1); String[] s = url.split(":"); info.setDbName(dbName); info.setHost(s[0]); info.setPort(Integer.parseInt(s[1])); } public void backupDB(String userName, String password, String dbName, String host, String dumpFile, List<String> tableNameList) throws Exception { StringBuffer stringBuffer = new StringBuffer(); // 用户名 stringBuffer.append("exp "); stringBuffer.append(userName); stringBuffer.append("/"); // 密码 stringBuffer.append(password); stringBuffer.append("@"); // 连接数据库的ip stringBuffer.append(host); stringBuffer.append("/"); // 数据库名称 stringBuffer.append(dbName); stringBuffer.append(" file="); stringBuffer.append(dumpFile); // 导出权限 stringBuffer.append(" grants=y"); // 按照用户全部导出 stringBuffer.append(" owner="); stringBuffer.append(userName); // 按照指定表名导出 /*stringBuffer.append(" tables=("); for (int i = 0; i < tableNameList.size(); i++) { stringBuffer.append(tableNameList.get(i)); if (i < tableNameList.size() - 1) { stringBuffer.append(","); } } stringBuffer.append(")");*/ String cmdStr = stringBuffer.toString(); // 得到jvm的运行环境 Runtime rt = Runtime.getRuntime(); // 在单独的进程中执行指定的字符串命令。 Process process = rt.exec(cmdStr); // 处理进程挂起 String line = null; BufferedReader br = new BufferedReader(new InputStreamReader(process.getErrorStream())); //读取ErrorStream很关键,这个解决了挂起的问题。 while ((line = br.readLine()) != null){ log.info(line); } // 导致当前线程等待,如有必要,一直要等到由该 Process 对象表示的进程已经终止。 process.waitFor(); } public void restoreDB(String userName, String password, String dbName, String host, String backupFile) throws Exception { StringBuffer stringBuffer = new StringBuffer(); // 用户名 stringBuffer.append("imp "); stringBuffer.append(userName); stringBuffer.append("/"); // 密码 stringBuffer.append(password); stringBuffer.append("@"); // 连接数据库的ip stringBuffer.append(host); stringBuffer.append("/"); // 数据库名称 stringBuffer.append(dbName); // 备份文件路径 stringBuffer.append(" file="); stringBuffer.append(backupFile); stringBuffer.append(" ignore=y full=y grants=y"); String cmdStr = stringBuffer.toString(); // 得到jvm的运行环境 Runtime rt = Runtime.getRuntime(); // 在单独的进程中执行指定的字符串命令。 Process process = rt.exec(cmdStr); // 处理进程挂起 String line = null; BufferedReader br = new BufferedReader(new InputStreamReader(process.getErrorStream())); //读取ErrorStream很关键,这个解决了挂起的问题。 while ((line = br.readLine()) != null){ log.info(line); } // 导致当前线程等待,如有必要,一直要等到由该 Process 对象表示的进程已经终止。 process.waitFor(); } }
3、用于解析数据库配置信息的工具类
public class DBTool { // 私有的构造方法 private DBTool() { } /** * 得到数据库类型 * * @return String */ public static String getDataBaseType() { String dataBaseType = null; // 获取当前色sessionFactory LocalSessionFactoryBean sessionFactory = getLocalSessionFactoryBean(); if (null != sessionFactory) { // 通过sessionFactory获取数据源 DataSource dataSource = sessionFactory.getDataSource(); // spring里的c3p0数据源 if (dataSource instanceof ComboPooledDataSource) { ComboPooledDataSource comboPooledDataSource = (ComboPooledDataSource) dataSource; // 数据库驱动信息 String driveClass = comboPooledDataSource.getDriverClass(); // 根据数据库驱动信息判断连接的数据库类型 if (null != driveClass) { if (driveClass.indexOf("postgresql") > -1) { dataBaseType = "postgresql"; } else if (driveClass.indexOf("OracleDriver") > -1) { dataBaseType = "oracle"; } } } } return dataBaseType; } /** * 是否是postgreSQL * * @return boolean */ public static boolean isPostgreSQL() { return "postgresql".equals(getDataBaseType()); } /** * 是否是oracle * * @return boolean */ public static boolean isOracle() { return "oracle".equals(getDataBaseType()); } /** * 得到数据库上下文 * * @author chenweiyf2 * @return DBContext */ public static DBContext getDBContext() { if (isPostgreSQL()) { return new PostgreSQLDBContext(); } else { return new OracleDBContext(); } } /** * 获取连接数据库信息 * * @return DataSourceInfo */ public static DataSourceInfo getDataSourceInfo() { DataSourceInfo dataSourceInfo = new DataSourceInfo(); // 当前sessionFactory LocalSessionFactoryBean sessionFactory = getLocalSessionFactoryBean(); if (null != sessionFactory) { // 数据源信息 DataSource dataSource = sessionFactory.getDataSource(); String driver = null; String url = null; String userName = null; String password = null; String encoding = null; // c3p0数据源 if (dataSource instanceof BasicDataSource) { BasicDataSource basicDataSource = (BasicDataSource) dataSource; driver = basicDataSource.getDriverClassName(); url = basicDataSource.getUrl(); userName = basicDataSource.getUsername(); password = basicDataSource.getPassword(); } dataSourceInfo.setDriver(driver); dataSourceInfo.setUserName(userName); dataSourceInfo.setPassword(password); dataSourceInfo.setUrl(url); // 通过url获取数据库的实例名、连接数据库ip、端口 if (null != url) { getDBContext().parseJdbcUrl(url, dataSourceInfo); Pattern pattern = Pattern.compile("UTF-8|GBK|GB2312", Pattern.CASE_INSENSITIVE); Matcher matcher = pattern.matcher(url); // 看连接信息中是否有设置编码 if (matcher.find()) { encoding = matcher.group(); } } dataSourceInfo.setEncoding(encoding); } return dataSourceInfo; } /** * 得到当前使用的SessionFactory * * @return LocalSessionFactoryBean */ @SuppressWarnings("rawtypes") public static LocalSessionFactoryBean getLocalSessionFactoryBean() { LocalSessionFactoryBean sessionFactory = null; // 获取由spring管理的所有的bean,获取到的是一个map集 Map map = AppContext.getContext().getBeansOfType( LocalSessionFactoryBean.class); // 寻找LocalSessionFactoryBean for (Object obj : map.values()) { if (obj instanceof LocalSessionFactoryBean) { sessionFactory = (LocalSessionFactoryBean) obj; break; } } return sessionFactory; } /** * 数据备份 * * @param filePath * 备份文件名(全路径) * @param valueList * 数据库表名list * @return String 返回信息 * @throws Exception */ public static String backupDB(String filePath, List<String> valueList) throws Exception { String responseStr = "-1"; DataSourceInfo dataSourceInfo = getDataSourceInfo(); // 根据上下文进行数据备份 // (待优化:备份数据库的大小,备份的操作系统,备份路径磁盘、文件夹的大小,备份结果文件的格式) getDBContext().backupDB(dataSourceInfo.getUserName(), dataSourceInfo.getPassword(), dataSourceInfo.getDbName(), dataSourceInfo.getHost(), filePath, valueList); // 备份最终结果是产生备份的文件,通过此判断是否已备份成功 File file = new File(filePath); if (file.exists()) { responseStr = filePath; } else { Log.error("数据备份失败!"); } return responseStr; } /** * 数据还原 * * @param resotreFilePath * 文件名(全路径) * @return void * @throws Exception */ public static void restoreDB(String resotreFilePath) throws Exception { DataSourceInfo dataSourceInfo = getDataSourceInfo(); // 数据还原过程,调用cmd命令,但无法得知调用后的结果如何,所以无法通过返回值来判断是否还原成功 // (待优化:如何判断是否还原成功,还原文件的大小) getDBContext().restoreDB(dataSourceInfo.getUserName(), dataSourceInfo.getPassword(), dataSourceInfo.getDbName(), dataSourceInfo.getHost(), resotreFilePath); } }
二、数据库还原操作
由于Oracle 数据库还原数据库时必须断开现有链接,所以无法实现在线还原功能,需要通过还原脚本完成。1、还原前需要删除数据库原有资源
--.sql脚本 --唯一注意的是下面的f:\dropobj.sql 为操作的.sql; --你的电脑没有F盘,请换为D或者E其他存在的盘符 --用于删除当前用户的所有对象 --use for drop all objects in current user; set heading off; set feedback off; spool %logdir%\dropobj.sql; prompt --删除约束条件 select 'alter table '||table_name||' drop constraint '||constraint_name||' ;' from user_constraints where constraint_type='R'; prompt --删除表空间 select 'drop table '||table_name ||';' from user_tables; prompt --删除视图 select 'drop view ' ||view_name||';' from user_views; prompt --删除数字序列 select 'drop sequence ' ||sequence_name||';' from user_sequences; --prompt --删除函数 --select 'drop function ' ||object_name||';' from user_objects --where object_type='FUNCTION'; prompt --删除存储过程 select 'drop procedure '||object_name||';' from user_objects where object_type='PROCEDURE'; prompt --删除包 prompt --删除包内容 select 'drop package '|| object_name||';' from user_objects where object_type='PACKAGE'; prompt --删除数据库链接 select 'drop database link '|| object_name||';' from user_objects where object_type='DATABASE LINK'; spool off set heading on; set feedback on; spool %logdir%\dropobj.log @@%logdir%\dropobj.sql; host del %logdir%\dropobj.sql; --done for drop objects in current user; --在SQL*PLUS 将这整段作为.sql导入或者直接复制黏贴,按F5执行,完成。 commit; exit;
2、还原脚本
@echo 数据还原程序会先删除数据库文件再进行还原,确认操作请按任意键继续...... @echo off pause>nul set /p ip=请输入数据库IP: @echo off set /p file=请输入还原文件的完整路径: @echo 系统开始执行还原程序,请不要关闭本界面..... @echo off set logdir=log%date:~0,4%%date:~5,2%%date:~8,2% if not exist %logdir% mkdir %logdir% @echo on @echo 建立日志文件夹完成...... @echo off sqlplus UserName/password@%ip%/orcl @deleteObject.sql @echo on @echo 删除数据库文件完成,执行还原语句请按任意键...... @echo off pause; imp IVMS8630/Hik123_CityParking@%ip%/orcl fromuser=ivms8630 touser=ivms8630 grants=y ignore=y file=%file% @echo on @echo 还原完成...... @echo off @echo 数据还原程序已完成还原操作,请按按任意键退出...... @echo off pause>nul
相关文章推荐
- oracle-创建用户,表空间及授权
- Oracle的rman备份与恢复
- 转:Oracle表分区
- “System.Data.OracleClient.OracleConnection”已过时
- Oracle查询表主键、外键
- SQLServer和Oracle,存储过程区别,常用函数对比
- Oracle分页存储过程
- Oracle 定义变量总结(转)
- jdbc 连接oracle单机与集群配置
- mybatis批量增加(oracle,mysql)
- Oracle导入导出
- Oracle导入导出
- oracle 11G rac 安装
- oracle的用户session
- Oracle服务一键启动/关闭
- Oracle索引重建
- Oracle常用sql
- Oracle视图
- oracle 存储过程返回 结果集 table形式 (使用sys_refcursor 及程序包package 两种方式)
- ORACLE中的支持正则表达式的函数