2013年7月6日 星期六

dbunit初體驗 - 從現有XML DATA中過濾出需要的資料

之前使用的QueryDataSet可以下SQL Query來SELECT出想要的資料(請見此篇),
然而QueryDataSet好像只能接受從connection資料來建立...這不符合我的需求,找到一個好方法,就是使用RowFilterTable 搭配IRowFilter,直接來看code:


 public static ITable filterXmlDataCol(
   String xmlDataFile, String tableName,IDatabaseConnection conn
   , final String expectColNames[] , final Object expectColVals[]) throws Exception {
  
  IDataSet databaseDataSet = getDataSetFromXmlFile(xmlDataFile);
  ITable actualTable = databaseDataSet.getTable(tableName);
  
  IRowFilter rowFilter = new IRowFilter() {
   @Override
   public boolean accept(IRowValueProvider rowValueProvider) {
    try {
     for(int i=0 ; i< expectColNames.length ; ++i){
      Object columnValue = rowValueProvider.getColumnValue(expectColNames[i]);
      if (!columnValue.equals(expectColVals[i]))
       return false;
     }
     return true;
    } catch (DataSetException ex) {
     ex.printStackTrace();
    }
    return false;
   }
  };
  RowFilterTable filteredRowsTable = new RowFilterTable(
    actualTable, rowFilter);
  return filteredRowsTable;
 }

使用方式:
現有XML DATA:


  
  
    

    
    
    
    

我只希望以XMLDATA建立出的ITable有條件:product == "17公司" and name=="tables"的資料,那麼就照以下方式呼叫:
   ITable expect = DBUnitUtilities.filterXmlDataCol("datasheet\\FactoryInfo.xml","FactoryInfo"
     , _dbunitConnection,new String[]{"name","product"},new String[]{"17公司","tales"} );


這樣就可以過濾囉~~

debug一下其實可以發現RowFilterTable並不是真的將資料給"過濾"掉了,只是將原先的Table給wrap後,然後帶入自行建立的IRowFilter(上述line 8~23),並在每一次巡迴column資料時以自定義的@ovverride accept()回傳true(資料保留) 或 false(資料移除)
回傳true的row index就會被保留在filteredRowIndexes這個List中囉。


p.s:
星期一就要交差幾乎會開天窗的我居然還在研究test.....只希望我這個堅持是對的....畢竟我真的不想再寫垃圾Code穩定度又差又無法擴充又不敢修改的爛東西了阿.........0rz...


參考:Filtering data sets and comparing results using DBUnit

沒有留言:

張貼留言