传统的jdbc操作数据库,导出和导入含有blob类型的sql文件

最近项目需要把oracle数据库中的数据导出几条作为备用数据使用,在使用的时候再次导入到数据库,前面以为很简单,可是在做的时候遇到了困难,因为看到了blob这种类型的数据,比较苦恼,传统的导出已经不能使用,于是想了一个办法,在查询到数据后使用rs.getMetaData,得到结果集的结构信息,不明白的同学可以在网上查找下,然后获取字段的列名和类型,判断是否是blob类型,如果是就用字节流写到文件中。

下面是代码:

package com.travelsky.pss.bkg.asom.pnrBackups;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;

public class PnrBackups {

	private static Connection conn = null;
	private static Statement sm = null;
	// private static String schema="ORCL";//模式名
	private static String select = "SELECT * FROM";// 查询sql
	private static String insert = "INSERT INTO";// 插入sql
	private static String values = "VALUES";// values关键字
	private static String[] table = { "CTR", "CTR_TKNE" };// table数组
	private static List<String> insertList = new ArrayList<String>();// 全局存放insertsql文件的数据
	private static String filePath = "./usecase/";// 绝对路径 导出数据的文件
	private static String driver = "oracle.jdbc.driver.OracleDriver";
	private static String url = "jdbc:oracle:thin:@(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = IP地址)(PORT = 1521)))(CONNECT_DATA =(SERVICE_NAME = ORCL)))";
	private static String userName = "";// 用户名
	private static String passWord = "";// 密码

	/**
	 * 导出数据库表
	 * 
	 * @param args
	 * @throws SQLException
	 */
	public static void main(String[] args) throws SQLException {
		List<String> listSQL = new ArrayList<String>();
		connectSQL(driver, url, userName, passWord);// 连接数据库
		// connectSQL("com.mysql.jdbc.Driver",
		// "jdbc:mysql://127.0.0.1:3306/test", "root", "root");
		Long pnrbkey = os.ant.usas1.PNR.pplcky("MGRNV6");
		String ctrKey = "-2542916197493062913";
		listSQL = createSQL(pnrbkey, ctrKey);// 创建查询语句
		executeSQL(conn, sm, listSQL,ctrKey);// 执行sql并拼装
		createFile(ctrKey);// 创建文件
	}

	/**
	 * 创建insertsql.txt并导出数据
	 */
	private static void createFile(String ctrKey) {
		filePath = filePath + ctrKey + ".sql";
		File file = new File(filePath);
		if (!file.exists()) {
			try {
				file.createNewFile();
			} catch (IOException e) {
				System.out.println("创建文件名失败!!");
				e.printStackTrace();
			}
		}
		FileWriter fw = null;
		BufferedWriter bw = null;
		try {
			fw = new FileWriter(file);
			bw = new BufferedWriter(fw);
			if (insertList.size() > 0) {
				for (int i = 0; i < insertList.size(); i++) {
					bw.append(insertList.get(i));
					bw.append("\n");
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				bw.close();
				fw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 拼装查询语句
	 * 
	 * @return 返回select集合
	 */
	private static List<String> createSQL(Long pnrbkey, String ctrKey) {
		List<String> listSQL = new ArrayList<String>();
		for (int i = 0; i < table.length; i++) {
			StringBuffer sb = new StringBuffer();
			if (table[i].equals("CTR_TKNE")) {
				sb.append(select).append(" ").append("CTR_TKNE").append(" ").append("where ").append("CTR_KEY")
						.append(" = '").append(ctrKey).append("'");
				listSQL.add(sb.toString());
			} else {
				// sb.append(select).append(" ").append(schema).append(".").append(table[i]);
				sb.append(select).append(" ").append(table[i]).append(" ").append("where ").append("PNRB_KEY")
						.append(" = '").append(pnrbkey).append("'");
				listSQL.add(sb.toString());
			}

		}
		return listSQL;
	}

	/**
	 * 连接数据库 创建statement对象
	 * 
	 * @param driver
	 * @param url
	 * @param UserName
	 * @param Password
	 */
	public static void connectSQL(String driver, String url, String UserName, String Password) {
		try {
			Class.forName(driver).newInstance();
			conn = DriverManager.getConnection(url, UserName, Password);
			sm = conn.createStatement();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 执行sql并返回插入sql
	 * 
	 * @param conn
	 * @param sm
	 * @param listSQL
	 * @throws SQLException
	 */
	public static void executeSQL(Connection conn, Statement sm, List listSQL,String ctrKey) throws SQLException {
		List<String> insertSQL = new ArrayList<String>();
		ResultSet rs = null;
		try {
			rs = getColumnNameAndColumeValue(sm, listSQL, rs, ctrKey);
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			rs.close();
			sm.close();
			conn.close();
		}
	}

	/**
	 * 获取列名和列值
	 * 
	 * @param sm
	 * @param listSQL
	 * @param rs
	 * @return
	 * @throws SQLException
	 */
	private static ResultSet getColumnNameAndColumeValue(Statement sm, List listSQL, ResultSet rs, String ctrKey) throws SQLException {
		if (listSQL.size() > 0) {
			for (int j = 0; j < listSQL.size(); j++) {
				String sql = String.valueOf(listSQL.get(j));
				int number = sql.indexOf("where");
				String tableName = sql.substring(14,number);
				rs = sm.executeQuery(sql);
				ResultSetMetaData rsmd = rs.getMetaData();
				int columnCount = rsmd.getColumnCount();
				while (rs.next()) {
					StringBuffer ColumnName = new StringBuffer();
					StringBuffer ColumnValue = new StringBuffer();
					for (int i = 1; i <= columnCount; i++) {
						Object value = rs.getObject(i);
						if ("".equals(value)) {
							value = " ";
						}
						if (i == 1 || i == columnCount) {
							String lineName = rsmd.getColumnName(i);
							if(i == columnCount){
								ColumnName.append("," + lineName);
							}else{
								ColumnName.append(lineName);
							}
							
							if (Types.BLOB == rsmd.getColumnType(i)) {
								Blob blob = rs.getBlob(lineName);
								if(blob == null){
									if(i == columnCount){
										ColumnValue.append(value);
									}else{
										ColumnValue.append(value).append(",");
									}
									continue;
								}
								InputStream ins = blob.getBinaryStream();
								//去掉ctrKey前的-
								ctrKey = ctrKey.replaceAll("-", "");
								//创建文件
								String fileNameTemp = "./usecase/" + ctrKey+ "_" + lineName + ".txt";
								File file = new File(fileNameTemp);
								try{
									//如果文件不存在则创建文件
									if(!file.exists()){
										file.createNewFile();
									}
								}catch(Exception e){
									e.printStackTrace();
								}
								
								// 输出到文件
								try {
									OutputStream fout = new FileOutputStream(file);
									// 下面将BLOB数据写入文件
									byte[] b = new byte[1024];
									int len = 0;
									while ((len = ins.read(b)) != -1) {
										fout.write(b, 0, len);
									}
									// 依次关闭
									fout.close();
									ins.close();
									if(i == columnCount){
										ColumnValue.append(fileNameTemp);										
									}else{
										ColumnValue.append(fileNameTemp).append(",");
									}
									
								} catch (Exception e) {
									e.printStackTrace();
								}
							}else if (Types.CHAR == rsmd.getColumnType(i) || Types.VARCHAR == rsmd.getColumnType(i)
									|| Types.LONGVARCHAR == rsmd.getColumnType(i)) {
								if(i == columnCount){
									ColumnValue.append("'").append(value);
								}else{
									ColumnValue.append("'").append(value).append("',");
								}
							} else if (Types.SMALLINT == rsmd.getColumnType(i)
									|| Types.INTEGER == rsmd.getColumnType(i) || Types.BIGINT == rsmd.getColumnType(i)
									|| Types.FLOAT == rsmd.getColumnType(i) || Types.DOUBLE == rsmd.getColumnType(i)
									|| Types.NUMERIC == rsmd.getColumnType(i) || Types.DECIMAL == rsmd.getColumnType(i)) {
								if(i == columnCount){
									ColumnValue.append(value);
								}else{
									ColumnValue.append(value).append(",");
								}
								
							} else if (Types.DATE == rsmd.getColumnType(i) || Types.TIME == rsmd.getColumnType(i)
									|| Types.TIMESTAMP == rsmd.getColumnType(i)) {
								if(i == columnCount){
									ColumnValue.append("to_date('").append(value).append("',").append("'YYYY-MM-DD HH24:MI:SS')");
								}else{
									ColumnValue.append("to_date('").append(value).append("',").append("'YYYY-MM-DD HH24:MI:SS')").append(",");
								}
							} else {
								if(i == columnCount){
									ColumnValue.append(value);
								}else{
									ColumnValue.append(value).append(",");
								}
								
							}
						} else {
							String lineName = rsmd.getColumnName(i);
							ColumnName.append("," + lineName);
							if (Types.BLOB == rsmd.getColumnType(i)) {
								Blob blob = rs.getBlob(lineName);
								if(blob == null){
									ColumnValue.append(value).append(",");
									continue;
								}
								InputStream ins = blob.getBinaryStream();
								ctrKey = ctrKey.replaceAll("-", "");
								//创建文件
								String fileNameTemp = "./usecase/" + ctrKey+ "_" + lineName + ".txt";
								File file = new File(fileNameTemp);
								try{
									//如果文件不存在则创建文件
									if(!file.exists()){
										file.createNewFile();
									}
								}catch(Exception e){
									e.printStackTrace();
								}
								
								// 输出到文件
								try {
									OutputStream fout = new FileOutputStream(file);
									// 下面将BLOB数据写入文件
									byte[] b = new byte[1024];
									int len = 0;
									while ((len = ins.read(b)) != -1) {
										fout.write(b, 0, len);
									}
									// 依次关闭
									fout.close();
									ins.close();
									ColumnValue.append(fileNameTemp).append(",");
                                                                       //把文件路径做参数传入values中后期操作会使用到 
                                                                    } catch (Exception e) {
									e.printStackTrace();
								}
							}else if (Types.CHAR == rsmd.getColumnType(i) || Types.VARCHAR == rsmd.getColumnType(i)
									|| Types.LONGVARCHAR == rsmd.getColumnType(i)) {
								ColumnValue.append("'").append(value).append("'").append(",");
							} else if (Types.SMALLINT == rsmd.getColumnType(i)
									|| Types.INTEGER == rsmd.getColumnType(i) || Types.BIGINT == rsmd.getColumnType(i)
									|| Types.FLOAT == rsmd.getColumnType(i) || Types.DOUBLE == rsmd.getColumnType(i)
									|| Types.NUMERIC == rsmd.getColumnType(i) || Types.DECIMAL == rsmd.getColumnType(i)) {
								ColumnValue.append(value).append(",");
							} else if (Types.DATE == rsmd.getColumnType(i) || Types.TIME == rsmd.getColumnType(i)
									|| Types.TIMESTAMP == rsmd.getColumnType(i)) {
								String dateStr = value.toString();
								String date = null;
								if(dateStr != null){
									if(dateStr.contains(".")){
										String[] time = dateStr.split("\\.");
										date = time[0];
									}
								}
								
								ColumnValue.append("to_date('").append(date).append("',").append("'YYYY-MM-DD HH24:MI:SS')").append(",");
							} else {
								ColumnValue.append(value).append(",");
							}
						}
					}
					System.out.println(ColumnName.toString());
					System.out.println(ColumnValue.toString());
					insertSQL(ColumnName, ColumnValue,tableName.trim());
				}
			}
		}
		return rs;
	}

	/**
	 * * 拼装insertsql 放到全局list里面 * @param ColumnName * @param ColumnValue
	 * */
	private static void insertSQL(StringBuffer ColumnName, StringBuffer ColumnValue,String tableName) {
		StringBuffer insertSQL = new StringBuffer();
		// insertSQL.append(insert).append(" ").append(schema).append(".").append(table[i])
		insertSQL.append(insert).append(" ").append(tableName).append("(").append(ColumnName.toString()).append(")")
				.append(values).append("(").append(ColumnValue.toString()).append(")");
		insertList.add(insertSQL.toString());
		System.out.println(insertSQL.toString());
	}
}

下面是将导出的数据导入到oracle数据库中:

说到导入,这里需要拿到blob文件的路径,我导出的时候是直接把blob文件的路径填写在blob字段中的,如:

insert into table(id,title,context) values(1,'ceshi',F://blob.txt);

其中context就是blob类型的字段,在valyes中这个字段的值却放的是对应的F://blob.txt文件的路径,这就是我们在导入的时候直接截取到就可以使用了,不多说,上传代码:

package com.travelsky.pss.bkg.asom.pnrBackups;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.travelsky.pss.bkg.asom.utils.MyBufferedReader;

public class InsertPnrBackups {
	
	private static Connection connection;
	private static Statement st;
	private static ResultSet rs;
	
	private static String url = "jdbc:oracle:thin:@(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = ip地址)(PORT = 1521)))(CONNECT_DATA =(SERVICE_NAME = ORCL)))";
	private static String userName = "";// 用户名
	private static String passWord = "";// 密码
	
	public static void main(String[] args) throws SQLException {
		
		
		try {
			
			Class.forName("oracle.jdbc.driver.OracleDriver");
			System.out.println("开始尝试连接数据库!");
			
			//通过DeriverManager类创建Connection连接对象
			connection = DriverManager.getConnection(url, userName, passWord);// 获取连接
			connection.setAutoCommit(false);
			if(connection == null){
				System.out.println("连接不成功!");
				return false;
			}
			st = connection.createStatement();
			//ctrKey = "-2542916197493062913";
			
			String filePath = "./usecase/" + ctrKey + ".sql";
			Reader read = new FileReader(new File(filePath));
			MyBufferedReader mr=new MyBufferedReader(read);
			
			String line;
			String[] fileNamePath = new String[12];
			while ((line=mr.readLine())!=null) {
				
				String sql = line.toString();
                                //这里需要获取到有多少个blob文件路径,然后把路径放入到fileNamePath中
                               if(sql.contains("./usecase/")){
					ctrKey = ctrKey.replace("-", "");
					Matcher m = Pattern.compile("./usecase/"+ ctrKey +"_[A-Z]{3,}_[A-Z0-9]{3,}.txt").matcher(sql);
					int i = 0;
					while(m.find()){
						String fileName = sql.substring(m.start(),m.end()); 
						fileNamePath[i++] = fileName;
					}
					//这里是将文件路径全部替换成EMPTY_BLOB(),这个的意思就是放入一个空的blob文件,具体解释各位找度娘吧
					for(int j = 0; j < fileNamePath.length; j++){
						if(fileNamePath[j] != "" && fileNamePath[j] != null){
							sql = sql.replaceAll(fileNamePath[j], "EMPTY_BLOB()");
						}
					}
				}
				if(!"".equals(line) && line != null){
					System.out.println(sql);
					st.addBatch(sql);
				}
			}
			st.executeBatch();
			//connection.commit();
			read.close();
			
			/* 查询此CLOB对象并锁定 */
                        //这里是查询出所有的blob类型的字段,切记,这里的查询必须要加上FOR UPDATE,否则会报错
                        rs = st.executeQuery("SELECT INDEX_DATA, CTR_DATA, CTR_DAT0, CTR_DAT1, "
								+"CTR_DAT2, CTR_DAT3, CTR_DAT4, CTR_DAT5, CTR_DAT6, "
								+"CTR_DAT7, CTR_DAT8, CTR_DAT9 FROM CTR "
								+"WHERE CTR_KEY = '"+ ctrKey + "' FOR UPDATE");
			//有关 ResultSet 中列的名称和类型的信息
			ResultSetMetaData rsmd = rs.getMetaData();
			int columnCount = rsmd.getColumnCount();
			String[] lineName = new String[columnCount];
			if(rs.next()){
                                //这里是拿到所有的列,也就是上面查询出来的字段,然后放到String数组中,在后面会用到
                               for(int i = 1; i <= columnCount; i++){
					lineName[i-1] = rsmd.getColumnName(i);
				}
				
				boolean falg = updateCtr(lineName,fileNamePath);
				
				if(falg){
					identifying = false;
					System.out.println("操作成功");
				}
			}
		} catch (Exception e) {
			connection.rollback();
			e.printStackTrace();
		}finally{
			try{
				if(rs != null){
					rs.close();
				}
				if(st != null){
					st.close();
				}
				if(connection != null){
					connection.close();
				}
			}catch(Exception e){
				e.printStackTrace();
			}
		}
	}
	
	private static boolean updateCtr(String[] lineName, String[] fileNamePath) throws SQLException{
		//判断是否成功
		boolean falg = false;
		//读取blob类型文件数据
		oracle.sql.BLOB blob = null;
		for(int i = 0; i < lineName.length; i++){
			
			try {
				//在这里我们就用到了上面的列名数据,和在发送insert into语句时截取出来文件路径,这里才是重中之重
				blob =  (oracle.sql.BLOB)rs.getBlob(lineName[i]);
				//得到数据库的输出流
				OutputStream out = blob.getBinaryOutputStream();
				//这里用一个文件模拟输入流
				File file = new File(fileNamePath[i]);
				InputStream in = new FileInputStream(file);
				
				//将输入流写到输出流
				byte[] temp = new byte[blob.getBufferSize()];
				int len = 0;
				
				while ( (len = in.read(temp)) != -1) {
					out.write(temp, 0, len);
			        //blob.putBytes(1,b);
			    }
				
				in.close();
				out.flush();
				out.close();
				falg = true;
			} catch (Exception e) {
				falg = false;
				e.printStackTrace();
			}
			
		}
		connection.commit();
		return falg;
	}
	
}
其实,这里的添加blob类型的字段是分为两个部分的,第一部分就是先添加数据,也就是insert  into table(id,title,context) values (1,'cesi',EMPTY_BLOB()),这也就是上面我们需要把文件路径替换成这个的原因,EMPTY_BLOB()会直接在数据库中插入一个空白的blob文件,然后我们利用查询,查询出刚才添加进去的数据,把blob类型的数据给查询出来,然后使用流一一写入数据库就可以了,我这里是有很多字段所以就写了一个方法,循环读取,如果您是一个字段,那就不需要使用方法了,在if(rs.next())中直接流读取,写入即可,更方便



  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值