1. 程式人生 > >用java實現把sql語句查詢的結果集寫到dbf檔案中

用java實現把sql語句查詢的結果集寫到dbf檔案中

這個其實就是一個匯出生成DBF檔案的功能,實現思路是這樣:首先動態拼接一個sql語句,執行後返回結果集到程式碼中,再通過dbfwriter物件把結果集的資料寫到dbf檔案裡。

1、開啟資料庫連線,執行sql語句,獲得結果集

	private Connection bakConn;
	private ResultSet RowSet = null;
	private Statement stats = null;
	private String formate = "yyyyMMdd";
	@Override
	public void run() {
		try {
			bakConn = DatabaseConn.getConnection();
		} catch (Exception e1) {
			e1.printStackTrace();
		}
	String sql = "select * from tablename";
	stats = bakConn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
					ResultSet.CONCUR_READ_ONLY);
	RowSet = stats.executeQuery(sql);
	RowSet.beforeFirst();
2、定義需要寫到dbf的欄位名,型別,長度,定義dbf檔案的欄位名,型別(從結果集中的資料庫型別對應轉換過來)

String[] strutName = new String[] {...} // field name
String[] rsTypejc = new String[] {...} // field type
int[] strutLength2 = new int[] { ...} // field length
/**
	 * 把資料庫欄位型別轉換成DBF欄位型別
	 */
	public static byte ResultsetTypeToDbfType(String rsType) {
		
byte strutType = DBFField.FIELD_TYPE_C; if (rsType == null) { return DBFField.FIELD_TYPE_C; } rsType = rsType.trim().toLowerCase(); if (rsType.equals("float") || rsType.equals("int") || rsType.equals("numeric") || rsType.equals("decimal") || rsType.equals("smallint") || rsType.equals("tinyint")) {// rsType.equals("bigint")
// || strutType = DBFField.FIELD_TYPE_N; } else if (rsType.equals("datetime") || rsType.equals("smalldatetime")) { strutType = DBFField.FIELD_TYPE_C; } else if (rsType.equals("bit")) { strutType = DBFField.FIELD_TYPE_L; } else { strutType = DBFField.FIELD_TYPE_C; } return strutType; }
上面是把資料庫型別轉為dbf型別。
下面是具體的dbf寫操作:

填充field,填入轉換後型別等等,把結果集rowset裡的資料逐條遍歷,把資料放進writer裡

// 定義dbf物件
	DBFField[] fields = new DBFField[strutName.length];
	System.out.println(fields);
	byte[] strutTypejc = new byte[strutName.length];
	for (int i = 0; i < strutName.length; i++) {
		fields[i] = new DBFField();
		fields[i].setName(strutName[i]);
		strutTypejc[i] = ResultsetTypeToDbfType(rsTypejc[i]);
		fields[i].setDataType(strutTypejc[i]);
		fields[i].setFieldLength(strutLength[i]);

	}
	DBFWriter writer = new DBFWriter();
	System.out.println(fields);
	writer.setFields(fields);
	writer.setCharactersetName("GBK");
	// 一條條的寫入記錄
	Object[] rowData = new Object[strutName.length];
	RowSet.last();
	RowSet.beforeFirst();
	while (RowSet.next()) {
		rowData = ResultsetToArrayJCTP(RowSet, rowData, "jc",
					strutName, rsTypejc);
		if (rowData != null) {
			writer.addRecord(rowData);
			}
		}
		// 把裝了檔案的輸出流放到writer裡
		writer.write(fos);
這裡注意:fos是檔案輸出流,具體處理在下面

file = new File("C:" + File.separator + "xxx"
				+ File.separator + "001" );
		if (file.isFile()) {
			file.delete();
		}
		OutputStream fos = null;
		// 定義輸出流,並關聯的一個檔案
        try {
        	// 把檔案放到輸出流
			fos = new FileOutputStream(file);
		} catch (FileNotFoundException e2) {
			e2.printStackTrace();
		}
dbf物件的writer通過檔案流來操作檔案,不是直接寫入檔案,如下:
writer = new DBFWriter(file);
writer.write();
這種做法是不正確的,會導致檔案無法及時釋放,直至整個應用關閉才可釋放。

最後是資源的釋放:

finally { // 按順序釋放資源
			// 關閉連線
			try {
				// 流關閉
				fos.close();
				// 關閉結果集
				if (this.getRowSet() != null) {
					this.getRowSet().close();
					this.setRowSet(null);
				}
				if (this.getStats() != null) { // 關閉語句
					this.getStats().close();
					this.setStats(null);
				}
				if (this.getBakConn() != null) { // 關閉連線
					this.getBakConn().close();
					this.setBakConn(null);
				}
			} catch (Exception e1) {
				e1.printStackTrace();
			}
		}

在finally塊中按順序釋放資源