如何数据库接口简化c 11访问为?
摘要:c++ 新特性除了零碎的小知识、学不完的语法、艰深难懂的模板,究竟给我们带来了哪些好处,这里从数据库接口入手谈一谈。话说如果只是使用者的话,感觉还蛮好的……
之前写过一篇文章专门分析了 c++ 模板编译过程中报的一个错误:《fatal error C1045: 编译器限制 : 链接规范嵌套太深 》,其中涉及到了 qtl —— 一个使用 c++ 11 构建的数据库访问库,当时限于篇幅,没有深入研究它是如何借助 c++ 11 来简化数据库访问接口的,本文现在就来探讨一下这方面的内容。
没有 c++ 11 之前,苦逼的程序员对于 sql 操作的输入输出,只好一行行敲代码,例如在调用数据库接口前设置绑定参数;在调用成功后,循环遍历查询的记录。很多时候数据库表对应在程序中就是一个结构体,程序员需要花费大量的精力将数据库表字段对应到结构体成员上、或反之,完全没有体现出来程序员应有的价值。而 qtl 这种 c++ 11 库的出现,可以极大的简化上面的程序编写,下面还是用之前文章中提到的例子作为演示,让大家感受一下:
插入单条数据
1 uint64_t test_insert_single(qtl::sqlite::database &db)
2 {
3 time_t now = time(0);
4 int tmp = rand() % 1000;
5 uint64_t id = db.insert_direct("insert into popbox_msg(msgid, msgtype, appname, uid, status, count, msgbody, stamp) values(?, ?, ?, ?, ?, ?, ?, ?)",
6 std::to_string(tmp), 108, "GDraw", "1923374929399", 1, 0, "this is msgbody", now);
7
8 printf("insert record with msgid %d return %d\n", tmp, (int)id);
9 return id;
10 }
插入操作需要输入数据,将数据编入 sql 是一种思路,但更好的方法是使用占位符 (?) 和数据绑定 (binding) 来防止 sql 注入问题,而这会给接口带来不定数量的输入参数,幸好 c++ 11 的可变模板参数特性允许用户提供不限数量与类型的输入数据,是不是很方便?下面是 qtl 提供的插入单条数据接口:
1 uint64_t qtl::base_database<T, Command>::insert<Params>(const std::string & query_text, const Params & params);
2 uint64_t qtl::base_database<T, Command>::insert<Params>(const char * query_text, const Params & params);
3 uint64_t qtl::base_database<T, Command>::insert<Params>(const char * query_text, size_t text_length, const Params & params);
4
5 uint64_t qtl::base_database<T, Command>::insert_direct<...Params>(const std::string & query_text, const Params & ...params);
6 uint64_t qtl::base_database<T, Command>::insert_direct<...Params>(const char * query_text, const Params & ...params);
7 uint64_t qtl::base_database<T, Command>::insert_direct<...Params>(const char * query_text, size_t text_length, const Params & ...params);
其中主要分两组:insert 与 insert_direct,前者只提供一个输入绑定参数,后者可以提供多个。而且这些接口会很贴心的将新插入记录的 rowid 返回,方便后续操作这条记录。
