免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3611 | 回复: 4
打印 上一主题 下一主题

有对C语言数据库包装感兴趣的吗?交流交流 [复制链接]

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-02-10 16:52 |只看该作者 |倒序浏览
利用包装器访问数据库,可以简化数据库操作,将访问逻辑与应用逻辑分离是程序更加清晰易懂。特别是,程序与数据适当分离,当数据结构变动时,尽可能少的改动程序。
我在这方面做了一点工作,与大家分享。
与JAVA的Hibernate类似的东西,在C语言实现,当然不是面向对象的,但也考虑改成C++。  
http://www.itpub.net/thread-1088197-1-1.html
这个包开始名为DTO,后来改名DAU,意为Data Access Unit 。现在是用于ORACLE的,容易改成其它数据库。

微软公司的ADO (ActiveX Data Objects) 是一个用于存取数据源的COM组件。它提供了编程语言和统一数据访问方式OLE DB的一个中间层。允许开发人员编写访问数据的代码而不

用关心数据库是如何实现的,而只用关心到数据库的连接。访问数据库的时候,关于SQL的知识不是必要的,但是特定数据库支持的SQL命令仍可以通过ADO中的命令对象来执行。

DAU赞同ADO的这些概念,并在更广泛的平台上使用。功能上也有进一步的改进,基本上可以在运行时生成SQL语句,在多数情况下不需要手动写,从而将SQL语句彻底从应用中隔离

出来。

看看ADO的update语句:
sql="UPDATE customers SET " PsOXNSF6<_  
  sql=sql & "companyname='" & Request.Form("companyname" & "',"  
  sql=sql & "contactname='" & Request.Form("contactname" & "',"
  sql=sql & "address='" & Request.Form("address" & "',"  
  sql=sql & "city='" & Request.Form("city" & "',"
  sql=sql & "postalcode='" & Request.Form("postalcode" & "',"   
  sql=sql & "country='" & Request.Form("country" & "'"
  sql=sql & " WHERE customerID='" & cid & "'"
  on error resume next
要是DAU:   
//sprintf(stmt,"WHERE customerID=:customerID";这句还有WHERE,改下句:
//DAU _mk_where(&sql_DAU,"customerID",stmt);这句还是出现了列名,改下句:  
//sql_DAU.srm.pks记录了表的主键,下面的语句生成了上面的语句,而且更具通用性,可以处理任何按主键修改的表。

DAU_mk_where((&sql_DAU,sql_DAU.srm.pks,stmt);//如果customerID是主键
ret=DAU_update(&sql_DAU,stmt);  
就完事了。
象这样的语句:
sql=sql & "companyname='" & Request.Form("companyname" & "',"
在DAU内部,用完全类似的过程自动生成的。

下边看一个程序实例,涉及两个表的关联查询:其中JSON是我们的通信传输格式。  
JSON_OBJECT get_shift(T_SQL_Connect *SQL_Connect,char *msg)
{
int ret;   
DAU u_DAU[2],tdev_DAU;  
JSON_OBJECT result,json;
T_PkgType tdev_tpl[2]; //想选几个字段n+1

        result=json_object_new_array();
        ret=DAU_init(&tdev_DAU,SQL_Connect,"tuxdev",0,0);//从数据库生成表结构
        partt_copy(tdev_tpl,tdev_DAU.srm.tp,"devname"); //生成子模板,想选几个字段用,分割列表
        ret=DAU_init(&u_DAU[0],SQL_Connect,"dev_shift a",0,0);
        DAU_init(&u_DAU[1],SQL_Connect,"tuxdev b",tdev_DAU.srm.rec,tdev_tpl);
        sprintf(msg,"WHERE a.devid=b.devid");  
        ret=DAU_getm(2,u_DAU,msg,0);// 生成并执行SQL语句。
        while(!DAU_nextm(2,u_DAU)) {//取结果集一条记录
                json=json_object_new_object();
                DAU_toJSON(&u_DAU[0],json,0);//dev_shift全部打包到json
                DAU_toJSON(&u_DAU[1],json,"devname");//组合devname到json
                json_object_array_add(result,json);//在JSON数组中加入一条记录
        }
        DAU_freem(2,u_DAU); //释放访问单元
        DAU_free(&tdev_DAU);//释放访问单元
        return result;  
}

执行结果:
下面是生成的语句:  
buf=SELECT  a.devid,to_char(a.stat_date,'YYYY-MM-DD') stat_date,a.shift_flg,a.shift_code,a.userid,to_char(a.log_time,'YYYY-MM-DD HH24:MI:SS') log_time,a.beg_no,b.devname FROM TICKET.dev_shift a,TICKET.tuxdev b WHERE a.devid=b.devid
数据:
result=[ { "devid": "JOLTTEST", "stat_date": "2008-10-20", "shift_flg": "BB", "shift_code": "5", "userid": "hp", "log_time": "2008-10-20 14:44:34", "beg_no": "A0000001", "devname": "JOLT测试终端" }, { "devid": "JOLTTEST1", "stat_date": "2008-11-06", "shift_flg": "AB", "shift_code": "5", "userid": "hww", "log_time": "2008-11-06 16:12:26", "beg_no": "A0000001", "devname": "黄伟伟的JOLT测试终端" }, { "devid": "SP0102002", "stat_date": "2009-01-20", "shift_flg": "DB", "shift_code": "5", "userid": "ylh", "log_time": "2009-01-20 13:54:03", "beg_no": "A0000001", "devname": "售票测试终端2" }, { "devid": "SP0102003", "stat_date": "2008-10-16", "shift_flg": "DB", "shift_code": "5", "userid": "", "log_time": "2008-10-16 10:14:53", "beg_no": "A0000001", "devname": "售票测试终端3" } ]

如果有人诚意需求,可以提供源码,共同切磋。

[ 本帖最后由 yulihua49 于 2009-2-10 16:59 编辑 ]

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
2 [报告]
发表于 2009-02-10 17:03 |只看该作者
sprintf(msg,"WHERE a.devid=b.devid");

还是离不开拼SQL语句呀

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
3 [报告]
发表于 2009-02-10 17:46 |只看该作者
原帖由 hellioncu 于 2009-2-10 17:03 发表
sprintf(msg,"WHERE a.devid=b.devid");

还是离不开拼SQL语句呀

SQL基本是离不开的,就是Hibernate框架还是保留了HQL,有时把它放到配置文件里(如ADO或iBatis,我认为不是好办法。
特殊情况下,DAU可以自动生成WHERE,例如用主键访问时。
我这个demo简单了,应该写一个函数(我们成为DAO函数)把它包起来,在主程序就看不到SQL了。
建议你花些工夫看看这贴,里边有包装严密性问题,就是要包的严严实实,一点看不见SQL。
http://www.itpub.net/viewthread. ... p;extra=&page=1

下边给你4个DAO函数,用于主键(PK)操作:

int select_by_PK(DAU *DP,char *stmt)
{
int ret;

        if(!mk_PK(DP,stmt)) return FORMATERR;
        ret=DAU_select(DP,stmt,1);
        if(ret<0) return ret;
        if(ret==0) return -1;
        return DAU_next(DP);
}
int prepare_by_PK(DAU *DP,char *stmt)
{
int ret;

        if(DP->cursor<0) {
                if(!mk_PK(DP,stmt)) return FORMATERR;
        }
        ret=DAU_prepare(DP,stmt);
        if(ret<0) return ret;
        return DAU_next(DP);
}

int update_by_PK(DAU *DP,char *stmt)
{
        if(DP->upd_sth<0) {
                if(!mk_PK(DP,stmt)) return FORMATERR;
        }
        return DAU_update(DP,stmt);
}
int delete_by_PK(DAU *DP,char *stmt)
{
        if(DP->del_sth<0) {
                if(!mk_PK(DP,stmt)) return FORMATERR;
        }
        return DAU_delete(DP,stmt);
}

使用方法如下:
先把主键值填入数据记录。
然后:

ret=select_by_PK(&_DAU,stmt);

如果成功,结果就在记录里了,没有SQL吧?当然,SQL是消灭不掉的,只不过藏起来了。
你会在stmt里见到构建的SQL语句。

[ 本帖最后由 yulihua49 于 2009-2-10 17:59 编辑 ]

论坛徽章:
0
4 [报告]
发表于 2009-02-25 16:29 |只看该作者
建议不要在统一数据库访问接口上花工夫了,每一种数据库系统都有自己的特色和优势,强求统一没有意义。
记得以前有人曾经为了在所有数据库平台上提供oracle的sequence机制而写过一套东西,非常低效且不安全。

论坛徽章:
0
5 [报告]
发表于 2009-03-03 16:16 |只看该作者
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP