gxx_base(三) 字典

2 篇文章 0 订阅
2 篇文章 0 订阅

gxx_base(三) 字典


GxxDictionary : 字典类
GxxDictionaryPtr : GxxDictionary的智能指针类
GxxDictionary 是基于 key-value键值对的数据结构, 笔者也把它作为json字符串的解析利器。笔者在大部分项目中都使用到它,主要在以下几个方面用到:
1. 存储key-value键值对。
2. GxxDictionaryPtr对象作为参数在业务与业务之间传递, 并且不用关心内存的释放问题。
3. 解析json字符串和字典转换成json字符串。
4. 高频访问数据做缓存, GxxDictionary能存储所有从GxxObject类继承的派生类对象,并能自动管理它们的内存释放。

key-value键值对的使用

GxxDictionaryPtr myDic = GxxDictionary::create();
// 设置值,有两种写法
myDic->setValueForKey("程序猿", "name"); // 直接使用函数
myDic["name2"] = "程序员"; // 使用[]表达式

myDic["age"] = 25;
myDic["address"] = "北京";
	
// 获取值
const char* myName = myDic["name"];// 获取字符串值,写法一
const char* myName2 = myDic->szStringValueForKey("name2"); // 获取字符串值,写法二
std::string myAddress = myDic->stringValueForKey("name2"); // 获取字符串值,写法三 
int myAge = myDic["age"];
myAge = myDic->intValueForKey("age");

// 判断key是否存在
if (!myDic->isKeyExist("wife"))
{
    printf("没有老婆\n");
}

// 遍历
GxxValueMapPtr vmap = myDic->mapKeyValue();
GxxValueMap::Iterator pos = vmap->FirstValue();
for(; !vmap->IsLastValue(pos); vmap->NextValue(pos))
{
	const char* key = pos->first;
	GxxValuePtr pVal = pos->second;
	const char* val = pVal->stringValue();
}


在业务之间传递参数

例如: 期末考试各科老师给学生评分

// 数学老师评分
void Fun1(GxxDictionaryPtr ptr)
{
	ptr["数学"] = 99;
}
// 语文老师评分
void Fun2(GxxDictionaryPtr ptr)
{
	ptr["语文"] = 98;
}
// 英语老师评分
void Fun3(GxxDictionaryPtr ptr)
{
	ptr["英语"] = 97;
}
int main(int argc, _TCHAR* argv[])
{
	GxxDictionaryPtr student = GxxDictionary::create();
	Fun1(student);
	Fun2(student);
	Fun3(student);
	printf("成绩汇总:\n%s\n", student->toJsonText().c_str());
	getchar();
	return 0;
}

输出结果如下:

成绩汇总:
{"数学":"99","英语":"97","语文":"98"}

json字符串互转

const char* jsonStr = "{\"class\":\"高三1班\",\"studentCount\":\"50\",\"teachers\":{\"语文老师\":\"张三\",\"数学老师\":\"李四\",\"英语老师\":\"王五\"}}";
GxxDictionaryPtr myDic = GxxDictionary::create();
myDic->initWithJsonText(jsonStr);
printf(myDic->toJsonText().c_str());
/* 输出结果
{"class":"高三1班","studentCount":"50","teachers":{"数学老师":"李四","英语老师":"王五","语文老师":"张三"}}
*/
printf("\n");
// 用此方法得到格式化后描述信息
printf(myDic->describe_d(0, true, false).c_str());
/* 输出结果
{
    "class":"高三1班",
    "studentCount":"50",
    "teachers":
     {
	    "数学老师":"李四",
            "英语老师":"王五",
            "语文老师":"张三"
     }
}
*/
printf("\n");

作为缓存

class CStudentInfo : public GxxObject
{
	GXX_CREATE_FUNC(CStudentInfo)
public:
	std::string no; // 学号
	std::string name; // 姓名
	std::string className; // 班级
	std::string address; // 地址
	std::vector<std::string> favs; // 兴趣爱好
public:
	void print()
	{
		// 打印信息
	}
};
// 定义CStudentInfo的智能指针类
typedef GxxAutoPtr<CStudentInfo> CStudentInfoPtr;

void ReadyStudentsInfo(GxxDictionaryPtr studentsMap)
{
	// 创建二个学生对象
	CStudentInfoPtr studentPtr1 = CStudentInfo::create();
	studentPtr1->no = "1001";
	studentPtr1->name = "小李";
	studentPtr1->className = "高三1班";
	studentPtr1->address = "北京";
	studentPtr1->favs.push_back("看书");
	studentPtr1->favs.push_back("足球");
	studentPtr1->favs.push_back("音乐");
	CStudentInfoPtr studentPtr2 = CStudentInfo::create();
	studentPtr2->no = "1002";
	studentPtr2->name = "嘎子";
	studentPtr2->className = "高三1班";
	studentPtr2->address = "北京";
	studentPtr2->favs.push_back("打架");
	studentPtr2->favs.push_back("逃课");

	studentsMap["1001"] = (GxxObjectPtr)studentPtr1;
	studentsMap["1002"] = (GxxObjectPtr)studentPtr2;
}
int main(int argc, _TCHAR* argv[])
{
	GxxDictionaryPtr studentsMap = GxxDictionary::create();
	ReadyStudentsInfo(studentsMap);

	// 调取学号为 1001同学的资料
	CStudentInfoPtr infoPtr = (CStudentInfo*)studentsMap->otherValueForKey("1001");
	// 打印同学的信息
	infoPtr->print();
}

真实实践

笔者这3年来一直在做好旺餐饮和水吧软件设计与开发,本地数据库采用sqlite3。软件视图层,经常需要查询后台设置的相关商品类型信息和商品列表信息,大家都知道商品信息有很多属性,因此在数据库必然存在多张表的关联。 每次读取商品,势必要关联几张表来联合查询。如果每次查询数据库,那么视图层的用户体验必然会很差。 因此,笔者在数据访问层创建了2个缓存, 1个来存储已查询过的商品信息,已经缓存过的商品信息则没必要再关联查询了; 另一个来存储sql语句的查询结果,完全相同的sql语句,直接返回缓存中存在的查询结果。如果web后台更改了商品信息, 数据访问层对相应的缓存做一下刷新就ok了。GxxDictionary此时为我的工作提供了巨大的便利。

笔者对sqlite3和gxx_base的使用做了一次业务应用上的封装, 加入异常机制和事务处理、防sql注入、高频sql参数化预编译缓存、简单易用的sql查询函数和执行函数、高效的批量数据插入函数。想了解的朋友可联系我: gemeryguo@126.com












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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值