简单介绍一下DataTable。DataTable主要基于表、行、单元格。行用集合包装单元格,表用集合包装行,大致就是这样。DataColumn表示单元格,DataColumn中的字段还挺多的,在实际应用中我们可能只想用它来存一个int型的数据;DataColumnCollection中用一个ArrayList封装DataColumn,表示一些单元格的集合;DataRow直接在DataColumnCollection的基础上提供一些方法,成为行记录。而DataRowCollection则用集合的方式封装DataRow成为表,但它不是以线性、链表等方式,而是基于红黑树RBTree<DataRow>,主要是查询和删除比较方便,而DataTable则是DataRowCollection的封装,对看了DataTable整个实现的大致代码,我不得吐槽一下:这它妈是把牛刀,我们每天用它来切菜,用着还挺方便。DataTable提供了很强大的功能,但是我们基本不需要,有时候基本上是得到一个DataTable,啥都不做,直接绑定,最常用的也就Update和Insert,Select和Delete则次之。当然你会说避免使用DataTable,当然还有人说C#......
OK废话到此结束,今天我想做说的是用C++来实现DataTable。大致思路还是按照C#中的来,功能没有C#中的强大,但增删改查的功能还是有的,基本还是个人练习,把代码放出来跟大家讨论一下。基本上是STL中几个集合的运用。在我的实现在并没有使用红黑树,而是用list<DataRow*>代替了,主要类的头文件如下:
DataColumn的实现代码如下,主要是对几个字段的封装。源码共享
#pragma once
class DataTable;
#include <iostream>
using namespace std;
template<typename T>
class TDataColumn
{
public:
TDataColumn():columnName(string()),caption(string())
{
}
TDataColumn(const string& _columnName):columnName(_columnName),caption(string())
{
}
virtual ~TDataColumn()
{
}
void Caption(const string& _caption)
{
caption=_caption;
}
string Caption()
{
return caption.size() ?caption:columnName;
}
void ColumnName(const string& _columnName)
{
columnName=_columnName;
}
string ColumnName()
{
return columnName;
}
void Value(const T& _value)
{
value=_value;
}
T Value()
{
return value;
}
int ObjectId()
{
return objectId;
}
void Table(DataTable* tb)
{
table=tb;
}
DataTable* Table()
{
return table;
}
string TypeName()
{
return typeid(T).name();
}
protected:
int objectId;
string columnName;
string caption;
T value;
DataTable* table;
};
class DataColumn:public TDataColumn<string>
{
public:
friend class DataColumnCollection;
friend class DataTable;
DataColumn():TDataColumn<string>()
{
objectId=++objectCountId;
}
DataColumn(const DataColumn& dc)
{
*this=dc;
}
DataColumn& operator=(const DataColumn& dc)
{
objectId=++objectCountId;
columnName=dc.columnName;
caption=dc.caption;
value=dc.value;
table=dc.table;
return *this;
}
DataColumn(const string& _columnName):TDataColumn<string>(_columnName)
{
objectId=++objectCountId;
}
bool operator==(const DataColumn& dc)
{
return objectId==dc.objectId;
}
bool operator!=(const DataColumn& dc)
{
return objectId!=dc.objectId;
}
bool operator<(const DataColumn& dc)
{
return objectId<dc.objectId;
}
bool operator>(const DataColumn& dc)
{
return objectId>dc.objectId;
}
void Show()
{
cout<<"columnName:"<<columnName.data()<<",caption:"<<Caption().c_str()<<",value:"<<value.data()<<endl;
}
private:
static volatile int objectCountId;
};
其他文件的头文件如下:
#pragma once
#include <iostream>
using namespace std;
#include <assert.h>
#include <vector>
#include <list>
#include <map>
#include "DataColumn.h"
#include "StringHelper.h"
class DataColumnCollection;
class DataRow;
class DataRowCollection;
class DataTable;
class DataColumnCollection
{
public:
friend class DataTable;
friend class DataRow;
friend class DataRowCollection;
DataColumnCollection(DataTable* table);
~DataColumnCollection();
void Add(DataColumn* dc);
void Add(DataColumn* dc,size_t index);
DataColumn& Add(const string& columnName);
bool Contains(const string& columnName);
void Clear();
size_t Count();
int IndexOf(const string& columnName);
void Remove(DataColumn& dc);
void Remove(const string& columnName);
void RemoveAt(size_t index);
void CopyTo(DataColumnCollection* arr, size_t index);
DataColumn& operator[](size_t index);
DataColumn& operator[](const string& columnName);
void Table(DataTable* tb);
DataTable* Table();
private:
void Add(DataColumn* dc,size_t index,DataColumnCollection* collect);
void RemoveAt(size_t index,DataColumnCollection* collect);
void InitData();
DataColumnCollection();
vector<DataColumn*> dlist;
map<int,DataColumn*> nameList;
DataTable* table;
};
class DataRow
{
public:
friend class DataTable;
friend class DataRowCollection;
friend class DataColumnCollection;
~DataRow();
void Table(DataTable* tb);
DataTable* Table();
DataColumnCollection& Columns();
DataColumn& operator[](size_t index);
DataColumn& operator[](const string& columnName);
bool operator=(const DataRow& dr);
private:
DataRow();
void Remove(DataColumn& dc);
void RemoveAt(size_t index);
DataColumnCollection* columns;
DataTable* table;
int rowId;
static volatile int rowIdCount;
};
class DataRowCollection
{
public:
friend class DataTable;
friend class DataColumnCollection;
DataRowCollection(DataTable* table);
~DataRowCollection();
void Add(DataRow* dc);
void Clear();
size_t Count();
void Remove(DataRow* dc);
void RemoveAt(size_t index);
DataRow& operator[](size_t index);
void Table(DataTable* tb);
DataTable* Table();
private:
DataRowCollection();
list<DataRow*> drlist;
DataTable* table;
};
class DataTable
{
public:
friend class DataColumnCollection;
friend class DataRowCollection;
DataTable();
DataTable(const string& _tableName);
~DataTable();
DataColumnCollection& Columns();
DataRowCollection& Rows();
string TableName();
void TableName(const string& _tableName);
DataRow& operator[](size_t index);
void Clear();
DataRow* NewRow();
vector<DataRow*>* Select(const string& columnName,const string& value) ;
private:
void InitData();
DataColumnCollection* dcCollect;
DataRowCollection* drCollect;
string tableName;
};
测试代码如下:
#include <iostream>
using namespace std;
#include <sstream>
#include "DataColumn.h"
#include "DataTable.h"
#include "OperationTimer.h"
int main( )
{
DataTable dt;
for(size_t i=0;i<10;i++)
{
string s("column");
s.push_back(char('0'+i));
DataColumn *dc=new DataColumn(s);
dt.Columns().Add(dc);
}
for(int j=0;j<10;j++)
{
DataRow* dr=dt.NewRow();
for(int i=0;i<10;i++)
{
string s("row");
s.push_back(char('0'+j));
s.push_back(char('0'+i));
(*dr)[i].Value(s) ;
}
dt.Rows().Add(dr);
}
int rowCount=dt.Rows().Count();
int columnCount=dt.Columns().Count();
cout<<"共"<<rowCount<<"行"<<columnCount<<"列"<<endl;
rowCount=rowCount/2;
columnCount=columnCount/2;
cout<<"第"<<rowCount<<"行"<<columnCount<<"列的值为:"<<dt[rowCount][columnCount].Value().c_str()<<endl;
dt.Columns().Add(new DataColumn("column10"));
dt.Columns().Add(new DataColumn("column11"));
cout<<"新增两列后:"<<endl;
rowCount=dt.Rows().Count();
columnCount=dt.Columns().Count();
cout<<"共"<<rowCount<<"行"<<columnCount<<"列"<<endl;
rowCount=rowCount/2;
columnCount=columnCount/2;
cout<<"第"<<rowCount<<"行"<<columnCount<<"列的值为:"<<dt[rowCount][columnCount].Value().c_str()<<endl;
cout<<"删除一行一列后:"<<endl;
dt.Columns().RemoveAt(4);
dt.Rows().RemoveAt(2);
rowCount=dt.Rows().Count();
columnCount=dt.Columns().Count();
cout<<"共"<<rowCount<<"行"<<columnCount<<"列"<<endl;
rowCount=rowCount/2;
columnCount=columnCount/2;
cout<<"第"<<rowCount<<"行"<<columnCount<<"列的值为:"<<dt[rowCount][columnCount].Value().c_str()<<endl<<endl;
cout<<"查询列名为column3,值为row43的行,数据如下:"<<endl;
vector<DataRow*>* vect=dt.Select("column3","row43");
for(size_t i=0;i<vect->size();i++)
{
DataColumnCollection& dcCollect= (*vect)[i]->Columns();
for(size_t j=0;j<dcCollect.Count();j++)
{
dcCollect[j].Show();
}
}
delete vect;
getchar();
return 0;
}
结构截图: