一、导入导出命令
oracle备份和还原除了使用工具比如PL/SQL进行导出导入还可以利用命令,在程序中也就只能调用外部命令了,首先我们得知晓oracle备份和还原的命令,根据需要我是需要备份和还原项目数据库的所有的表的,以下命令为备份和还原所有表命令。
备份:exp username/password@TEST file=D:\export.dmp
还原:imp username/password@TEST file=D:\export.dmp full=y ignore=y
二、Java代码实现
调用runtime方法,因为是远程的数据库,所以SID为ip+"/"+数据库名
-
-
-
-
-
-
-
-
-
-
-
- public int oraBackup() throws IOException{
-
- String userName=Global.getConfig("jdbc.username");
- String password=Global.getConfig("jdbc.password");
- String savePath=Global.getConfig("oraBackupPath");
- String SID=Global.getConfig("SID");
- String id=IdGen.uuid();
-
- File saveFile = new File(savePath);
- if (!saveFile.exists()) {
- saveFile.mkdirs();
- }
-
- PageData pd=new PageData();
- pd.put("id", id);
- pd.put("user_name", UserUtils.getUser().getName());
- pd.put("op_dt", new Date());
-
- oracleBackupDao.insertOraBackup(pd);
-
-
- List<String> tablesList=oracleBackupDao.findAltTables();
-
- for (int i = 0; i < tablesList.size(); i++) {
- oracleBackupDao.doAltSql(tablesList.get(i));
- }
- String command ="exp " + userName + "/" + password + "@" + SID + " file=" + savePath + id + ".dmp";
- System.out.println("备份数据库命令操作:" + command);
-
- Process process = Runtime.getRuntime().exec(command);
-
- final InputStream is1 = process.getInputStream();
-
- new Thread(new Runnable() {
- public void run() {
- BufferedReader br = new BufferedReader(new InputStreamReader(is1));
- String info;
- try {
- while ((info=br.readLine()) != null){
- System.out.println("info: "+info);
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }).start();
- InputStream is2 = process.getErrorStream();
- BufferedReader br2 = new BufferedReader(new InputStreamReader(is2));
-
- StringBuilder buf = new StringBuilder();
- String line = null;
- int i=0;
- while ((line = br2.readLine()) != null){
-
- System.out.println("info: " +line);
- buf.append(line);
- }
- try {
- if(buf.toString().contains("ORA-")&&buf.toString().contains("EXP-")){
- System.err.println("备份失败!");
- process.destroy();
- }else{
- i=process.waitFor();
- System.out.println("over status: "+i);
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println("备份结束...");
-
-
- String dmpPath = savePath + id + ".dmp";
-
- pd.put("file_size", new File(dmpPath).length());
- oracleBackupDao.updateFileSize(pd);
- return 0;
- }
PS:因为是oracle11g,发现11G中新特性,当表无数据时,不分配segment,以节省空间。而使用exp命令时,无Segment的表不会被导出。所以如果单纯直接执行导出语句是不可以的,必须查询所有的空表后,执行alter命令。
- select table_name from user_tables where NUM_ROWS=0;
如果平时导出的话直接执行这句:
- select 'alter table '||table_name||' allocate extent;' from user_tables where num_rows=0
最后为所有的表执行alter命令
- alter table '表名' allocate extent;
导入还原的代码是类似的,根据命令自己拼字符串即可,不再累述
小结:
1.看似一个小的功能,当简单代码的完成后的测试更是重头戏,要考虑表是不是全部导出,每个表的数据是不是完全,要考虑备份导出过程中的突发情况,比如网线断连接。
2.导入还原时添加full=y ignore=y,否则导入会报错
3.如果原数据库是有数据的直接导入的话数据会在原基础上添加,所以可能存在数据重复现象,试了很多办法不可以,所以我的处理是在还原时查询所有表,用truncate强制执行清表的操作,再重新导入。
http://blog.csdn.net/ww130929/article/details/70208744