First we try, then we trust

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  183 随笔 :: 111 文章 :: 3015 评论 :: 339 引用

前段时间在CNBLOGS上面看到好多人谈论代码自动生成。这里所谓的代码自动生成是指自动根据数据库的内容身成数据访问存储过程以及对应的C#代码。比较典型的有CodePlus等(我最早看到的类似工具是DBHelper,大概是在CodeProject上,记不清楚了。功能强大而且完全开源)。

这些代码自动生成工具确实会帮助我们减少代码编写的麻烦,提高工作效率。不过,我在这里还是想对“代码自动生成”发表一下我的看法:

一、代码自动生成的言外之意是先有数据库再编代码

先设计数据库再根据数据库编写程序,很多人(包括我在内)都喜欢这样开发程序。因为这种开发模式似乎很对口味。不过问题也就随之而来了。

首先,数据库的设计方案是根据业务方案而来的,通常要进行完业务流程分析后进行数据流程分析,然后建立数据字典给出数据库设计方案(传统的管理信息系统分析于设计方式)。在没有充分进行业务流程分析的情况下就开始数据库的设计是一项很危险的事。

其次,我们使用的数据库通常是关系型数据库,而业务分析通常对应实体模型,为了更好的通过关系模型描述实体模型,数据库设计通常包括这么几个阶段:

  1. 需求分析,分析业务流程以及数据库流程
  2. 概念设计,包括局部设计以及集成设计反复迭代,给出E-R图(实体-关系图)
  3. 物理设计,包括确定数据库物理结构、字段方案、约束条件、索引等等,建立物理模型
  4. 数据库实施,通过DDL建立数据库

从分析的阶段上来看,也应当是先有实体而后有数据库。像Delphi 8中的ECO,在设计过程中首先进行对象的设计,然后通过Persist保存对象(可以存成XML,也可以存储成关系数据库)。

很多人(包括我在内)喜欢先设计数据库的根源在于过于看重编码而轻视了分析流程。导致一旦数据库底层发生变化(这是很可能的),所有上层内容,包括存储过程、O-R代码、业务对象乃至表现层都会发生变化。代码的自动生成缓解了写代码的压力,但没有从根源上解决问题。

软件开发的“依赖倒置原则”要求我们依赖于抽象而尽可能避免依赖于具体。在这里我们可以利用这种思想,将“抽象”提取出来。而最有可能担当“抽象”角色的就应当是“业务实体”本身。虽然客户需求的频繁变更倒置业务实体本身会发生变化,但是,这比依赖于数据库稳定的多。

陈震军的《典型的分层、接口和工厂的写法》描述的微软宠物商店的数据库设计,其中的抽象层定义了业务实体接口。一旦业务实体发生变化,两条并行工作可以同时进行:一是根据业务的实体的变化向下修改数据库;二是根据抽象业务实体接口向上修改商业逻辑以及界面等等。如果没有这层抽象,恐怕只能根据业务实体的变化调整数据库,然后从数据库开始修改数据访问层、实体层、商业逻辑层直到标识层。相比之下还是第一种做法好一些。(这只代表个人观点,欢迎大家讨论)

因此,所谓自动代码生成是根据关系模型生成实体模型呢还是根据实体模型生成关系模型,顺序问题值得讨论。


二、代码自动生成真的起到应有的作用了吗?

抛开O-R还是R-O问题,单纯从代码生成的角度来看,目前我看到的几种方案千篇一律,尤其是更新,生成的更新代码基本上没有抛开这个模式:

UPDATE ... SET ... WHERE 关键字段=.... AND 其它字段=....

数据库的更新如果真的这么简单就好了。不要忘记,现有的离线数据访问模式虽然提高了数据库的使用效率,但也带来了一系列的问题,其中最重要的一条就是并发操作(解决更新冲突问题)。并发操作的表现形式包括丢失的修改、不可重复读、读脏数据等(数据库原理里面有详细的说明以及解决对策),可到了代码自动生成这里,似乎这些并发问题根本不会出现。

就拿丢失的修改来说:

T1、甲售票员读出机票余额 16,存入本地缓存;
T2、乙售票员读出机票余额 16,也存入本地缓存;
T3、甲卖出一张,更新数据库 16-1 =15;
T4、乙也卖出一张,更新数据库 16-1 =15。

这时候发现数据库中有15张票,而实际卖出了2张票。

为了检测出并发异常,应当在更新时检测是否有数据库被其它人更改过。实现手段就是在UPDATE命令的WHERE子句中增加条件,判断数据是否还是当时读入数据时的数据。比如上面的问题在更新时应当写成:

UPDATE ... SET Ticket=15 WHERE 关键字段=... AND Ticket=16

其中后面的Ticket=16就是用来保护并发冲突的。16是当时读入数据的原始值。

而在CNBLOGS中我看到的代码自动生成工具,没有人考虑这些更新问题,也没有人考虑保留原始数据,而是将这些问题一并推给了DataSet对象。不知道用这些工具生成的代码是否真可以使用?

Visual FoxPro很早就把更新中WHERE短语生成策略考虑进来了。在VFP视图更新策略中,VFP(实际上Delphi也提供了类似的功能)提供了以下几种WHERE短语生成策略:

  • 关键字
  • 关键字和可更新字段
  • 关键字和已更新字段
  • 时间戳

虽然不能涵盖所有策略,但不失为一种好的解决方案。


三、更新成功后的后续操作怎么办?

如果再退一步,抛开一、二两个问题,更新真的可以成功。那么看下面的例子:

有张表有三个字段:学号、姓名、年龄。

一个人更新了年龄后,我更新了姓名(使用UPDATE Student SET Name = "aaa" WHERE id = 1 )。由于使用了离线数据库访问方式,这时候我不知道年龄也变了。正常情况下,在更新完成后要将数据库中的数据与目前缓冲中的数据库做一个同步,也就是说重新读入一次数据(在不同的应用系统中,这一步可能不是必须的)。但在自动生成代码的工具中没有人提供这种选项。


总结

上面就是我对代码自动生成工具的一些看法。随时欢迎大家讨论、批评、指正。

posted on 2004-09-04 13:21 吕震宇 阅读(7784) 评论(31)  编辑 收藏 网摘 所属分类: 数据库技术

评论

#1楼  2004-09-04 15:14 birdshome      

自动代码工具存在意义在于我们是否会有对重复代码的需求,而和本身的实现没有关系。如果对两个字典表的新建、更新、删除,你都可以设计成完全不同的代码(除了表名和字段),那就真的没有必要AutoCode了。


  回复  引用  查看    

#2楼  2004-09-04 16:52 吕震宇      
我不否认AutoCode带来的好处,只是希望能从另外一个角度增加AutoCode的价值。这种增值不仅仅停留在根据数据库生成代码的层次上,而是根据用户需求定制数据库以及代码生成策略。

这样,便可以对各个阶段代码生成过程增加控制手段,而控制的直接来源就是用户的业务需求。

从业务出发应当比从数据出发更为灵活。
  回复  引用  查看    

#3楼  2004-09-04 17:12 progame [未注册用户]
楼主对代码自动生成的理解有误(或者说不全面)

1、class->database还是db->class?
我对两者都不反对,有些程序是DB为主的,有些DB只是一个简单的存储方式,所以不同情况不同分析
2、代码生成的作用
我现在代码自动生成主要是用在O/R mapping中的,生成纯数据的实体类,生成XML的mapping文件(但我不生成SQL语句!!!),所以楼主所理解的代码自动生成只是很缺乏灵活性的一种生成方式

在以前,我曾经写过相应的模板,但后来我没有使用,因为我的OPLIB、DALOP、SINOLIB都不是利用这种简单的SQL来进行管理实体<->数据库的

3、这种功能不是自动代码生成去做的(当然也可以做)

如果有兴趣,可以到我主页上看看:
http://progame.vip.myrice.com/
  回复  引用    

#4楼  2004-09-04 18:26 吕震宇      
@progame

好象都是VB的代码,不过我会学习学习的。谢谢!
  回复  引用  查看    

#5楼  2004-09-04 22:30 寒枫天伤      
数据库本来就不是专门给面向对象技术的开发的,它们之间有一定的磨擦,甚至还有矛盾之处。

一个完美的O/R映射是不可能做到的。因为这涉及到一个关系建模的问题,现在的面向对象理论与实际的面向对象技术之间还有着一定的距离。
  回复  引用  查看    

#6楼  2004-09-05 08:40 风前絮~~      
1.自动代码范围不应该只包括O/R Mapping,应该包括好多方面,但感觉应该在一定的业务Framework下才有意义。
例如你做了一个针对自己业务的Framework后,在这个基础上自然可以总结出一些编程规范和模式,就可以利用自动代码来加快这些重复性的劳动了。
2. O/R Mapping我觉得应该以先Object在DB的顺序做符合逻辑,对于已经存在的DB,Object会自动去对应,当然这些由O/R Mapping组件去做了,这个XPO似乎做得不错,但只支持Access和MS SQL。有兴趣可以看http://www.cnblogs.com/windsails/articles/39263.aspx
3. 自动代码生成似乎现在用XML在结合XSLT来转成需要的代码的工具好多,当然这得益于XML技术的发展,但还有一些工具则是利用解释器的原来来做的,例如CodeSmith用一个可以解释类ASP.NET的语言做,还不清楚它是否直接扩展了ASP.NET的解释器,如果是这样的话,应该也是个好的思路,毕竟解释器都好多了,以前的Basic,Perl等...这样有个好处就是模板本身也是可以动态执行的,功能比用XSLT来解释应该强好多,当然似乎XSLT似乎也可以看成是解释器?!
目前在看CodeSmith,有兴趣的同好一起讨论啊 ^_^
  回复  引用  查看    

#7楼  2004-09-05 08:49 吕震宇      
虽然我还不清楚CodeSmith是什么,但是我以前看过有人用CodeDom生成代码,效率也不错。这个XPO我也在看。其实C#下类似的框架很多,只是想理出个头绪来。看来我还要继续努力呀...
  回复  引用  查看    

#8楼  2004-09-05 11:42 rexsp      
任何一个工具都不可能解决所有的问题,但不代表没有存在的价值。抽象出一种好的架构出来,代码自动化是完全可能的。代码自动化也是在发展初期吧,有一定的局限性,但这反感表明,其还有很大的发展空间的。
  回复  引用  查看    

#9楼  2004-09-05 18:04 ddl      
代码生成器只是个辅助的工具,起到的目的只是帮助用户生成一些无聊的格式固定的代码,而可以让使用者花更多的精力放在业务逻辑的实现上.
对于现有数据库库还是代码的讨论,个人认为如果一个系统是以操作数据为目标,那代码必须在数据库的基础上搭建.
至于作者讲道的自动生成代码没有进行一些数据完整性的保证,我觉得这里已经不属于代码生成器负责的数据访问层或者是实体层应该考虑的问题,这些问题应该交给业务规则层.
代码生成器生成的代码不仅仅应该局限于对数据的访问,也可以包含其它和数据库相关的内容,向O/R映射等等.

  回复  引用  查看    

#10楼  2004-09-06 18:55 飞刀      
自动生成代码,主要是思想上、设计上的考虑。
不过,当然有些小打小闹的软件。

如果楼主研究过MDA,就知道自动生成代码的最佳用途(当然是我个人认为),虽然自动生成代码只是MDA的某一种表现而已。
  回复  引用  查看    

#11楼  2004-09-06 19:07 飞刀      
哦,上面发的东东,写少了,呵呵,再发

自动生成代码,主要是思想上、设计上的考虑。
不过,当然有些小打小闹的软件做些好玩的功能,但是并没有切入到自动生成代码的真正应用。

如果楼主研究过MDA,就知道自动生成代码的最佳用途(当然是我个人认为),虽然自动生成代码只是MDA的某一种表现而已。 
  回复  引用  查看    

#12楼  2004-09-06 20:52 吕震宇      
@飞刀

我只读过《解析MDA》,《应用MDA》正在读。MDA的思想让我感触颇多。实现代码自动生成不但需要在设计方面深思熟虑,而且在代码生成的过程中也需要有灵活的控制。我认为关键还是在“思想”。实际上我认为MDA不但提供了代码自动生成,更重要是描绘了未来系统设计的前景。我对它充满信心。

文中讨论的代码自动生成是狭隘了一些,不过作为一个出发点,还是有一定意义的。毕竟我现在还没有用上.NET下的MDA工具。写上面的东西的目的也是希望就此讨论讨论。
  回复  引用  查看    

#13楼  2005-04-23 16:54 david [未注册用户]
T1、甲售票员读出机票余额 16,存入本地缓存;
T2、乙售票员读出机票余额 16,也存入本地缓存;
T3、甲卖出一张,更新数据库 16-1 =15;
T4、乙也卖出一张,更新数据库 16-1 =15。

这时候发现数据库中有15张票,而实际卖出了2张票。

==============

更新数据库 16-1 =15。的操作应该在服务器上以存储过程方式完成,楼主的方法决不能出现。
  回复  引用    

#14楼  2005-07-19 14:06 bruce [未注册用户]
Snake.Net中的数据映射是基于DataSet对象的。DataSet 对象是 Microsoft .NET 框架中数据访问的关键部分,是可保存表、视图和关系的内存中对象。Snake.Net中的数据映射是通过定义一个描述业务实体的DataSet(如图1.1),将其所需要应用到的数据表结构定义(表以及表与表之间的关系)进行描述。然后通过构建一个业务实体类(Class)并将类内特定域(Field)映射到DataSet中相对应数据表内的字段而实现的。

Snake.Net代码包内包括以下内容:
所有代码在Eastasp.Enterprise.Core目录下,
所有需要使用到的类库在library目录下
演示事例在Eastasp.Enterprise.Core.Samples目录下
数据库脚本在scripts目录下(当前仅提供MSSQL)
目录DataBindObjectBuilder下提供了一个实体类生成工具DataBindObjectBuilder你只需要选择一个特定的xsd文件,然后按生成即可。

Snake.Net目前提供的是测试版本,近供有兴趣的同仁参考和使用
如果你在试用的过程中发现不足之处,欢迎指正。

详细情况请访问我的Blog
http://blog.csdn.net/soulroom/

下载地址
http://www.eastasp.com/download.files/products/snake.net.rar
http://download2.eastasp.com/snake.net.rar

  回复  引用    

#15楼  2005-09-09 12:39 蛙蛙池塘      
刚发现这个帖子,不错。
  回复  引用  查看    

#16楼  2006-02-26 21:05 张育龙 [未注册用户]
代码生产器的产生我认为是一种技术上的进步,代码生成器至少可以解决一些简单重复性的劳动;当然,如果结合一些成熟的框架,设计模式,就更好了;代码生产器代表语言在向更高级的方向发展;高级语言有它的优点,一般是高效;但也有它的缺点,一般就是应用范围随着语言的高级化,它的应用面会变窄.

我也做了一个.Net的代码生成器.现在支持的数据库类型有SqlServer, Oracle,Access, mySql , XML,支持的语言有C#,VB.NET;支持的应用类型有Web,Win;支持的开发环境有Vss2003和VSS2005.
系统采用多层框架,分为通用类库,通用控件库,数据访问层, 项目专用控件组件;业务规则层;UI界面层;
系统实现了比较完整的OR映射,表,记录,字段,Primary Key,Unique Key,Foreign key,Null ,Default等数据库对象都映射了.net的对象;
系统应用了MVC,Factory, Bridge,Single等多种设计模式;

PoerCoding目前提供的是测试版本,近供有兴趣的同仁参考和使用
如果你在试用的过程中发现不足之处,欢迎指正。

访问地址为http://www.PowerCoding.Com
  回复  引用    

#17楼  2006-05-20 21:41 张育龙 [未注册用户]
DotNetCoding(http://www.dotnetcoding.net">http://www.dotnetcoding.net)是一款帮助开发以数据库为基础,以DotNet为开发语言的Case开发工具。它集系统设计,代码自动生成等功能于一体
系统运用分层原理和组件原理,将所有的基于数据库访问的系统划分为用户界面层(UI),业务规则层(BLL), 数据访问层(DAL)和数据库层(DB). 每一下层为上层提供支持,一般不跨层访问,是一个真正意义上的多层架构; 同时结合现在一些已经成熟的设计框架,设计模式和构件模式,将一个解决方案分解为6个Project. 分别是通用类库, 通用控件库, 数据访问工程, 业务规则工程,项目专用控件工程,UI界面工程.整个方案根据已经设计好的数据库自动生成,在生成的过程种可以灵活的定义生成参数.
系统实现了比较完整的O-R映射.数据库中的所有逻辑对象表,列,字段,主键,外键,Null, Default,唯一索引都在类里得到了体现,同时还支持代码表,代码列,自增长机制.
系统支持完整的数据操作功能,支持带事务功能的数据操作,提供数据自动装载功能,有很强的数据查询功能.
系统采用强类型来进行代码的生成,并且对最终开发人员的强类型支持很好,从而减少在编码过程中引入的错误,为编写高质量的代码提供了强有力的支持.
系统也比较充分的考虑了变更与维护的需要,在数据库设计发生变化的情况下,只要在已有工程的基础上重新生成一遍,系统就会自动合并最终开发编写的代码到生成的代码中,使系统的变更变的很容易.
UI界面层按到组件原则来进行代码的自动生成.自动生数据编辑,数据显示控件,页面组合组件,并采用控件和CSS技术,由于采用了这些组件技术,使得最终开发人员可以很方便的变更自动生成的界面样式; UI界面应用MVC模式,将这个UI界面代码部分分为三部分:视图部分,模型部分和控制,自动生成Data Source属性来完成view和Model的相互映射;并且能按照功能组生成菜单, 同时系统能自动完成null, PK ,UK等基本的数据检验和基于单表数据的增删查改等基础功能.
此系统还提供了文档生成,数据库迁移与转换及部分设计有关的功能
现在此平台支持多种数据访问框架(三层框架, PetShop框架,工厂框架, WebServeice框架)
支持Windows , Web两种应用类型
支持VB.net , c#.Net两种开发语言
支持SqlServer, Oracle, Access等多种数据库, 并且支持用SqlServer数据库来进行数据模式的设计,而实际开发运行数据库是其他数据库的情况, 开发的应用可以非常轻松的变换数据库.
本系统的应用范围:有数据库访问功能的.net应用
应用前提:需要有已经设计好的数据库
采用此平台来开发信息管理系统, 能够直接将设计转化为代码,并支持系统的重构;最终开发人员一般只需要在业务规则层扩展相关业务规则的编码,对自动生成的界面进行少量的调整,在UI界面工程里添加少量的控制代码.
采用此开发平台,能够复用成熟的开发架构,自动生成所有非商业有关的代码,在公司范围内不断的积累开发技能和经验,极大的提高开发效率,规范开发,提高开发质量。
欢迎使用dotnetcoding(http://www.dotnetcoding.net">http://www.dotnetcoding.net)代码生成

  回复  引用    

www.bz2008.com
理论上可以生成各种语言、各种数据库的各类代码,包括数据库脚本、输入、输出、报表,有规律的树形,注册后就可以使用,不需要安装任何程序和组件。
大家看看怎么样

  回复  引用    

这个网站的自动代码不错
www.bz2008.com
  回复  引用    

#20楼  2006-07-13 09:37 龙哥哥 [未注册用户]
www.58186.cn 也可以。
  回复  引用    

#21楼  2006-07-13 15:03 仰天一笑      
好文,收藏,最近在看这个
  回复  引用  查看    

#22楼  2006-07-20 09:36 sp [未注册用户]
最近发现一个代码生成工具的好东东,是国人写的免费的.

这时官方网站上的介绍.
==========================================
Spdevelop是国内唯一基于模板引擎的代码生成工具.还集成数据库建模软件。

Spdevelop致力于满足全球开发人员的愿望和需求. 两年来,我们一直坚持不懈追求一个目标:帮助改善开发团队在软件开发项目中的协作、提高软件质量、加速应用程序开发.
SpDevelop DB Designer是一款数据库建模软件,它可根据用户的需求进行调整,二次开发,它支持完全成熟的相应商业软件(如Visio或ERStudio)的所有功能,SpDevelop的数据库建模功能有:图形化设计,模块化设计,正向反向工程,基于VSS的项目管理,丰富的导出方式等功能.利用它,您甚至可以生成各种各样的代码,可以作为多种数据库的查询分析器
SpDevelop Code Gener是一种基于模板的代码生成工具,它使用类似于 ASP.NET 的语法来生成任意类型的代码或文本。与其它许多代码生成工具不同,SpDevelop不要求你订阅特定的应用程序设计或体系结构。借助SpDevelop可以生成包括简单的强类型集合和完整应用程序在内的任何东西。
下载地址:www.spdevelop.com
  回复  引用    

#23楼  2006-10-12 13:56 许欢 [未注册用户]
代码主要是在编码阶段产出的。之前是设计。因此,真正的代码自动生产必须以设计结果作为输入。
Heavenlake Auto 在这方面做的不错,有兴趣可以下载试一试。

下载地址:http://www.heavenlake.com/products.html
  回复  引用    

#24楼  2006-10-12 13:57 许欢 [未注册用户]
Heavenlake Autocode 1.0
  回复  引用    

各位高手帮帮忙 :我想编个代码生成器,但是脑袋一团浆糊,请各位帮帮我,应该从何下手,万分感谢!!
  回复  引用    

#26楼  2006-12-06 16:31 lim [未注册用户]
天池软件自动化生产平台 Heavenlake Autocode 1.1 发布了

1.1版:

增加了权限控制的接口。

增加了两个示例,
一个为企业电子商务门户软件(演示:http://ecommerce.heavenlake.com),
一个为型号产品数据管理系统(演示:http://pdm.heavenlake.com)。

修改了1.0版本中,生产javaBean代码时不能及时获得设计更新的问题。使用了“java类重载”技术。现在无须重新启动AutoCode即可感知最新的设计变更。
  回复  引用    

#27楼  2006-12-21 11:19 一剑飘红[匿名]      
不错不错,我个人也在搞代码生成,可以找人交流了..呵呵
  回复  引用  查看    

#28楼  2007-02-13 01:56 Bention      
- -!!!!咋这么多代码生成器的广告呢
  回复  引用  查看    

#29楼  2007-08-18 21:44 Clark Chan      
决定学习MDA,做MDA代码生成器,并使用之才有意义.
  回复  引用  查看    

代码自动生成(java模板语言)

http://bbs.skystonesoft.com/viewthread.php?tid=1&extra=page%3D1
简单说明:
模板解释性语言,在模板中没有特殊标记的部分,原封不动输出,
标记的部分允许所有的java语法,并解释执行。
用途:代码自动生成
比如:开发完了一个类文件,但还有很多类似的类要做,只是要改变一些个别的地方,
那么,可以把需要改动的地方用java变量标记,然后运行该模板,自动生成多个类。

  回复  引用    





标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2004-09-04 13:40 编辑过
Google站内搜索

相关文章:

相关链接: