用java實現把sql語句查詢的結果集寫到dbf檔案中
阿新 • • 發佈:2018-11-20
這個其實就是一個匯出生成DBF檔案的功能,實現思路是這樣:首先動態拼接一個sql語句,執行後返回結果集到程式碼中,再通過dbfwriter物件把結果集的資料寫到dbf檔案裡。
1、開啟資料庫連線,執行sql語句,獲得結果集
2、定義需要寫到dbf的欄位名,型別,長度,定義dbf檔案的欄位名,型別(從結果集中的資料庫型別對應轉換過來)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();
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塊中按順序釋放資源