ITPub博客

首页 > 数据库 > Oracle > java oracle 存储过程 备份还原

java oracle 存储过程 备份还原

Oracle 作者:Elsie 时间:2014-01-15 16:31:24 0 删除 编辑
最近在用java做关于oralce数据库热备份与还原的功能,应用服务器与oralce数据库服务器分离。

因为很多情况,时间运行的服务器可能和 oracle数据库服务器是不同的服务器,所以不能直接用expcmd命令窗口备份。于是就想到了把exp写成 存储过程或者  函数的形式,存到数据库里面,然后在java程序中直接连到数据库调用 

数据库:oralce   用户:devetms 密码:password

  1. oracle建立java源
--创建java源
create or replace and compile java source named ExpA11Source as
import java.util.*;
import java.io.*;
public class ExpA11 {
  public static String expData(String cmd,String filePath) throws Exception{
    Runtime rt = Runtime.getRuntime();
    String command = new String(cmd);
    File file = new File(filePath);
    if (!file.exists()) {
     file.mkdir();
    }
    Process pr = rt.exec(command);
    pr.waitFor();
    return "success";
  }
   public static String impData(String cmd) throws Exception{
    Runtime rt = Runtime.getRuntime();
    String command = new String(cmd);
    Process pr = rt.exec(command);
    pr.waitFor();
    return "success";
  }
};

2、创建存储过程
创建函数,调用oracle中的java源
CREATE   OR   REPLACE   FUNCTION exp_data_function(cmd varchar2,filePath varchar2) RETURN   VARCHAR2
as language java name'ExpA11.expData(java.lang.String,java.lang.String) return java.lang.String';

CREATE   OR   REPLACE   FUNCTION imp_data_function(cmd varchar2) RETURN   VARCHAR2
as language java name'ExpA11.impData(java.lang.String) return java.lang.String';

3、权限控制
在创建java源与函数之后,需要知道的是,在调用java源时是需要使用当前用户对java源中的api的使用权限
--使用管理员身份附权限
CREATE OR REPLACE DIRECTORY EXP_IMP_DIR AS  'f:oracle_beifen';
GRANT READ, WRITE ON DIRECTORY  EXP_IMP_DIR TO DEVETMS;

--创建用户权限
begin
Dbms_Java.Grant_Permission('DEVETMS','java.io.FilePermission', '<>','read ,write, execute, delete');
Dbms_java.grant_permission('DEVETMS', 'SYS:java.io.FilePermission', '<>','read ,write, execute, delete');
Dbms_Java.Grant_Permission('DEVETMS', 'java.io.FilePermission', '%systemroot%system32cmd.exe','read ,write, execute, delete');
dbms_java.grant_permission('DEVETMS', 'java.lang.RuntimePermission','*','writeFileDescriptor' );
end;

以上,我们建立好了oracle的java源,调用java源的函数,并且赋予当前使用用户的权限,需要注意的是权限一定要赋予,不然应用程序调用时会报找不到权限的错误。

目前数据备份还原的路径是指定的,当然可以在第一次执行或者其他方式的情况下利用oracle的java源创建。

4、应用程序调用

//获取数据源连接
public Connection getSqlConnection() {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection(
"jdbc:oracle:thin:@localhost:1521:ORCL", "devetms", "password");
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
//关闭连接
public void closeConnection() {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

//数据备份,备份单个表或表空间
public void backUpExecute(){
Connection conn = null;
Map param = this.getContext().getAllParams();
String tables = (String)param.get("tablesId");
String cmd = "exp devetms/password@localhost:1521/orcl " +
"file=f:\oracle_beifen\dev0001.dmp tables=(sys_user)";
String command = "";
Date date = new Date();
String operateFlag = "1";
DateFormat df = new SimpleDateFormat("yyyyMMdd");
String dateStr = df.format(date);
String file = "f:/oracle_beifen";
try {
conn = getSqlConnection();
command = getCommands(conn, tables, date, operateFlag, "");
logger.info("BackUpRestoreOperate backUpExecute back up command is :"+command);
executeCommand(conn,file, command);
}  catch (SQLException e) {
logger.error("BackUpRestoreOperate backUpExecute error :",e);
}
}

//数据还原(表或表空间)
public void restoreExecute(){
Connection conn = null;
Map param = this.getContext().getAllParams();
//String tables = (String)param.get("tables");
String filePath = (String)param.get("filePath");
String command = "";
Date date = new Date();
String operateFlag = "2";
try {
conn = getSqlConnection();
command = getCommands(conn, "", date, operateFlag, filePath);
logger.info("BackUpRestoreOperate restoreExecute restore data command is :"+command);
executeCommand(conn,"", command);
}  catch (SQLException e) {
logger.error("BackUpRestoreOperate restoreExecute error :",e);
}
}
//命令执行器,也是java调用oracle函数或存储过程直接调用
public void executeCommand(Connection conn,String filePath,String command) throws SQLException{
CallableStatement cs =null;
String cmd = "exp devetms/password@localhost:1521/orcl " +
"file=f:\oracle_beifen\dev0001.dmp tables=(sys_user)";
String sql = "";
if(!"".equals(filePath)){
sql = "{? = call exp_data_function(?,?)}";
}else{
sql = "{? = call imp_data_function(?)}";
}
//String strcmd = "exp DEVETMS/password file=f:\oracle_beifen\20140102\backUp_1388648793578_table.dmp tables=(lwd_user)";
//String filecmd = "imp DEVETMS/password file=f:\oracle_beifen\20130102\backUp_1388649060937_table.dmp tables=(lwd_user) ignore=y";
try {
//conn = DbUtils.getConnection("1");
cs = conn.prepareCall(sql);
cs.registerOutParameter(1, Types.VARCHAR);
cs.setString(2, command);
if(!"".equals(filePath)){
cs.setString(3, filePath);
}
cs.execute();

String strValue = cs.getString(1);
logger.info("execute  command return string is :"+strValue);
System.out.println("executeCommand result is:" + strValue);
cs.close();
} catch (SQLException e) {
logger.error("BackUpRestoreOperate getCommands error :",e);
throw new SQLException(e);
}
}

//命令生成器,生成命令规则
private String getCommands(Connection conn ,String tables,Date date,
String operateFlag,String filePath) throws SQLException{
StringBuffer sb = new StringBuffer("");
if("1".equals(operateFlag)){
sb.append("exp ");
}else{
sb.append("imp ");
}
String userName ="";
try {
DatabaseMetaData dmd = conn.getMetaData();
String url = dmd.getURL();
String[] strUrl = url.split("@");
String[] strInstall = strUrl[strUrl.length-1].split(":");
String name = dmd.getUserName();
String serverName = "localhost";
userName = "devetms";
String port = "1521";
sb.append(name+"/password");
//sb.append("@"+serverName+":"+port+"/"+"orcl");
sb.append("@"+strInstall[strInstall.length-1].toString());
} catch (SQLException e) {
logger.error("BackUpRestoreOperate getCommands error :",e);
throw new SQLException(e);
}
if("1".equals(operateFlag)){
DateFormat df = new SimpleDateFormat("yyyyMMdd_hhmmss");
long dateMi = date.getTime();
String dateStr = df.format(date);
String file="f:\"+"\"+"oracle_beifen"+"\"+"\";
sb.append(" file="+file);
if(!"".equals(tables)){
sb.append("backUp_"+dateStr+"_table.dmp");
}else{
sb.append("backUp_"+dateStr+"_all.dmp");
}
}else{
// String [] filearr= filePath.split("");
// StringBuffer files = new StringBuffer("");
// for(int j=0;j
// if(j==filearr.length-1){
// files.append(filearr[j].toString());
// }else{
// files.append(filearr[j].toString()+"\"+"\");
// }
// }
StringBuffer files = new StringBuffer("");
files.append("f:\"+"\"+"oracle_beifen");
files.append("\"+"\"+filePath);
sb.append(" full=y");
sb.append(" file="+files.toString());
}
if("1".equals(operateFlag)){
if(!"".equals(tables)){
sb.append(" tables=("+tables+")");
}else{
sb.append(" owners=("+userName+")");
}
}
if("2".equals(operateFlag)){
sb.append(" ignore=y");
}
return sb.toString();
}

注:
这个方式最终的目的是实现在数据库服务器端调用exp/imp命令进行数据的还原与备份

这个方式没有去先删除表或者表空间而是进行所有表与数据的覆盖,这就会存在一个问题,如果现存在的数据还要大于已备份的数据,那么还原之后多余的数据还会存在,那么怎么才能去做到完全的还原?
个人建议先删除表,可以再建立存储过程或者函数时建立函数或过程包体,
create package body sp_package,这样就可以先执行删除的函数或过程再调用恢复。


<!-- 正文结束 -->

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/65971/viewspace-1115531/,如需转载,请注明出处,否则将追究法律责任。

下一篇: 没有了~
请登录后发表评论 登录
全部评论

注册时间:2009-06-12

最新文章