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

描述:分表建模,用于管理少量表,表多了建模型繁琐。


例子:

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


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

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()
  {

  }


 };


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值