楼主: yulihua49

[PRO*C] 看我做的数据库包装器

[复制链接]
论坛徽章:
519
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
31#
发表于 2008-11-25 03:26 | 只看该作者
呵呵,我说怎么找不见贴,原来置顶了。关于C或JAVA的各种FRAMEWORK的讨论超出我的范围,我就说几句外行话,如果不对请指正。

"于是,1楼的那句话你注意没有?
DTO_toJSON(&seat_DTO,json,0);
一句话,一个row的数据打包完成!怎么样,劳动生产率一下至少提高17倍吧?"

1楼的这段程序,我觉得就应该是这样:
用start_date,Train_no,carno作输入参数,调用一个存储过程; (而不是你的组装stmt)
存储过程利用这些输入作DML或查询,最后输出一个结果集(或几个返回参数)(这就是我说的“业务逻辑”,我认为该用存储过程实现)
遍历这个结果集,该怎么用就怎么用。如果你还想传给前台的其他模块,又必须按规定包装成JSON或者什么,那完全是和业务无关的,属于数据的格式化,你愿意的话完全可以做一段通用程序(类似DTO_toJSON)去处理,或者用一段自动生成的代码去处理。
这些前台程序员,他们看到的是事务接口,而不用关心数据库端的实现。你也说了是由你们的精英来完成的,一般程序员何必知道里面有这个SEAT表?何必知道某个地方要用自动模板,另一地方就用手动模板?他们只需知道根据输入(来自用户或来自其他模块)可以得到想要的数据,这数据完全可能是从几个表通过复杂连接得到的;只需知道把输入喂给数据库,数据库就会用DML把数据写到该去的地方,可能是一个或多个表。


"许多复杂的业务处理是需要动用函数的,函数间怎么传数据,当然是传一个结构要比传一大堆离散的变量要好得多。"
如果采用我说的存储过程方式,复杂性屏蔽到数据库里了,前台模块间接口将会简化,层次也会少很多。当然你可以用你喜欢的方式在中间传递数据,到最里层再换成数据库能辨认的格式。


"SQL都是面向列的,怎么组装结构?一个一个列的点名吗?……"
当我们在PL/SQL DEVELOPER中查看一个输出结果集(游标)的时候,它会自动变成二维表的形式(组装结构),这不难做到吧?我只管写我的SQL, 输出什么就不用再去一个一个的点了。这就是我上面说的可以有“通用程序”来处理数据的格式化。


"数据结构变化了,怎么办?你必须把所有列名列表检查一遍:prepare、fetch into、insert、update,以及所有的应用逻辑。这使我们陷入痛苦的泥潭。"
我的建议是要在客户端程序消灭SQL, 全部放到存储过程中,仅留下事务接口。如果接口变了,那么调用的地方肯定要修改;如果只改动后台结构,那么只需修改存储过程(虽然这种情况并不多见)。
数据结构变了,存储过程中的DML(INSERT UPDATE等)要作相应修改,这在我看来并不痛苦。静态的SQL有它的好处:你可以在编译的时候就知道SQL有没有写错,你可以把它分离出来调优,如果哪个数据有错,你可以轻易跟踪到输入源头。一个事务涉及了什么表,数据从哪里来,怎么变化、怎么加工,用静态SQL看起来十分直观。这样的事务处理程序容易维护。
用你的方法,则是修改模板,在我看来并不比改写PL/SQL方便多少。如果是“使用时建立”的动态模板(利用数据库字典),那么你就等于自己多套一层,系统性能要打个折扣。
依赖模板的动态SQL, 调试调优就更加困难。你的DBA可能从后台找出性能不佳的SQL, 但这个SQL是从什么地方组装出来的?那可要费一翻脑筋,用SQL全文检索是找不到的。


"模板,可以手动建立,也可以自动建立,还可以使用时建立,就像1楼。"
不知道你的程序运行时候能否不依赖模板?我的看法是模板仅仅是用作开发的辅助工具,你可以用模板生成源代码,程序是脱离模板运行的。


"就像铸模,做一个模子,你可以浇铸一百个、一千个产品,比起给你一个铁疙瘩,你锯、你锉、你凿,即使你是高级铁匠,能有什么生产率呢?师傅还非常自豪的说:我们根本不需要模子!"
钟表匠不会浇铸出一个个齿轮然后交给你去组装。你最多就是装上电池,拧紧发条。至于钟表匠自己用什么模具?哪些部件可批量生产?原材料有几种?那就是钟表匠的事啦。


"我们做的是流水线上的一个部件,他让工人变成傻瓜,只要会几个简单动作,就会生产出我们要的产品。这个部件的设置是需要精英来做的,设计数据结构、构建模板(不管是手工还是自动),提供DAO。剩下的,让工人做去吧,老板要的就是这个。"
你的流水线在DAO, 我的流水线在数据库里。工人仅仅作UI的处理(收集输入数据,展示输出数据),当然他们也不能是傻瓜,这部分的编程也有技巧和讲究,但已经不属于事务处理范围了。

再来看看那天说的并发处理,你用SELECT ... for update WAIT 10 SKIP LOCKED确实不会出现重票的问题。但这里也有一个小问题,如果你开两个SESSION做如下测试:

SELECT * FROM SEAT WHERE FLAG=0 AND ROWNUM<2 for update WAIT 10 SKIP LOCKED;

第二个窗口其实会返回NO_DATA_FOUND, 它不会往下再找一条新记录去加锁。

使用道具 举报

回复
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
32#
 楼主| 发表于 2008-11-25 12:48 | 只看该作者
原帖由 shinerainy 于 2008-11-24 21:30 发表


什么东东??一点都看不懂哦。。

就是想用数据库,不想写SQL语句。

使用道具 举报

回复
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
33#
 楼主| 发表于 2008-11-25 12:53 | 只看该作者
原"SQL都是面向列的,怎么组装结构?一个一个列的点名吗?……"
当我们在PL/SQL DEVELOPER中查看一个输出结果集(游标)的时候,它会自动变成二维表的形式(组装结构),这不难做到吧?我只管写我的SQL, 输出什么就不用再去一个一个的点了。这就是我上面说的可以有“通用程序”来处理数据的格式化。

怎么组装结构?没用过,请教。
“通用程序”,你写通用程序,怎么面对不知道的结构?JAVA可以有反射机制解析未知对象,C和C++都不可能。就只能靠模板了。

使用道具 举报

回复
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
34#
 楼主| 发表于 2008-11-25 13:00 | 只看该作者
依赖模板的动态SQL, 调试调优就更加困难。你的DBA可能从后台找出性能不佳的SQL, 但这个SQL是从什么地方组装出来的?那可要费一翻脑筋,用SQL全文检索是找不到的。

调优,主要是分析where子句,DTO并未封装where。那是应用层的DAO封装的,DAO程序员自然会分析。


不知道你的程序运行时候能否不依赖模板?我的看法是模板仅仅是用作开发的辅助工具,你可以用模板生成源代码,程序是脱离模板运行的。


模板是运行时需要的,甚至开发时可以不出现 如1楼。

通用程序如何把一个未知的struct与结果集、JSON对象、通信字符串或其它形形色色的数据映像呢?要知道,C的struct是不可解析的,
至今我未发现能够解析C结构的软件出现,只能是盲人摸象,就是依靠模板。模板就是让应用程序能够摸到用户结构的成员。见:
http://space.itpub.net/8804348/viewspace-478471
那里边的例子就是DTO出现前的SRM程序,包的不严,最多算是个睡裙。DTO就是阿拉伯长袍了,还露一个where的小脸蛋。DAO就戴上面纱,我们的ORACLE美女可就一点见不着了,真是让人不爽。你就专心看她的拿手菜,就别老是心猿意马的想看人家的身体啦。

[ 本帖最后由 yulihua49 于 2008-11-25 13:25 编辑 ]

使用道具 举报

回复
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
35#
 楼主| 发表于 2008-11-25 13:35 | 只看该作者
再来看看那天说的并发处理,你用SELECT ... for update WAIT 10 SKIP LOCKED确实不会出现重票的问题。但这里也有一个小问题,如果你开两个SESSION做如下测试:

SELECT * FROM SEAT WHERE FLAG=0 AND ROWNUM<2 for update WAIT 10 SKIP LOCKED;

第二个窗口其实会返回NO_DATA_FOUND, 它不会往下再找一条新记录去加锁。



我也是担心这个问题。这个逻辑是INFORMIX的,它处理跳锁是在FETCH阶段,prepare-open阶段是把含锁的行一并装入活动集。文档明确说,连续两次 Fetch next将跳过被锁的记录。
ORACLE不是这样,它是在prepare时处理,就像你说的那种情况。这句话是向接手的人表明一个意图,将来有合适的方法取代之。语句的实际功能与不跳锁没什么两样。

SYBASE又一个样,在from子句里写 readpast,可惜,在游标环境下这句话错误,非游标环境下不能加锁,弄得这玩意儿没用了。

[ 本帖最后由 yulihua49 于 2008-11-25 13:41 编辑 ]

使用道具 举报

回复
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
36#
 楼主| 发表于 2008-11-25 13:58 | 只看该作者
用start_date,Train_no,carno作输入参数,调用一个存储过程; (而不是你的组装stmt)
存储过程利用这些输入作DML或查询,最后输出一个结果集(或几个返回参数)

前边说了,如果解析一个结果集到结构,我仍需模板。此时,并不能保证存储过程里的sql与我的模板一致。
况且,你在存储过程里,结果集要重新筛选过(我发表的程序只是DEMO,并非完整的,其中还有筛选算法略去),选中的席位占用、打包输出。你如何重新组织结果集?用临时表吗?效率要比我低了吧?
我的DTO_prepare()要简单多了吧?还能保证语句结果集和struct的一致。C程序的处理能力要比那半编译的存储过程高多了,灵活多了吧?

DTO,虽然内容不多,也很简单,但是,它是一个完整的框架体系,不方便割裂开的。它的重要缺陷是不能处理BLOB类型和存储过程。
这些内容要在libsqlora或OCI层面来处理,应用程序完全可以脱离DTO调用sqlora8来处理。SQL_Connect->dbh就是sqlora的句柄。

前边说了,我们是三层 C/S应用,不允许客户端访问数据库的。广义的讲,我这里就是存储过程了,不过不是数据库的,是C的。

[ 本帖最后由 yulihua49 于 2008-11-25 14:23 编辑 ]

使用道具 举报

回复
论坛徽章:
0
37#
发表于 2008-11-25 14:08 | 只看该作者
完全浪费了数据库的强大功能,自己找罪受。花钱卖了数据库,却要自己写里边已经都实现的功能 = =!

全用存储过程,充分发挥数据库的性能,高级语言专注于业务逻辑,程序简洁、清晰,容易维护。

如果真的遇到要换数据库的情况(在我看来跟被陨石砸中的概率差不多... 我想一个成熟运行的复杂应用,不到万不得已是绝对不能换数据库的),把所有的存储过程重新写一遍,都比这样开发代价低

使用道具 举报

回复
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
38#
 楼主| 发表于 2008-11-25 14:30 | 只看该作者
原帖由 badcatgarfield 于 2008-11-25 14:08 发表
完全浪费了数据库的强大功能,自己找罪受。花钱卖了数据库,却要自己写里边已经都实现的功能 = =!

全用存储过程,充分发挥数据库的性能,高级语言专注于业务逻辑,程序简洁、清晰,容易维护。

如果真的遇到要换数据库的情况(在我看来跟被陨石砸中的概率差不多... 我想一个成熟运行的复杂应用,不到万不得已是绝对不能换数据库的),把所有的存储过程重新写一遍,都比这样开发代价低

没有浪费,几乎所有功能都可以实现,只不过更简单了。
虽然有潜在的换数据库的意图,但不是主要的,主要是把数据库与应用割裂开,让精英处理数据库,草根处理应用。
另外提供一些工具,方便数据打包和格式变换工作,用于支持数据传输。
按记录访问数据库也是一个目的。自从SQL出现后,没办法按记录和struct操作数据了。

这个项目在这里提出来,可能就是反对的多,因为在这混的大多是精英,可是,你们想过草根的痛苦吗?

[ 本帖最后由 yulihua49 于 2008-11-25 14:51 编辑 ]

使用道具 举报

回复
论坛徽章:
2
2010新春纪念徽章
日期:2010-03-01 11:07:21ITPUB9周年纪念徽章
日期:2010-10-08 09:31:21
39#
发表于 2008-11-25 16:18 | 只看该作者
如果真的遇到要换数据库的情况(在我看来跟被陨石砸中的概率差不多... 我想一个成熟运行的复杂应用,不到万不得已是绝对不能换数据库的),把所有的存储过程重新写一遍,都比这样开发代价低


转换数据库这个问题在客户那里是很少见到的,但是软件公司的通用产品要应对不同的客户,不同客户有不同的需求,A喜欢Oracle,而B喜欢DB2,难道我们的产品都要为不同的数据库重写一遍吗?所以说,一个通用的中间层是必然的选择。

使用道具 举报

回复
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
40#
 楼主| 发表于 2008-11-25 16:25 | 只看该作者
原帖由 fflush 于 2008-11-25 16:18 发表


转换数据库这个问题在客户那里是很少见到的,但是软件公司的通用产品要应对不同的客户,不同客户有不同的需求,A喜欢Oracle,而B喜欢DB2,难道我们的产品都要为不同的数据库重写一遍吗?所以说,一个通用的中间层是必然的选择。

请看楼上,转换数据库不是主要目的,至少现在不是。但我手里的确有一套关于SYBASE的。现在的主要是分离业务逻辑和访问逻辑。实际上,在SRM层就能分离数据库。DTO层分离访问逻辑,但不彻底,提供简短、方便、数据一致的上下文的应用函数是主要的。最彻底的分离在DAO层,这是一个应用层,不属于框架。在什么环节上分离可以在应用时定夺,毕竟应用逻辑和访问逻辑并没有一个明确的分水岭。

[ 本帖最后由 yulihua49 于 2008-11-25 16:35 编辑 ]

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表