深入FDO----数据维护

 

本节将介绍如何用FDO API进行数据维护,数据维护相关的主要操作如下:

l  插入(Inserting

l  更新(Updating

l  删除(Deleting

l  事务(Transactions

l  加锁(Locking

1.1.1        属性值

在执行插入和更新操作之前,往往需要为插入和更新的要素创建属性值。FDO使用类FdoPropertyValue表示属性值,创建一个属性值需要如下两个参数:

l  属性名称

l  值:值的类型必须和属性类型匹配

值可以分为数据类型值和几何类型值,数据类型值用来描述数据类型属性值,几何类型值用于描述几何属性的值,它们的类图如93所示。

1.1.1.1  创建数据属性值

FDO支持的数据类型有BooleanByteDateTimeDecimalDoubleInt16Int32Int64Single(单精度浮点数)、StringBLOB(二进制大数据对象)、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);

 

Class Diagram

94 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中我们会介绍长事务。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值