深入FDO----資料維護
本節將介紹如何用FDO API進行資料維護,資料維護相關的主要操作如下:
l 插入(Inserting)
l 更新(Updating)
l 刪除(Deleting)
l 事務(Transactions)
l 加鎖(Locking)
1.1.1 屬性值
在執行插入和更新操作之前,往往需要為插入和更新的要素建立屬性值。FDO使用類FdoPropertyValue表示屬性值,建立一個屬性值需要如下兩個引數:
l 屬性名稱
l 值:值的型別必須和屬性型別匹配
值可以分為資料型別值和幾何型別值,資料型別值用來描述資料型別屬性值,幾何型別值用於描述幾何屬性的值,它們的類圖如圖9‑3所示。
1.1.1.1 建立資料屬性值
FDO支援的資料型別有Boolean、Byte、DateTime、Decimal、Double、Int16、Int32、Int64、Single(單精度浮點數)、String、BLOB(二進位制大資料物件)、CLOB(字元大資料物件)。建立一個資料型別的值可以通過如下兩種方式之一:
1) 使用FdoDataValue,例如:Fdo
2) 使用FdoDataValue的子類
如下的程式碼展示瞭如何建立一個Decimal型別資料值,以及Decimal型別屬性值。
FdoPtr<FdoDataValue> sampleDataValue = FdoDataValue::Create(100.0, FdoDataType_Decimal); FdoPtr<FdoPropertyValue> sampleDataPropertyValue = FdoPropertyValue::Create("Area", value); 或 FdoPtr<FdoDataValue> sampleDataValue = FdoDecimalValue::Create(100.0); FdoPtr<FdoPropertyValue> sampleDataPropertyValue = FdoPropertyValue::Create("Area", value); |
圖 9‑4 FDO值型別的類圖
1.1.1.2 建立幾何屬性值
幾何屬性值物件包含著一個用位元組陣列描述的幾何物件。一個幾何物件可以是簡單的,如,點;也可以是複雜的,如,多邊形。在幾何物件比較複雜的情況下,會建立多個幾何物件並將它們合併到一個幾何物件,最後把目標幾何物件轉化成位元組陣列從而得到幾何型別物件。
建立幾何屬性值物件的步驟如下:
1) 呼叫靜態的Create()方法來建立FdoGeometryValue型別的幾何資料物件。
2) 呼叫靜態的GetInstance()方法建立一個FdoAgfGeometryFactory型別的幾何工廠物件,該工廠是用來建立幾何型別物件的。
3) 呼叫相應的Create<geometry>()方法來建立所需的幾何物件。
4) 用幾何工廠將目標幾何物件轉換成位元組陣列。
5) 將自己陣列合併到幾何屬性物件中。
FdoPtr<FdoGeometryValue> sampleGeometryValue = FdoGeometryValue::Create(); // 建立一個用來建立幾何物件的幾何工廠 FdoPtr<FdoFgfGeometryFactory> sampleGeometryFactory = FdoFgfGeometryFactory::GetInstance(); // 定義多邊形的外部邊界 FdoInt32 numOrdinates = 10; double ordinates[] = {52.0, 18.0, 66.0, 23.0, 73.0, 9.0, 48.0, 6.0, 52.0, 18.0}; FdoPtr<FdoILinearRing> exteriorRing = sampleGeometryFactory->CreateLinearRing(FdoDimensionality_XY, numOrdinates, ordinates); // 建立多邊形 FdoPtr<FdoIPolygon> polygon = sampleGeometryFactory->CreatePolygon(exteriorRing, NULL); // 將多邊形轉換成位元組陣列,然後設定幾何型別的值 FdoPtr<FdoByteArray> geometryByteArray = sampleGeometryFactory->GetAgf(polygon); sampleGeometryValue->SetGeometry(geometryByteArray); // 將FdoGeometryValue型別的新增到幾何屬性中 FdoPtr<FdoPropertyValue> sampleGeometryPropertyValue = FdoPropertyValue::Create(L"SampleGeometryProperty", sampleGeometryValue); |
1.1.2 插入操作
現在我們可以建立要素資料物件,也就是要素類的例項,並把他們插入到Data Store中。為了便於理解,我們可以認為一個FDO的類就是關聯式資料庫中的一個表,而類的屬性相當於表的列,於是新增屬性值就是向表中新增一行了。
插入操作包含以下步驟:
1) 建立FdoIInsert型別的插入命令物件,該物件可被多次插入操作重用。
2) 通過呼叫SetFeatureClassName(<className>)方法來設定需要插入屬性值的要素類。
3) 呼叫插入命令物件的GetPropertyValues()方法來得到FdoPropertyValueCollection型別的屬性值集合。在使用插入命令物件插入屬性值之前,必須先把各屬性值新增到該屬性集合中。
4) 建立FdoDataValue型別的資料值或FdoGeometryValue型別的幾何值。建立資料值直接呼叫靜態的Create()方法,傳入字串或整型值即可;建立幾何型別值請參考幾何屬性值。
5) 呼叫靜態Create()方法並傳入資料型別或集合型別物件來建立FdoPropertyValue型別的屬性值物件。
6) 將屬性值物件加入到第三步中得到的屬性值集合中。
7) 呼叫Execute()方法執行插入命令。
在前面的章節我們建立了一個要素模式並給它新增了一個要素類,該要素類有三個屬性:一個整型資料屬性,一個字串型別屬性以及一個幾何屬性。而後,我們把該要素模式應用到了Data Store中。有了模式和要素類,我們就可以建立要素類的物件並把他們插入到Data Store中了。
以下示例程式碼展示瞭如何插入一個整型、字串以及一個幾何型別屬性值。
// 建立插入命令 FdoPtr<FdoIInsert> sampleInsert = (FdoIInsert *) connection->CreateCommand(FdoCommandType_Insert); // 插入操作返回的索引值 FdoInt32 valueCollectionIndex = 0; // 為插入命令指定目標要素類 // 傳入一個完整的要素類名,其格式為“<schemaName>:<className>” sampleInsert-> SetFeatureClassName(L"SampleFeatureSchema:SampleFeatureClass"); // 得到屬性值集合,新建的屬性將插入到該集合中 FdoPtr<FdoPropertyValueCollection> samplePropertyValues = sampleInsert->GetPropertyValues(); // 為主鍵屬性建立一個FdoDataValue型別的值 FdoPtr<FdoDataValue> sampleIdentityDataValue = FdoDataValue::Create(101); // 將FdoDataValue新增到主鍵屬性中 FdoPtr<FdoPropertyValue> sampleIdentityPropertyValue = FdoPropertyValue::Create(L"SampleIdentityDataProperty", sampleIdentityDataValue); // 將主鍵屬性值新增到屬性值集合 valueCollectionIndex = samplePropertyValues->Add(sampleIdentityPropertyValue); // 為屬性“name”建立一個FdoDataValue型別的值 FdoPtr<FdoDataValue> sampleNameDataValue = FdoDataValue::Create(L"Blue Lake"); // 將FdoDataValue型別的值新增到name屬性 FdoPtr<FdoPropertyValue> sampleNamePropertyValue = FdoPropertyValue::Create(L"SampleNameDataProperty", sampleNameDataValue); // 將“name”屬性值新增到屬性值集合 valueCollectionIndex = samplePropertyValues->Add(sampleNamePropertyValue); // 為幾何屬性建立一個FdoGeometryValue型別的值 // 該多邊形描繪了一個帶有一個小島的湖 // 湖的外邊界是用Linear Ring來描述的,湖的外邊界也是多邊形的外邊界 // 島的邊界也是用Linear Ring來描述的,島的外邊界是多邊形的內部邊界 FdoPtr<FdoGeometryValue> sampleGeometryValue = FdoGeometryValue::Create(); // 建立一個用來建立幾何物件的幾何工廠 FdoPtr<FdoFgfGeometryFactory> sampleGeometryFactory = FdoFgfGeometryFactory::GetInstance(); // 定義多邊形的外部邊界,也就是“Blue Lake”的外邊界 FdoInt32 numBlueLakeShorelineOrdinates = 10; double blueLakeExteriorRingOrdinates[] = {52.0, 18.0, 66.0, 23.0, 73.0, 9.0, 48.0, 6.0, 52.0, 18.0}; FdoPtr<FdoILinearRing> exteriorRingBlueLake = sampleGeometryFactory->CreateLinearRing(FdoDimensionality_XY, umBlueLakeShorelineOrdinates, blueLakeExteriorRingOrdinates); // 定義“Blue Lake”內部小島“Goose”的邊界 FdoInt32 numGooseIslandShorelineOrdinates = 10; double gooseIslandLinearRingOrdinates[] = {59.0, 18.0, 67.0, 18.0, 67.0, 13.0, 59.0, 13.0, 59.0, 18.0}; FdoPtr<FdoILinearRing> linearRingGooseIsland = sampleGeometryFactory->CreateLinearRing(FdoDimensionality_XY, umGooseIslandShorelineOrdinates, gooseIslandLinearRingOrdinates); // 將“Goose”島的邊界加入到內部邊界集合中 FdoPtr<FdoLinearRingCollection> interiorRingsBlueLake = FdoLinearRingCollection::Create(); interiorRingsBlueLake->Add(linearRingGooseIsland); // 建立“Blue Lake”多邊形 FdoPtr<FdoIPolygon> blueLake = sampleGeometryFactory->CreatePolygon(exteriorRingBlueLake, interiorRingsBlueLake); // 將“Blue Lake”多邊形轉換成位元組陣列,然後設定幾何型別的值 FdoPtr<FdoByteArray> geometryByteArray = sampleGeometryFactory->GetAgf(blueLake); sampleGeometryValue->SetGeometry(geometryByteArray); // 將FdoGeometryValue型別的“Blue Lake”新增到幾何屬性中 FdoPtr<FdoPropertyValue> sampleGeometryPropertyValue = FdoPropertyValue::Create(L"SampleGeometryProperty", sampleGeometryValue); // 將幾何屬性值新增到屬性值集合中 valueCollectionIndex = samplePropertyValues->Add(sampleGeometryPropertyValue); // 執行插入操作,插入命令返回一個FdoIFeatureReader FdoPtr<FdoIFeatureReader sampleFeatureReader = sampleInsert->Execute(); |
1.1.3 更新屬性值
插入屬性之後也可以對屬性進行修改。更新操作指的是找出要素類(相當於“表”)、要素(相當於“行”)以及要修改的屬性(相當於“行的某一列”),然後用新的屬性值取代舊的屬性值。
首先,要建立一個FdoIUpdate命令物件,呼叫該物件的SetFeatureClassName()方法來查詢相應的要素類。
然後,建立一個過濾器來查詢需要更新的要素物件,呼叫命令物件的SetFilter()方法可以設定過濾條件。
前面的示例中,要素類SampleFeatureClass包含了一個名為“SampleIdentityDataProperty”的資料屬性,它是一個Int32型別的主鍵屬性,也就是說它的值可以唯一確定一個要素,即一 “行”。我們使用主鍵屬性名來設定過濾器,該關鍵屬性的值為‘101’,所以過濾器應該為“(SampleIdentityDataProperty = 101)”。
最後,建立一個新的屬性值,將其新增到更新命令並執行。
以下示例展示瞭如何更新一個屬性值。
// 建立更新命令 FdoPtr<FdoIUpdate> sampleUpdate = (FdoIUpdate *)connection->CreateCommand(FdoCommandType_Update); // 為更新命令指定目標要素類 // 傳入一個完整的要素類名,其格式為“<schemaName>:<className>” sampleUpdate-> SetFeatureClassName(L"SampleFeatureSchema:SampleFeatureClass"); // 設定過濾條件來鎖定目標集合 sampleUpdate->SetFilter(L"( SampleIdentityDataProperty = 101 )"); // 得到屬性集合,用以向更新命令中新增屬性 // 這裡我們將重用插入操作裡用到的samplePropertyValues物件 samplePropertyValues = sampleUpdate->GetPropertyValues(); // 為name屬性建立一個FdoDataValue型別的物件 FdoPtr<FdoDataValue> sampleNameDataValue = FdoDataValue::Create(L"Green Lake"); // 設定屬性名以及對應的值 sampleNamePropertyValue->SetName(L"SampleNameDataProperty"); sampleNamePropertyValue->SetValue(sampleNameDataValue); // 新增name屬性物件到更新命令的屬性集合中 samplePropertyValues->Add(sampleNamePropertyValue); // 執行命令,返回值為更新命令所更新的要素總數 FdoInt32 numUpdated = sampleUpdate->Execute(); |
1.1.4 刪除要素
除了插入和更新操作,我們還可以執行刪除操作。刪除操作是針對要素的,也就是相當於刪除資料庫表中的某一行。
首先,需要建立一個FdoIDelete命令物件,呼叫物件的SetFeatureClassName()方法來找到相應的要素類。然後,建立一個過濾器來定位所要刪除的要素,此處的過濾和前面講到的完全一樣。最後,執行刪除命令。
以下示例展示瞭如何刪除一個要素。
// 建立刪除命令 FdoPtr<FdoIDelete> sampleDelete = (FdoIDelete *)connection->CreateCommand(FdoCommandType_Delete); // 為刪除命令指定目標要素類 // 傳入一個完整的要素類名,其格式為“<schemaName>:<className>” sampleDelete->SetFeatureClassName(L"SampleFeatureSchema:SampleFeatureClass"); // 設定過濾條件來鎖定目標集合 sampleDelete->SetFilter(L"( SampleIdentityDataProperty = 101 )"); // 執行命令,返回值為刪除命令所刪除的要素總數 FdoInt32 numDeleted = sampleDelete->Execute(); |
1.1.5 管理事務
在9.1.2.2中,我們介紹過事務的概念。一個事務是指由一系列資料操作組成的一個完整的邏輯過程,它具原子性、一致性、隔離性和永續性的特點。
FDO中事務的概念和RDBMS中事務的概念是基本相同的,和RDBMS中的事務一樣,FDO的事務也是關聯與一個連線。呼叫FdoIConnection::StartTransaction()可以啟動一個事務,它會返回一個FDO事務FdoTransaction物件,呼叫FdoITransaction::Commit()可以提交一個事務,在啟動事務後針對Data Store所做的所有修改寫入資料來源中,呼叫FdoITransaction::Rollback()可以回滾一個事務,在啟動事務後針對Data Store所做的所有修改會全部撤銷,就像從來沒有做過這些修改一樣。
FdoPtr<FdoTransaction> transaction; FdoPtr<FdoICommand> command; try { // 啟動事務 transaction = connection->BeginTransaction(); ...... command->SetTransaction(transaction); ...... transaction->Commit(); } catch (FdoException* e) { e->Release(); transaction->Rollback(); } |
不過,FDO不支援巢狀事務,這就意味著如果當前連線啟動了一個事務,那麼在這個事務提交或回滾之前,使用者不可以再啟動一個新的事務。
需要注意的是事務和長事務不是兩個相同的概念,在9.9中我們會介紹長事務。
相關文章
- 資料維護和基礎架構維護-有感架構
- 維護樹狀資料
- 維護資料庫安全資料庫
- 資料庫常用維護命令資料庫
- Oracle資料庫日常維護Oracle資料庫
- 六、資料庫管理與維護資料庫
- Nagios資料提取和維護iOS
- SAP RETAIL MM41維護商品主資料的時候可以維護分類資料AI
- nodebb搭建 維護 discuz 資料遷移
- 物料主資料的維護狀態
- ORACLE資料庫管理維護綱要Oracle資料庫
- 《大型資料庫技術》MySQL管理維護資料庫MySql
- Oracle資料庫維護的重要性Oracle資料庫
- 【轉】Oracle資料庫日常維護手冊Oracle資料庫
- oralce動態維護資料庫的序列資料庫
- Informix_on_line資料庫維護技巧ORM資料庫
- Oracle資料庫中索引的維護 ztOracle資料庫索引
- PostgreSQL學習手冊(資料庫維護)SQL資料庫
- Oracle資料庫日常維護手冊 (zt)Oracle資料庫
- Oracle資料庫中索引的維護(zt)Oracle資料庫索引
- Oracle資料庫中索引的維護(轉)Oracle資料庫索引
- 29. 使用MySQL之資料庫維護MySql資料庫
- SAP QM QA08批次維護QMAT資料
- 開發資料大全(個人整理,長期維護)
- 資料庫自動維護任務的管理資料庫
- ORACLE資料庫日常維護知識總結Oracle資料庫
- Oracle資料庫維護常用SQL語句集合Oracle資料庫SQL
- Oracle資料庫中索引的維護 (轉帖)Oracle資料庫索引
- UT 資料庫日常維護指導手冊資料庫
- 網站怎樣利用整體性防護策略維護資料安全?網站
- Access資料庫日常維護和Access資料庫最佳化方法資料庫
- Hybris產品主資料的價格折扣維護
- restapi(0)- 平臺資料維護,寫在前面RESTAPI
- 如何避免重複性地做資料維護頁面?
- 瞭解和使用kfed維護ASM後設資料ASM
- 資料庫維護常用操作命令1--約束資料庫
- 啟用enable restricted對資料庫進行維護REST資料庫
- 資料庫維護常用操作命令2--約束資料庫