上一篇文章《更简洁的C++数据库访问框架-soci》介绍了soci,但也同时提到了一个缺点—insert/update/delete操作的时候,没有返回影响了多少行。
另外还有一个隐性的原因,soci的代码大量使用了异常,而项目中要求底层代码是严禁抛出异常的(其实google也是有这个要求的)。
基于以上两个原因,所以最终没有把soci用在生产环境。

但是又不想每次都重复去调用那些繁琐的MySQL API,所以这次又重新对MySQL API做了一层C++的封装。

其实相信每个和mysql打过交道的程序员都应该会尝试去封装一套mysql的接口,这一次的封装已经记不清是我第几次了,但是每一次我希望都能做的比上次更好,更容易使用。

先来说一下这次的封装,遵守了几个原则,其中部分思想是从python借鉴过来的:

  • 1.简单
  • 简单,意味着不为了微小的效率提升,而去把接口搞的复杂。因为本身数据库存储效率的瓶颈并不是那一两次内存copy,代码中随处可以看到以这个为依据的设计。

  • 2.低学习成本
  • 使用一套新库通常意味着投入学习成本,而这次的封装并没有像django那样实现一套完整的模型系统,也没有做soci那样的语法分析器,我选择最简单易懂的方式:做sql语句拼接器,所以对习惯了使用原生mysql api的朋友,学习成本很低

  • 3.模块化
  • 代码实际包括了两个模块,一个是mysql client端的封装,一个是sql的拼接器,这两个模块是完全独立的,调用者可以任意组合或者独立使用。

  • 4.尽量使用STL以及模板,简化代码编写
  • 最大的特点就是大量使用了stringstream进行类型转化,减少了大量的重复代码。

OK,基于以上的简单介绍,我们先来看一下
一.mysql client端的封装:

代码中的注释已经描述的很清楚了,语言描述不清楚,我们直接来看一下gtest的代码:
select:

insert:

可以看出,对于mysql的收发包已经很简洁了,但是sql语句的拼装却显得十分臃肿。所以这个时候sql语句拼装器-SQLJoin闪亮登场!
二.sql语句拼装器-SQLJoin

看看我们用了SQLJoin之后的代码应该如何:

从上面的代码可以看出,代码的可维护性和健壮性得到了很大的提升。

OK,简单的介绍就是这样,说的比较简略,大家有兴趣可以直接看代码,也欢迎给我提意见和建议。代码下载路径如下:
mysql_wrapper

明天这份代码就会作为数据库访问层正式进入生产环境的代码中,因此有什么bug我也会及时在这里更新。

暂无相关产品

7则回应给“再谈C++版的MySQL API封装”

  1. Carriage Bolts说道:

    额。。。。代码好多啊。。。头有点疼了

    [回复]

    Dante 回复:

    呃,确实代码有点多。。

    [回复]

  2. 刺猬说道:

    提个问题:
    另外还有一个隐性的原因,soci的代码大量使用了异常,而项目中要求底层代码是严禁抛出异常的(其实google也是有这个要求的)。
    这个 禁用异常 说说你们是如何考虑的?

    [回复]

    Dante 回复:

    有很多原因啦,我所理解的可能有几个:
    1.异常的效率比较低
    2.底层库抛出异常的话,如果上层没有捕捉就会使程序挂掉,而互联网服务是要保证进程尽量不死的。
    3.异常的捕获是跨函数的,很像goto语句。出问题很难定位。

    其实说到底还是一个项目管理的问题,如果真要强制所有开发人员都捕获异常,其实也不是不行。

    另外google公开的那份c++编码规范可以可以看一下,里面也有提到异常的问题。

    [回复]

  3. 单余若风说道:

    if(mysql_real_connect(m_Database, m_ip, m_user, m_pwd, m_db, m_port, NULL, 0) < 0)

    你这里本身的代码有问题,不能用<0去判断连接失败,而应该用==0
    if(mysql_real_connect(m_Database, m_ip, m_user, m_pwd, m_db, m_port, NULL, 0) == 0)

    [回复]

    Dante 回复:

    多谢提醒,看了官方文档,确实应该判断是否 == NULL

    [回复]

  4. kitbo说道:

    你好,看你的的这段代码感觉很不错,我学习一下封装代码的思想;可现在上不去google的网址,不知您可不可以将《再谈C++版的MySQL API封装》的代码发到我的邮箱,zhangyc@cucop.com。可能这个时候您已经有更新的代码了也可一并发来,,多谢了。。

    [回复]

发表评论