您的位置:首页 > 数据库

数据库(1):配置数据的缓存建立方法,独立数据表模型

2015-12-18 16:07 579 查看
描述:分表建模,用于管理少量表,表多了建模型繁琐。

例子:

基础模型及表模型实例 (行数据对象)

// 基类接口 (主要提供要处理的接口)

template <typename T>

struct EntityBase

{

virtual string getTableName()=0;

virtual string getDBName()=0;

virtual string getPrimary()=0;

virtual string readDB()=0;

virtual void fromDB(MusicDbRow &aRow)=0;

virtual string toDB(list<T> &aDataSet)=0;

virtual string dump()=0;

virtual ~EntityBase(){}

};

// 例子

//公会名称数据

struct GonghuiInfo: public EntityBase<GonghuiInfo>

{

// 表模型

uint32_t contractid; //公会签约ID(主键)

string name; //公会名称

uint32_t createtime;//更新时间

//实现虚函数,声明相关配置操作

virtual string getTableName()

{

return "gonghui_table"; // 对应数据库的表名

}

virtual string getDBName()

{

return "activity_one"; // 数据库名字 (一个数据库可以直接写入基类)

}

virtual string getPrimary()

{

return toString(contractid); // 唯一键 (经常对应的是数据库里面的主键,如果是组合键这个地方就是组合键,用于map的key识别)

}

virtual string readDB()

{

string sql="SELECT contractid, name, createtime FROM "; // 从数据库读表的select语句

sql.append(TABLE_SD2015_GH);

sql.append(" ORDER BY createtime DESC");

return sql;

}

virtual void fromDB(MusicDbRow &aRow) // 获取数据行键入到模型

{

contractid=aRow[0].asUInt();

name=aRow[1].str;

createtime=aRow[2].asUInt();

}

virtual string toDB(list<GonghuiInfo> &aDataSet) // 从模型到数据表

{

string tSql="REPLACE INTO ";

tSql.append(TABLE_SD2015_GH);

tSql.append("(contractid, name, createtime) VALUES ");

for(list<GonghuiInfo>::iterator it=aDataSet.begin(); it!=aDataSet.end();)

{

GonghuiInfo &tInfo=(*it);

tSql+="("+yymusic::toString(tInfo.contractid)+", "

+"\""+tInfo.name+"\", "

+yymusic::toString(tInfo.createtime)+") "

;

++it;

if(it!=aDataSet.end()) tSql.append(", ");

}

return tSql;

}

virtual string dump() // 打印值

{

stringstream ss;

ss << "contractid:" << contractid

<< ",name:" << name

<< ",createtime:" << createtime

;

return ss.str();

}

};

模型数据组合器 (表数据对象)

template <typename T>

struct EntityTable

{

EntityTable(){}

// 从数据库中获取数据

bool load()

{

MusicDBContext dbContext(entity.getDBName(), HASH_ALL_DB_KEY, false); // 获取数据库连接对象

string ssql=entity.readDB();

if(!ssql.empty())

{

//执行失败才false

if(!dbContext.commonSqlExe(ssql.c_str())) return false; // 执行查找语句

MusicDbRow tRow;

map<string, T> tDataMap;

T tEntity;

while(dbContext.fetchRow(tRow))

{

tEntity.fromDB(tRow); // 将数据插入模型

tDataMap[tEntity.getPrimary()]=tEntity; // 将模型插入表对象

}

boost::mutex::scoped_lock lock(_mutex);

data.swap(tDataMap);

}

return true;

}

//更新表数据,允许部分更新,会立即更新本地缓存,同时通知其他进程从数据库加载全量。

bool set(list<T> &aDataSet)

{

if(!aDataSet.empty())

{

MusicDBContext dbContext(entity.getDBName(), HASH_ALL_DB_KEY, false);

string ssql;

ssql=entity.toDB(aDataSet); // 产生插入语句

if(!ssql.empty())

{

//执行失败才false

if(!dbContext.commonSqlExe(ssql.c_str())) return false; // 执行更改到数据库

boost::mutex::scoped_lock lock(_mutex);

for(typename list<T>::iterator it=aDataSet.begin(); it!=aDataSet.end(); ++it)

{

data[(*it).getPrimary()]=*it; // 更改缓存

}

}

}

return true;

}

void getData(map<string, T> &aDataMap)

{

boost::mutex::scoped_lock lock(_mutex);

aDataMap=data;

}

// 获取一个对象

void getOne(const string &aPrimary, T& aEntity)

{

boost::mutex::scoped_lock lock(_mutex);

if(data.find(aPrimary)==data.end()) return;

aEntity=data[aPrimary];

}

private:

boost::mutex _mutex;

map<string, T> data; // 表数据列表

T entity; // 模型对象

};

表管理器 (整合所有的表)

struct EntityManager

{

static EntityManager& getInstance()

{

static EntityManager oIns;

return oIns;

}

// 初始化数据表

template <typename T>

void initTable()

{

T tEtt;

EntityTable<T> *tTableMgr=new EntityTable<T>();

string tKey=tEtt.getDBName()+"_"+tEtt.getTableName(); // 数据库名+表名组合成表唯一key

boost::mutex::scoped_lock lock(_mutex);

data[tKey]=new EntityTable<T>();

}

// load数据到缓存

template <typename T>

bool loadTable(uint32_t aRetry=3, uint32_t aRetryInterval=500000)

{

T tEtt;

EntityTable<T> *tTableMgr;

{

string tKey=tEtt.getDBName()+"_"+tEtt.getTableName();

boost::mutex::scoped_lock lock(_mutex);

if(data.find(tKey)==data.end()) return false;

tTableMgr=(EntityTable<T>*)data[tKey];

}

if(tTableMgr->load()) return true;

// 容错重处理

for(uint32_t i=0; i<3; i++)

{

logth(Info, "EntityManager::loadTable retrying at %u time %u", i, aRetryInterval)

usleep(aRetryInterval);

if(tTableMgr->load()) return true;

}

return false;

}

//更新表数据,允许部分更新,会立即更新本地缓存,同时通知其他进程从数据库加载全量。

template <typename T>

bool setTable(list<T> &aDataSet, uint32_t aRetry=3, uint32_t aRetryInterval=500000)

{

T tEtt;

EntityTable<T> *tTableMgr;

{

string tKey=tEtt.getDBName()+"_"+tEtt.getTableName();

boost::mutex::scoped_lock lock(_mutex);

if(data.find(tKey)==data.end()) return false;

tTableMgr=(EntityTable<T>*)data[tKey];

}

if(tTableMgr->set(aDataSet)) return true;

// 容错重处理

for(uint32_t i=0; i<3; i++)

{

logth(Info, "EntityManager::setTable retrying at %u time %u", i, aRetryInterval)

usleep(aRetryInterval);

if(tTableMgr->set(aDataSet)) return true;

}

return false;

}

// 获取整个表数据

template <typename T>

void getTable(map<string, T> &aDataMap)

{

T tEtt;

EntityTable<T> *tTableMgr;

{

string tKey=tEtt.getDBName()+"_"+tEtt.getTableName();

boost::mutex::scoped_lock lock(_mutex);

if(data.find(tKey)==data.end()) return;

tTableMgr=(EntityTable<T>*)data[tKey];

}

tTableMgr->getData(aDataMap);

}

// 获取一个对象数据

template <typename T>

void getOne(const string &aPrimary, T& aEntity)

{

T tEtt;

EntityTable<T> *tTableMgr;

{

string tKey=tEtt.getDBName()+"_"+tEtt.getTableName();

boost::mutex::scoped_lock lock(_mutex);

if(data.find(tKey)==data.end()) return;

tTableMgr=(EntityTable<T>*)data[tKey];

}

tTableMgr->getOne(aPrimary, aEntity);

}

private:

map<string, void*> data;

boost::mutex _mutex;

~EntityManager()

{

}

};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: