在利用数据库进行MIS系统的开发过程中,经常需要把BLOB数据统一存放在数据库中以便共享处理。本文介绍在多层体系结构下,C++Builder中BLOB的读写方法(也适用于两层的C/S结构)。 程序处理示意图如图1所示: BLOB读取 应用服务器用TQuery控件连接到数据库,并显示输出接口(即直接拖拉TDataSetProvider控件,把新控件的DataSet指向要引出的TQuery)。注意:不能隐式输出Provider接口,即在要输出接口的控件上单击鼠标右键,选择“Export Query1 From Data Module”。 应用服务器与客户端TClientDataSet控件通过Midas中间件连接。直接通过Select语句读出即可,语句序列写法如下: ClientDataSet1->Close(); ClientDataSet1->SQL->Clear(); ClientDataSet1->SQL->Add(合法的Select语句); ClientDataSet1->Open(); BLOB写入 客户端通过TClientDataSet控件的ApplyUpdates方法提交已修改的BLOB数据到应用服务器。(根据BCB开发手册介绍,ApplyUpdates方法可以更新BLOB数据到数据库,但实际中常出现更新失败的情况)。 应用服务器截获从客户端传来的BLOB数据,利用两层结构的提交方式提交。本例中,假设系统中所有BLOB数据存放在同一表BlobTbl中,表结构为:BlobId INT、BlobText BLOB。BLOBId为该表关键字,BLOB相关数据通过该关键字同BLOB数据关联。所有BLOB数据均通过该数据集Query1进行处理。客户端数据集有且只有一条更新内容,否则,只有第一条更新内容有效。如果存放多个表或一次更新多个记录,可通过其他一些技巧实现。 在引出接口TdataSetProvider的BeforeUpdateRecord事件中,编写如下代码: void __fastcall SrvCom::Query1BeforeUpdateRecord(TObject *Sender,TDataSet *SourceDS, TClientDataSet *DeltaDS, TUpdateKind UpdateKind, bool &Applied) if (UpdateKind != ukDelete) { AnsiString SessionName; TSession *SessionForTran; //生成临时数据集供提交使用 TQuery* tmpQry=new TQuery(NULL); try { //从与数据库连接的会话池中取可用的会话 SessionName=SessionPools->GetSession Name(……); if(!SessionName.IsEmpty()) { //设置临时数据集的会话 SessionForTran=Sessions-> FindSession(SessionName); tmpQry->DatabaseName=SessionForTran->Databases[0]->DatabaseName; tmpQry->SessionName=SessionName; tmpQry->RequestLive=true; //设置修改数据集 tmpQry->SQL->Add(“Select * From BlobTbl Where BlobId="+SourceDS->FieldByName(“BlobId")->AsString); tmpQry->Open(); //更新数据 tmpQry->Edit(); ((TBlobField*)tmpQry->FieldByName (“BlobText"))->Value=((TBlobField *)DeltaDS-> FieldByName(“BlobText"))->NewValue; //提交数据 tmpQry->Post(); tmpQry->Close(); delete tmpQry; } } catch(Exception &e) { delete tmpQry; throw e; } //忽略BCB的处理机制 Applied=true; } 注意:BLOB数据提交必须在事务中进行,本例中未进行事务处理是因为把事务放到了客户端进行处理。不要使用SQL的DML语句(如INSERT、UPDATE),因为通常数据都有特殊专用字符,而这些字符都有可能出现在BLOB数据中,从而导致数据库处理错误。 效率处理 对BLOB读写不要使用TTable控件,否则会大大降低效率。 在多层体系结构下,服务器端从数据库读取BLOB数据时,最好采用单独的会话(Sessions),避免多用户状态下,一个用户读取较大的BLOB数据时,其他用户等待响应的时间过长。 最好把BLOB数据单独存放在一个表中,不要同相关联的其他类型数据存放在同一表中。一般数据库均会自动把BLOB数据存放到专门的数据空间。同时,最好在逻辑视图上也把它们分开,既好理解也好处理。 BLOB同非BLOB数据在读写时也要分开处理。 在多用户情况下,可在应用服务器设置BLOB缓冲池,再设计专门的读写函数供客户端调用处理。 |
C++ Builder中
最新推荐文章于 2020-12-27 19:23:40 发布