在DTL中,对数据进行插入和删除操作,目前发现有两种方法,一是用STL方法,一是用IndexDBView类操作;昨天就实验了这两种方法操作,DTL真不是一般的强大啊,可以像STL的操作,也可以直接执行SQL语句(ODBC封装貌似都可以吧),效率也还不错,当然,得选择合适的方法。(今天发现,对DTL操作,需要添加的库就是DTL和odbc2个即可,可以不添加odbcinst和stdc++库)
一、用index.htm自带的ReadData和WriteData进行操作,代码如下:
//将表内容存到vector vector<Example> ReadData() { vector<Example> results; DBView<Example> view("example",Test()); DBView<Example>::select_iterator read_it = view.begin(); for ( ; read_it != view.end(); ++read_it) { results.push_back(*read_it); } return results; } //将vector到写到view //用copy显然会重复;STL操作只能在末尾操作 void WriteData(const vector<Example> &examples) { DBView<Example> view("example",Test()); DBView<Example>::insert_iterator write_it = view ; //此时view是在最后,怎么搞到begin位置呢? copy(examples.begin(), examples.end(), write_it ); }原带的read 和write方法,问题在于,写的时候,用的copy方法,而且不能将写的iterator调到开始对数据表进行重刷
vector<Example> results = ReadData(); DBView<Example> view("example",Test()); DBView<Example>::delete_iterator del_it = view ; //每次读出来先把表里面的内容删除 copy(results.begin(), results.end(), del_it ); Example E; E.exampleInt=5; E.exampleStr="insert5"; E.exampleDouble=6.4; results.push_back(E);/// // 本方法的问题:WriteData中采用了copy方法切在末尾添加,表内容只增不减 WriteData(results);其实这种方法与windows中ODBC封装的CRecordset感觉蛮像的,一次全部读到内存,映射,优点是操作方便,所有数据都读到了vector中;缺点是当数据表内容过大时耗时过多;
插入的另一种方式,是用variant_row,代码如下:
DynamicDBView<> view("example", "*"); DynamicDBView<>::insert_iterator write_it = view; //用insert_iterator插入 variant_row s(view.GetDataObj()); string str="insert"; s[0]= rand()%10; s[1]=str; //直接赋值会得到错误 s[2]=3.3; *write_it = s ; write_it++;STL方法操作db,方便,不过有2个局限性:a.如查找,需要手动的为每一个类写一个函数;b.STL只支持数据的单个index。STL操作,最大的问题在于,只能在数据表后面操作,不能调到view的前端进行操作。
二、IndexDBView类
IndexDBView的优点,如类介绍:Onemajor difference between the IndexedDBView container and a standard containeris that any changes made to the items in our container can be automaticallypropagated back to the database.任何改写会自动写到数据库(当然,得使用参数BOUND)
以删除代码为例,代码如下:(更多示范代码直接参考docs/IndexDBView.htm)
DBConnection::GetDefaultConnection().Connect("DSN=example;UID=sa;" "PWD=123;server=127.0.0.1"); typedef DBView<Example, ParamObjExample> DBV; DBV view("example", BCAExampleObj(), "WHERE INT_VALUE BETWEEN (?) AND (?) OR " "STRING_VALUE = (?) ORDER BY INT_VALUE", BPAExampleObj()); IndexedDBView<DBV> indexed_view( view, "UNIQUE PrimaryIndex; STRING_VALUE; " "AlternateIndex; INT_VALUE", BOUND, USE_ALL_FIELDS, cb_ptr_fun(SetParamsExample)); IndexedDBView<DBV>::iterator idxview_it = indexed_view.begin();// .find(string("new")); IndexedDBView<DBV>::iterator deleteMe = idxview_it; //都是删除相同的一大片啊 idxview_it++; indexed_view.erase(deleteMe);
另外,删除数据后,可能有如下提示:
Exception type: DBException
Method: IndexedDBView::erase()
Error Message:Delete from DB failed! Record may have been changed by another user.
数据库显示正常,应该删除元素后迭代器失效,数据库中内容已经更新。
两种方法的耗时对比也很明显:
插入单条记录的时间测试效果如下:
|
STL(s) |
IndexDBView(us) |
10 |
0 |
0 |
100 |
0 |
0 |
1000 |
1.4 |
0 |
10000 |
2.5 |
0 |
删除单条记录耗时如下:
数量级 |
10 |
100 |
1000 |
5000 |
10000 |
用时(us) |
0 |
0 |
0 |
0 |
0 |
下面就是封装它的东东,提供接口给人使用了,刚搞定个连接和读取,sql_iterator什么的,居然有存储过程,想vc6的存储过程我也就写过一个,直接避过吧,先只是个简单的SQL语句算了。
说明下就是,记录情况为本人遇到,仅代表个人观点,如有问题,请留言。
菜鸟go go go ~~~