﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-萝卜青菜的BLOG-文章分类-技术类</title><link>http://www.blogjava.net/aawanghuan/category/15804.html</link><description>路漫漫其修远兮，吾将上下而求索！~</description><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 12:35:49 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 12:35:49 GMT</pubDate><ttl>60</ttl><item><title>.NET和J2EE的全面比较(二)</title><link>http://www.blogjava.net/aawanghuan/articles/83843.html</link><dc:creator>萝卜青菜</dc:creator><author>萝卜青菜</author><pubDate>Mon, 27 Nov 2006 09:47:00 GMT</pubDate><guid>http://www.blogjava.net/aawanghuan/articles/83843.html</guid><wfw:comment>http://www.blogjava.net/aawanghuan/comments/83843.html</wfw:comment><comments>http://www.blogjava.net/aawanghuan/articles/83843.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/aawanghuan/comments/commentRss/83843.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/aawanghuan/services/trackbacks/83843.html</trackback:ping><description><![CDATA[简介<br /><br />关于.NET技术与Sun公司的Java2企业版（J2EETM）相比较，许多客户都想了解Microsoft公司的观点。由于以下的几个原因，.NET和JEE的比较有点棘手：<br /><br />1) 一般来说，Windows .NET Framework是Microsoft的Windows系统中经过精心定义的技术部分，而J2EE则是一个书面的协议。如果不局限于学术方面的讨论，换句话说，就是在几个应用平台上讨论这个话题的商业价值，那么仅仅比较J2EE和一个实际应用的工具是没有意义的。<br /><br />这样实际应用的工具如：IBM公司的WebSphere应用服务，BEA的WebLogic服务或是其它类似的应用服务。<br /><br />要想得到令人满意的分析，只有进行产品之间的比较，例如比较开发效率。使用J2EE，开发者需要创建4个组件来建立一个单一的EJB。表面上看来，这只不过是为开发效率付出的一点代价而已。但是Java的一些开发工具隐藏了一些开发技巧，降低了效率。另一个例子，J2EE的部署体系十分复杂难解，类嵌入JAR，而JAR嵌入WAR，WAR又嵌入EAR。但是在一定程度上，有些工具能自动完成部署进程。上述情况导致决定一个应用服务商业价值的关键因素开发效率因不同的销售商而有差异，这主要取决于开发工具的效率。<br /><br />2) 关于“J2EE全明星队伍”的问题。当比较.NET和J2EE所有组件的集合时，这个问题就产生了。例如，分析者考虑开发效率时可能碰到下列问题，A公司的产品， B公司的应用服务程序， C公司的安全规则， D公司简便安装， E公司决定价格。所有这些都可能和J2EE有关。集合上述这些特征属性，J2EE工具看起来还行：价格便宜，安装简便，速度快，安全性高，有超高速缓存，并且有好的开发工具，等等。但这些都无关痛痒—因为不可能同时获得所有的这些特性。事实上，一次只能得到一个准确的特性。因为这些产品来自不同的公司，它们不可能合作无间。例如，IBM公司的工具不能和BEA公司的WebLogic服务同时工作，因为后者是用的Oracle公司的缓存引擎，而Oracle的引擎不能用Iona的价格获得，等等诸如此类。人们有时候会误将“J2EE的所有特性集合”作为比较的基础；但这是不合理的。客户需要的是知道一对一，产品对产品的比较。<br /><br />3）比较.NET和J2EE而忽视其它应用平台是十分重要的。J2EE是仅关注应用程序服务器的规范。但是绝大多数客户对下列这些感兴趣：应用程序服务器，端口，商业服务器和分析工具，数据库，分离数据和流动性，信息代理，应用程序集合，容量管理，智能客户端等等。作为对客户要求的回应，这些因素应该统一工作，所有的主要销售商应该推行整合的平台。例如Microsoft的平台（包括Windows系统的客户端和服务器，Windows .NET Framework，Visual Studio.NET Framework，和Microsoft企业服务器）；BEA的WebLogic平台；IBM公司的WebSphere平台；Oracle的平台；还有Sun公司的一个平台。将精力集中在这些平台的一个难题（应用服务器）上将会导致一个类似“树林和森林”关系的问题。这样的一个比方是合适的，但是它应该被考虑到一个更广阔平台的一部分。<br /><br />从Microsoft的角度来看，和那些不常见的警告相比，这些是Windows .NET Framework和基于J2EE的产品的关键性的异同点。<br /><br />相似点<br /><br />1） Windows .NET Framework和Java都有一个受控的运行时环境，它不但将源代码转换成中间语言，而且将这些中间语言编译成本地的可执行代码。两个环境都支持碎片整理、动态类加载和异常处理等。<br /><br />2） .NET和Java都倡导和支持基于组件的设计、多态性、继承和接口等，也提供基础类库来执行I/O、XML处理、带有连接池的数据库接入、文本操作与网页脚本编写等。<br /><br />3） 两者都经过特有的销售商的产品进行发布。J2EE规范自己是“销售中立”的，但实际上那些遵从规范的产品都必须实现规范外的特性，例如管理特性或是展开特性。因此，这些产品必须是对应特定的销售商。例如Microsoft公司的Windows和.NET系统。<br /><br />4） Windows .NET Framework和基于J2EE的产品都和第三方的产品一起工作。例如，在后端数据库领域，.NET和基于J2EE的应用程序能访问储存在Microsoft的SQL服务器、IBM的DB2、Oracle，Informix、Sybase等服务器里面的数据。再举一个例子，.NET和基于J2EE的系统能访问流行的信息中间设备，如Microsoft的MSMQ或是IBM的MQSeries。同样，也包括文件系统，第三方开发工具，代码版本系统，防火墙等。<br /><br />不同点<br /><br />1） 原理<br /><br />J2EE是一个单一语言的平台，关注跨平台的可移植性。这就意味着，要利用J2EE，设计方案能使用多个操作系统其中的一个，但开发者必须接受关于Java的培训。Microsoft提供的.NET构架作为Windows系统的一部分。开发者能使用多种语言，并且效率很高而不用进行一种新语言的重新训练。但.NET Framework是Windows系统的一部分。<br /><br />2） 宽度和广度<br /><br />a. .NET包括代码、产品、工具和构架，来利用网络上全部的计算资源，包括设备、个人电脑和服务器等。.NET使所有的这些设备能经过标准通讯协议全部连接在一起，即所谓的“XML WEB服务”。（.NET应用程序可以和任何一个系统连接，无论系统用什么语言和平台，甚至是J2EE。只要目标系统遵照XML WEB服务标准。）.NET模型是广泛的分布式计算，它和许多代码互相通讯并交换信息。<br /><br />b. J2EE是面向服务器的模型，它并不开发网络上的智能和计算功能。总的来说，基于J2EE的产品只支持服务器端的应用程序。J2EE一般把PC只看作是一个HTML的浏览器，而将这些设备认为是哑终端。至于XML WEB服务，现有的协议标准支持分布式的计算，现有版本的J2EE规范并没有提到XML WEB服务的问题，但是基于J2EE的产品在添加了附加装置后也可以支持XML Web服务。然而，添加附加装置也就意味着有严格的限制。例如，还不清楚现有的规范是否允许EJB调用Web服务，虽然Web服务的组件能调用一些EJB程序。<br /><br />3） 编程模型的一致性<br /><br />Windows .NET Framework提供了一个跨服务器、PC和其它设备的一致的、面向组件的模型。而J2EE提供EJB作为服务器端的组件模型；为客户端或是本地组件建立开放的完全用Java编写的API；为用户界面提供servlet；也为移动设备提供另一种不同的模型。甚至在EJB内部也有至少3种明显不同的子模型，每一种子模型都有不同的语言定义。<br /><br /><br /><br />Microsoft的.NET编程模型与Java平台相比较，在各种服务器和客户端上有更好的一致性。J2SE是基于开放的完全用Java编写的API，而J2EE是基于Java servlet和EJB。<br /><br />DH Brown, 2002年7月<br /><br /><br /><br />4） 功能<br /><br />a. Windows .NET Framework提供一个能识别版本的类加载器，这就意味着应用程序的开发者能确保他们开发的应用程序在一部分代码已经更新的情况下仍能运行。而Java和J2EE（现有的）没有版本识别的类加载器，这就意味着开发者和管理员不能保证代码被执行时是正确的。或是说，开发者只能靠运气来保证这一点。<br /><br />b. Windows .NET Framework显示了语言层面上的类属性—这就使得编程更加简单。例如，在源代码中只用一个简单的属性就能把.NET组件标志为处理模式。或者说，一个.NET组件和XML的串行化可以在一个属性中被定义。这个机制大大简化了许多编程任务。而Java不显示语言层上的类属性，虽然Sun公司考虑到要修改Java语言来改变现状。这种变化估计在两三年内才能第一次实现。<br /><br />c. .NET还支持分离数据访问，这主要用于在移动设备或是偶尔联网的场合里运行的应用程序。数据能被脱机操作，接着再和起始数据重新同步。而不论是J2EE还是J2SE现阶段都不支持分离数据访问，需要这项功能的J2EE开发者必须自己写“plumbing code”。<br /><br />d. 为建立基于网络的用户界面，Windows .NET Framework提供基于事件的模型，这些模型类似于流行的Visual Basic中的智能客户端模型。ASP .NET模型使得建立、发布和维护一个基于网络的用户界面变得更加容易。与之形成对比的是，J2EE在JSP中不支持这样的模型。有一些第三方的扩展程序部分弥补了这些功能，但是它们的实用性和简便性不能和ASP .NET相比。作为一个推荐的J2EE附加程序，Java Server Faces可能做到这一点。但这个附加程序并没有包括在J2EE的1.4版本以前。而要获得销售商的支持，则又需至少一年的时间。<br /><br />e. J2EE支持一个对象相关的数据映像模型，它被称作EJB Entity Beans。这样是为了允许开发者更容易地从一个相关的数据库建立对象模型。然而，实际上把这个想法编程实现却要面对下列问题：<br /><br />Ⅰ.易用性：当那些熟知的、正规定义的、被广泛支持的结构化查询语言（SQL）和开发者的数据相互作用时，开发者不得不放弃它们，而使用一个被称为EJBQL的弱定义查询语言。和SQL相类似，EJBQL的功能并不强大（例如，在现有的规范中，它没有ORDER BY的语句，这样开发者就没法使用特定数据库的SQL扩展），而它的语义也没有被正规定义。还有，在对象间建立联系和附属关系十分困难，而且在对象间和XML以及后端之间的数据翻译是手动控制的。<br /><br />Ⅱ.性能：基于EJB系统的性能仍是一个未知数。没有提供公开的基准。客户反映，得到的性能远远偏离了Entity Beans，并且转向一个更直接的数据访问策略。这是EJB Entity Beans没有被广泛使用的一个关键因素。<br /><br />在Windows .NET Framework中，数据访问是基于数据集比较的。数据集保存了相关数据的一个子集，它由一个或多个SQL查询语句描述。数据集中的数据可能保存关键的联系，并且开发者能直接对数据进行操作，能将数据转换成XML格式和上次操作的类型，能使用标准的SQL过滤数据等。总而言之，相对于EJB Entity Beans，.NET的数据集模型提供一个更丰富而且简单熟悉的途径。<br /><br />5） 简便性<br /><br />a． 配置：对于J2EE，配置是由部署描述信息获得的XML格式的文件，它们和实际执行的商用逻辑代码有明显区别。这种方法有很多问题。第一，考虑到特定类的元数据，有些代码中的改变和元数据中的改变是相互依赖的。两个独立文件的同步性要求有可能产生错误。第二，考虑到应用程序层的元数据，在J2EE中，没有可以从一个程序继承元数据到另一个程序的途径。与J2EE不同，Windows的.NET构架包括了这个功能，使得可以在源代码中直接向类添加属性，这样就不会产生第一个问题。Windows .NET中的元数据模型允许客户自己添加扩展程序，这样开发者就可以编写和使用自己的属性。为了在Windows的.NET构架中配置外部元数据，这个功能被包括在配置文件的分级系统中，它能从父系统中继承属性，这样每个文件会很小，它只记录改变的设定。这就避免了J2EE模型的第二个问题<br /><br />b． 数据库连接池Windows .NET Framework中，是根据需要自动建立和管理这些池的。而在J2EE模型中，连接池必须被明确配置和管理。<br /><br />c． XML Web服务：在.NET中建立一个XML Web服务就像在类中添加一个属性那样简单。有些基于J2EE的产品也想在Java中模拟这个功能，.NET提供更简单的方法来建立和使用可由双方共同操作的 XML Web服务。<br /><br />d． 部署：在.NET中，要部署一个应用程序，管理员只需要拷贝文件。而在J2EE中，管理员必须将很多编译文件和JAR、WAR以及EAR绑定，然后在一个特定的服务器部署工具中解开并运行它们，接着拷贝结果档案。这个多步部署过程意味着典型的编辑/编译/调试循环被大大延长了。此外，由于动态加载类过程中的一些变化，更新一个简单的类常常需要重新启动基于J2EE的服务器。<br /><br /><br /><br />虽然许多公司选择Java作为企业发展的策略平台，但它们的使用却由于J2EE的复杂性而受到阻碍。Meta Group，8月<br /><br /><br /><br />6） 成本<br /><br />a． 为了部署，运行在Windows .NET Framework之外编写的服务器端的应用程序需要一个Windows Server的许可，这比三个遵从J2EE的商业服务器中的任何一个许可都便宜很多。包括四个网络服务器的系统部署费用的差别可达到数十万美元。例如，Microsoft Windows Server 2003（企业版）的一个四机器系统（每个有四个pc）的许可费用不超过16，000美元（这考虑了零售因素）。而WebSphere Application Server 5.0在同样的系统中每台pc的许可费用达12，000美元，这共要192，000美元。这个比率是12比1。大多数基于J2EE的商业应用程序服务器的价格都和这类似。（这假定了性能相等。然而实际上Middleware公司2002年10月的报告显示，一个建立在Windows .NET Framework上的应用程序的效率是建立在同样流行的基于J2EE的服务器上的程序的2-4倍。所以实际上价格的优势远高于12比1）有很多免费的，基于J2EE的开放源应用服务器，但是它们并没有J2EE-compliant的商标。还有关于文件和产品的问题：需要产品之间的比较来讨论采许可费用。<br /><br />b． 为Windows .NET Framework开发工具的费用也更加低廉。Visual Studio .NET是.NET的整合开发工具，它的许可费用大大低于商业化的J2EE销售商制定的开发工具的费用。并且在业界，Visual Studio .NET作为最佳开发工具赢得了一系列的大奖。评估过Visual Studio .NET和其竞争对手的客户都说，相对于最好的Java工具，Visual Studio .NET开发效率更高（See Giga，2002年6月）。<br /><br />c． 使用Windows .NET Framework的开发和维护费用更低。专家认为许可费用并不是一个项目的最大开支。典型的软件开发和维护占项目总费用的50-80%（Glass，2002；Kemerer，1995；Gartner，2001）。Middleware公司2002年10月的研究表明，在Windows .NET Framework上一个给定的应用程序开发相对于J2EE，只需要1/3的代码。代码越少就意味着维护更加简单。<br /><br />总结<br /><br /><br /><br />显而易见：正确的产品选择决策不可能不评估实际的产品。对比Microsoft Windows Server及Windows .NET Framework和J2EE（Sun公司的规范）是有价值的，但是这样的努力缺少实际产品的评估。然而，还是可以从中得出一些结论：<br /><br />1） J2EE展现了一个以服务器为中心的原则，并将重心放在EJB和解决“相关对象的映像问题”上。J2EE在支持XML和Web服务上已经落后了。Windows .NET Framework的原则则是通过协议标准和XML、充分利用服务器、接口和设备的的大规模分布式计算。<br /><br />2） 相对于编写在Windows .NET Framework上的程序，J2EE应用程序需要更多的代码来执行相同的任务。<br /><br />3） J2EE的管理和部署模型更像是一个主机模型，它关注保护和限制稀有的计算资源，按比率使用。而Windows .NET Framework展现出的原则是计算资源是廉价的，而且将更加廉价，但是部署能力将保持大部分昂贵的资源。<br /><br />总之，如果一个项目要求必须从几个操作系统中选择一个作为部署平台，而不考虑开发成本；强制（并且重新培训训练）开发者使用单一的编程语言来执行这个项目，从而代码的版本问题就不再重要；重要的是配给和限制相对便宜的计算资源；这样使用昂贵复杂的开发和维护工具就显得顺理成章；而编写更多的代码也有其优越性-- J2EE也许是一个不错的选择。<br /><br />然而，如果商业目标显示最优化的开发效率是重要的；低廉的性价比更符合要求；通过通讯协议的标准获得的可相互操作性有较高价值；大量支持基于界面的应用程序和移动的应用程序是重要的；更感兴趣的是易扩展性—这样的话，建立一个Windows .NET Framework上的Windows Server应用程序是正确的选择。<img src ="http://www.blogjava.net/aawanghuan/aggbug/83843.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/aawanghuan/" target="_blank">萝卜青菜</a> 2006-11-27 17:47 <a href="http://www.blogjava.net/aawanghuan/articles/83843.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>J2EE 与.Net 的比较</title><link>http://www.blogjava.net/aawanghuan/articles/83841.html</link><dc:creator>萝卜青菜</dc:creator><author>萝卜青菜</author><pubDate>Mon, 27 Nov 2006 09:32:00 GMT</pubDate><guid>http://www.blogjava.net/aawanghuan/articles/83841.html</guid><wfw:comment>http://www.blogjava.net/aawanghuan/comments/83841.html</wfw:comment><comments>http://www.blogjava.net/aawanghuan/articles/83841.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/aawanghuan/comments/commentRss/83841.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/aawanghuan/services/trackbacks/83841.html</trackback:ping><description><![CDATA[<p>（1）多系统整合和系统延展性   <br />  跨平台的特性一直是J2EE   的最大特点，它通过Java   的虚拟机技术屏蔽了底层操作系统的细节。从而实现了所编写的代码可以在Windows   平台上使用，也能够在Unix   平台上使用。即所谓“一次编写，处处可用”。在J2EE   规范里面又通过JDBC、JNDI   等技术屏蔽了诸如数据库、目录访问等网络细节。可以这么说，目前用J2EE   技术实现的企业级应用可以运行在大机、Unix、windows、linux等各种操作系统上，后台可以连接Oracle、DB2、Informix   等等数据库，并且效率方面没有太多的区别。在各系统连接方面，J2EE   也提出了很多很好的解决方案，例如J2CA——J2EE   联接器体系结构，就是J2EE   规范规定的如何使用Java。   <br />  技术与所谓遗留系统如ERP、CRM   等的连接方法。当然J2EE   现在也提倡使用Web   Service   等技术来进行系统互联。总体而言，J2EE   技术是一套标准，它由诸多公司一起支持，所以技术的通用性和标准性比较高，目前基本上成为企业级解决方案的事实标准。   <br />  .Net   从本质上来讲不是一套标准，而是微软一系列产品的集合，所以，选择.Net   技术，基本上就选定了微软平台。也就是说，操作系统只能使用Windows，甚至低层硬件只能选择Intel   的系列芯片。而不能在大机、Unix   以及Linux   等系统上使用。在数据库方面，.Net   在自身的Microsoft   SQL   Server   上也会比其他数据库运行得好。在系统互联方面，.Net   提倡使用Web   Service，这个技术目前还比较新，还没有太多的成熟可靠的解决方案。   <br />  总之，在多系统整合和系统延展性方面，基本上是J2EE   的特点，目前而言，.Net   技术还很难望其项背。   <br />  （2）I/O   处理和线程调度   <br />  在这个方面，从应用的层面看，两者都能够达到企业级应用的需求。但是I/O处理和线程调度从本质上来讲应该由底层硬件和操作系统来解决。J2EE   支持众多的硬件和操作系统，单从这点来讲，都比.Net   技术有优势得多。别的不说，大型计算机的I/O   处理能力和线程调度能力是其他任何机种所无法企及的。而大机上目前只能运行J2EE，不能运行.Net。光这一点，就说明了在这个方面J2EE   优于.Net   技术。   <br />  （3）稳定性和安全性   <br />  稳定性和安全性方面可以用很多方式去实现和补偿，问题的关键是看投入的成本和维护的费用是多少，昂贵的资金投入显然是不合适的。所以，我们去讨论那些软硬件的补偿方法没有太多的意义，我们把讨论集中在操作系统和硬件芯片级别的比较。   <br />  .Net   技术进军高端应用市场，靠的是Windows   Data   Center   之类的操作系统，靠的是Intel   的安腾芯片。Windows   操作系统的稳定性和安全性与Unix   乃至S/390等操作系统相比较，其结果不言而喻。Windows   是最通用的桌面系统，也是最大的病毒温床。众多的病毒困扰着Windows   的使用者。目前，利用Microsoft     SQL   Server   的漏洞的病毒正在肆虐就是一个明证。而Unix、Linux   和大型机操作系统的病毒就较少，安全级别也比Windows   高。   <br />  再来看看.Net   所能够运行的硬件平台，一般而言只有Intel   公司的芯片，Intel公司的志强芯片一般我们认为它只是个部门级别服务器的芯片。Intel   公司仰仗进入高端服务器市场的是Intel   公司与HP   公司共同研发的64   位芯片安腾。安腾系列目前最新的是安腾2。尽管在其发布会上英特尔展示了安腾2   处理器与Sun   公司UltraSPARCⅢ的性能对比资料，但英特尔并没有展示更多的基于系统的安全性、稳定性及兼容性能的对比评测，而这些是高端应用的关键所在，而安腾2与现有应用软件的兼容则更是不甚明了的二进制兼容。因此，我们可以说安腾2要在高端市场占领一定的地位还需要一些时日和改进。   <br />  所以，.Net   技术在高端的企业级应用市场还比较缺乏案例支持。   <br />  （4）产品成熟度等其他因素   <br />  J2EE   在1999   年形成了其成熟的架构，并且到今天已经有相当成熟的经过检验的企业应用系统。而.Net   究其渊源是源自微软以前开发企业应用程序的平台DNA   （   Distributed   NetworkArchitecture），其中包括了许多已经被证实的技术，并且这些技术已经在产品中得到实现，包括微软的事务服务器、COM+、消息队列、SQL   Server   数据库等。而对于扩展性，广为业界接受的事实是.NET   平台的扩展思想是基于软件的横向扩展，而J2EE   平台的扩展思想则是基于硬件的纵向扩展。这也符合微软和Sun各自的产品利益。但是我们还需要细看这个问题，.Net   技术源于DNA   技术。众所周知，DNA技术可能能够解决部门级应用的问题，但是在大型企业应用中就不是那么适合了。其实，从微软这家公司的历史背景就可以看出这个问题，微软从来不是一个老牌的企业级解决方案的提供者，它是从DOS、Windows   等桌面操作系统起家的，在购买了一个企业级操作系统开发出Windows   NT   后才开始进入企业级解决方案市场。与IBM、HP、Sun   等一直从事企业级应用的提供商相比，其技术和支持力量还显得稚嫩。尚没有大多的成功案例和解决方案。而J2EE   却是这些企业级解决方案的提供商所力推的，所以J2EE   在企业中有大量的成功案例和解决方案。这些可以从世界各种大企业的IT   应用系统的实际情况可以看出。世界上大多数企业的IT   系统中，使用J2EE   技术的远远大于.   Net。可以这么说，.Net技术尚没有太多比较成功的实施案例。   <br /></p><img src ="http://www.blogjava.net/aawanghuan/aggbug/83841.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/aawanghuan/" target="_blank">萝卜青菜</a> 2006-11-27 17:32 <a href="http://www.blogjava.net/aawanghuan/articles/83841.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Ruby on Rails 和 J2EE：两者能否共存？</title><link>http://www.blogjava.net/aawanghuan/articles/83835.html</link><dc:creator>萝卜青菜</dc:creator><author>萝卜青菜</author><pubDate>Mon, 27 Nov 2006 09:10:00 GMT</pubDate><guid>http://www.blogjava.net/aawanghuan/articles/83835.html</guid><wfw:comment>http://www.blogjava.net/aawanghuan/comments/83835.html</wfw:comment><comments>http://www.blogjava.net/aawanghuan/articles/83835.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/aawanghuan/comments/commentRss/83835.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/aawanghuan/services/trackbacks/83835.html</trackback:ping><description><![CDATA[<blockquote>
				<font size="2">Ruby on Rails 是一个相对较新的 Web 应用程序框架，构建在 Ruby 语言之上。它被宣传为现有企业框架的一个替代，而它的目标，简而言之，就是让生活，至少是 Web 开发方面的生活，变得更轻松。在本文中，Aaron Rustad 将对 Rails 和传统的 J2EE 框架在架构上的一些关键特性进行比较。</font>
		</blockquote>
		<!--START RESERVED FOR FUTURE USE INCLUDE FILES-->
		<!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters -->
		<!--END RESERVED FOR FUTURE USE INCLUDE FILES-->
		<p>
				<font size="2">Ruby on Rails 是一个 Web 应用程序框架，它的目标是为应用程序开发提供一条易行道。实际上，框架的支持者们声称 Ruby on Rails 开发人员的生产率最多是使用传统 J2EE 框架的 10 倍。（请阅读“Rolling with Ruby on Rails”一文，以获得关于这一声明的更多内容；请参阅 </font>
				<a href="http://www-128.ibm.com/developerworks/cn/java/wa-rubyonrails/#resources">
						<font color="#996699" size="2">参考资料</font>
				</a>
				<font size="2">）。虽然这句话造成了 Rails 和 J2EE 社区相当大的争议，但争论中却很少谈及如何比较 Rails 和 J2EE 架构。本文将使用企业应用程序中常见的开源工具，对 Rails 框架和典型的 J2EE 实现进行比较。</font>
		</p>
		<p>
				<a name="1">
						<span class="atitle">
								<font size="2">什么是 Ruby on Rails？</font>
						</span>
				</a>
		</p>
		<p>
				<font size="2">要想找到用一句话描述 Rails 的简单说明，只需查看项目的 </font>
				<a href="http://www.rubyonrails.org/" target="_new">
						<font color="#5c81a7" size="2">主页</font>
				</a>
				<font size="2"> 即可：</font>
		</p>
		<blockquote>
				<font size="2">Rails 是一个用 Ruby 编写的全栈的（full-stack）、开源的 Web 框架，可以使用它来轻松编写实际的应用程序，所需的代码也要比大多数框架花在处理 XML 上的代码少。 </font>
		</blockquote>
		<p>
				<font size="2">虽然我不能保证框架确实会提供它所承诺的轻松快乐，但是上面这句话确实很好地总结了 Rails 的品质。全栈包括：Web 服务器、处理 HTTP 请求和响应的框架，以及方便地把数据持久存储到关系数据库的框架。Rails 通过消除复杂的 XML 配置文件，使用 Ruby 语言的动态性质，帮助把静态类型语言中常见的许多重复代码减少到最少，努力使开发工作变得更容易。</font>
		</p>
		<p>
				<a name="1.1">
						<span class="smalltitle">
								<strong>
										<font face="Arial" size="2">Rails 和典型的 J2EE Web 堆栈</font>
								</strong>
						</span>
				</a>
		</p>
		<p>
				<font size="2">图 1 比较了 Rails 堆栈和典型的 J2EE Web 堆栈（包括 Tomcat servlet 容器、Struts Web 应用程序框架和 Hibernate 持久性框架）。</font>
		</p>
		<br />
		<br />
		<a name="figure1">
				<b>
						<font size="2">图 1. Rails 和 J2EE 堆栈的比较 </font>
				</b>
		</a>
		<br />
		<font size="2">
				<img style="WIDTH: 463px; HEIGHT: 232px" height="248" alt="Rails 和 J2EE 堆栈的比较" src="http://www-128.ibm.com/developerworks/cn/java/wa-rubyonrails/stack.jpg" width="599" />  <br /></font>
		<p>
				<font size="2">可以看到，Rails 堆栈和构成普通的基于 J2EE 的 Web 应用程序的组件之间的基本区别很小。两者都有用来执行应用程序代码的容器；都有帮助分离应用程序的模型、视图和控件的 MVC 框架；以及持久存储数据的机制。</font>
		</p>
		<table cellspacing="0" cellpadding="0" width="45%" align="right" border="0">
				<tbody>
						<tr>
								<td width="10">
										<font size="2">
												<img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="10" />
										</font>
								</td>
								<td>
										<table cellspacing="0" cellpadding="5" width="100%" border="1">
												<tbody>
														<tr>
																<td bgcolor="#eeeeee">
																		<a name="sidebar1">
																				<b>
																						<font size="2">MVC 框架</font>
																				</b>
																		</a>
																		<br />
																		<p>
																				<font size="2">模型-视图-控制器（MVC）是应用时间相当长、应用面相当广的一个设计模式。它源自 Smalltalk；如今，几乎所有的 GUI 框架，包括 Web 和胖客户端，都以该框架为基础。MVC 有三个部分：<i>模型</i>，负责业务逻辑，包括应用程序状态和将在这个状态上执行的动作；<i>视图</i>，用来渲染和向用户呈现模型（在 Web 应用程序中，视图一般渲染为 HTML）；<i>控制器</i>，定义应用程序的行为。有关 MVC 模式的详细解释，请参阅 </font>
																				<a href="http://www-128.ibm.com/developerworks/cn/java/wa-rubyonrails/#resources">
																						<font color="#996699" size="2">参考资料</font>
																				</a>
																				<font size="2">。</font>
																		</p>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<p>
				<a name="1.2">
						<span class="smalltitle">
								<strong>
										<font face="Arial" size="2">前端控制器</font>
								</strong>
						</span>
				</a>
		</p>
		<p>
				<font size="2">Struts 的 <code><font face="新宋体">ActionServlet</font></code> 和 Rails 的 <code><font face="新宋体">DispatchServlet</font></code> 都是前端控制器模式的例子；所以，它们提供了相同的功能。它们接受 HTTP 请求，解析 URL，把请求的处理转发给适当的动作。在 Struts 中，动作是扩展自 <code><font face="新宋体">Action</font></code> 的类；对于 Rails，动作是扩展自 <code><font face="新宋体">ActionController</font></code> 的类。两个前端控制器之间的主要区别是它们如何决定处理具体请求的动作。</font>
		</p>
		<p>
				<font size="2">使用 Struts，开发人员需要把特定请求的映射外部化到 XML 配置文件中的 <code><font face="新宋体">Action</font></code> 类。当首次装入 <code><font face="新宋体">ActionServlet</font></code> 时，它将解析这个文件，并准备接受请求。根据约定，以 <code><font face="新宋体">.do</font></code> 结束的请求被重定向到 <code><font face="新宋体">ActionServlet</font></code>，由 ActionServlet 分派到适当的 <code><font face="新宋体">Action</font></code>。</font>
				<a href="http://www-128.ibm.com/developerworks/cn/java/wa-rubyonrails/#figure2">
						<font color="#996699" size="2">图 2</font>
				</a>
				<font size="2"> 的 XML 是一个典型的映射。它告诉 <code><font face="新宋体">ActionServlet</font></code> 把叫作 <code><font face="新宋体">deleteOrder.do</font></code> 的请求转发到 <code><font face="新宋体">controllers.order.DeleteOrderAction</font></code> 作进一步处理。</font>
		</p>
		<p>
				<font size="2">Rails 采用了不同的方式。它没有依赖配置文件把请求映射到某一个动作，而是根据请求的 URL 发现适当的动作。从图 2 可以看到，URL <code><font face="新宋体">http://localhost/order/delete/4</font></code> 告诉 Rails 调用 <code><font face="新宋体">OrderController</font></code> 实例上的 <code><font face="新宋体">delete</font></code> 方法，并将 <code><font face="新宋体">4</font></code> 作为可用的实例变量。Rails 足够聪明，知道 <code><font face="新宋体">/order</font></code> 将映射到文件 order_controller.rb 中定义的一个控制器类。如果在控制器中定义了 <code><font face="新宋体">find</font></code> 方法，那么只要用 <code><font face="新宋体">find</font></code> 替代 URL 中的 <code><font face="新宋体">delete</font></code>，就可以调用这个方法。</font>
		</p>
		<br />
		<br />
		<a name="figure2">
				<b>
						<font size="2">图 2. Rails 和 Struts 中的 URL 映射 </font>
				</b>
		</a>
		<br />
		<font size="2">
				<img style="WIDTH: 616px; HEIGHT: 253px" height="211" alt="Rails 和 Struts 中的 URL 映射" src="http://www-128.ibm.com/developerworks/cn/java/wa-rubyonrails/mappings.jpg" width="600" />  <br /></font>
		<p>
				<a name="1.3">
						<span class="smalltitle">
								<strong>
										<font face="Arial" size="2">动作和模型</font>
								</strong>
						</span>
				</a>
		</p>
		<p>
				<font size="2">在 Rails 和 Struts 中，动作用来充当前端控制器和模型之间的桥梁。开发人员提供动作的现实，从而提供特定于应用程序的请求处理。前端控制器负责接受请求，并把请求传递到特定动作。图 3 演示了 Rails 和 Struts 基本的动作层次结构。</font>
		</p>
		<br />
		<br />
		<a name="figure3">
				<b>
						<font size="2">图 3. Rails 和 Struts 的动作层次结构</font>
				</b>
		</a>
		<br />
		<font size="2"> <img style="WIDTH: 621px; HEIGHT: 231px" height="200" alt="Rails 和 Struts 的动作层次结构" src="http://www-128.ibm.com/developerworks/cn/java/wa-rubyonrails/actions.jpg" width="600" /><br /></font>
		<table cellspacing="0" cellpadding="0" width="45%" align="right" border="0">
				<tbody>
						<tr>
								<td width="10">
										<font size="2">
												<img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="10" />
										</font>
								</td>
								<td>
										<table cellspacing="0" cellpadding="5" width="100%" border="1">
												<tbody>
														<tr>
																<td bgcolor="#eeeeee">
																		<a name="sidebar2">
																				<b>
																						<font size="2">动作是模型还是控制器？</font>
																				</b>
																		</a>
																		<br />
																		<p>
																				<font size="2">
																						<code>
																								<font face="新宋体">Action</font>
																						</code> 和 <code><font face="新宋体">ActionController</font></code> 从技术上讲是 MVC 模式的控制器的一部分，因为它们对客户发起的事件进行响应。但是，在小型应用程序中，开发人员通常在这些类中对域或业务逻辑进行编码，所以在这些情况下，也可以把它们看作是模型的一部分。最佳实践建议：应当把域逻辑从控制器中抽象出来，放置在它自己的特定于域的类中。</font>
																		</p>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<p>
				<font size="2">Struts 要求开发人员扩展 <code><font face="新宋体">Action</font></code> 并覆盖 <code><font face="新宋体">execute()</font></code>，以处理请求。通常，每个 <code><font face="新宋体">Action</font></code> 类都提供了非常具体的工作单元。</font>
				<a href="http://www-128.ibm.com/developerworks/cn/java/wa-rubyonrails/#figure3">
						<font color="#996699" size="2">图 3</font>
				</a>
				<font size="2"> 演示了三个特定动作：<code><font face="新宋体">SaveOrderAction</font></code>、<code><font face="新宋体">DeleteOrderAction</font></code> 和 <code><font face="新宋体">ListOrdersAction</font></code>。前端控制器将调用 <code><font face="新宋体">execute()</font></code> 方法，传递给它许多有用的对象，其中包括 HTTP 请求和响应对象。<code><font face="新宋体">ActionForm</font></code> 是一个类，它可以方便地向视图来回传输并验证与表单有关的输入，<code><font face="新宋体">ActionMapping</font></code> 包含映射的配置信息，就像 </font>
				<a href="http://www-128.ibm.com/developerworks/cn/java/wa-rubyonrails/#figure2">
						<font color="#996699" size="2">图 2</font>
				</a>
				<font size="2"> 的 XML 所描述的那样。</font>
		</p>
		<p>
				<font size="2">
						<code>
								<font face="新宋体">execute()</font>
						</code> 方法返回 <code><font face="新宋体">ActionForward</font></code> 对象，Struts 用这个对象来确定对请求继续进行处理的组件。一般来说，这个组件是一个 JSP 页面，但是 <code><font face="新宋体">ActionForward</font></code> 也能指向其他动作。开发人员必须清楚，Struts 创建的是 <code><font face="新宋体">Action</font></code> 的单一实例，并允许多个线程调用它的 <code><font face="新宋体">execute()</font></code>。这使请求处理变得更快，因为框架处理每个请求时不用频繁地创建新的 <code><font face="新宋体">Action</font></code> 实例。但是因为可以在多个线程之间共享单一对象，所以必须遵守适当的线程注意事项，因为其他线程可能会破坏在这个动作中保持状态的实例变量。</font>
		</p>
		<p>
				<font size="2">在 Rails 中，必须扩展 <code><font face="新宋体">ActionController::Base</font></code>，让模型参与到请求处理中。Rails 没有将 <code><font face="新宋体">ActionController</font></code> 的实例池化；相反，它为每个请求创建新的实例。虽然这对性能可能有负面影响，但是它可以让开发变得更容易。开发人员不需要关注 Struts 中存在的线程问题，因此，会话、请求、标题和参数都可以作为 <code><font face="新宋体">ActionController</font></code> 的实例成员来进行访问。<code><font face="新宋体">ActionController</font></code> 还是一个将特定域逻辑的所有处理组合在一起的合理场所。Struts 的 <code><font face="新宋体">Action</font></code> 类是细粒度的，它提供了非常具体的工作单元，而 Rails <code><font face="新宋体">ActionController</font></code> 则是粗粒度的，它将具体的工作单元模拟为一些方法。</font>
		</p>
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/java/wa-rubyonrails/listing1.html" target="_new">
						<font color="#5c81a7" size="2">清单 1</font>
				</a>
				<font size="2"> 和 </font>
				<a href="http://www-128.ibm.com/developerworks/cn/java/wa-rubyonrails/listing2.html" target="_new">
						<font color="#5c81a7" size="2">清单 2</font>
				</a>
				<font size="2"> 分别演示了典型的 Struts 动作和典型的 Rails 动作</font>
		</p>
		<p>
				<font size="2">表 1 提供了对两种方法的逻辑流程的比较，并演示了清单 </font>
				<a href="http://www-128.ibm.com/developerworks/cn/java/wa-rubyonrails/listing1.html" target="_new">
						<font color="#5c81a7" size="2">1</font>
				</a>
				<font size="2"> 和清单 </font>
				<a href="http://www-128.ibm.com/developerworks/cn/java/wa-rubyonrails/listing2.html" target="_new">
						<font color="#5c81a7" size="2">2</font>
				</a>
				<font size="2"> 的特定行中发生的事情。研究 <code><font face="新宋体">DeleteOrderAction</font></code> 的 <code><font face="新宋体">execute()</font></code> 方法和 <code><font face="新宋体">OrderController</font></code> 的 <code><font face="新宋体">delete</font></code> 方法，可以看出它们基本上是相同的。</font>
		</p>
		<br />
		<br />
		<a name="table1">
				<b>
						<font size="2">表 1. execute() 和 delete 方法比较</font>
				</b>
		</a>
		<br />
		<table cellspacing="1" cellpadding="3" width="80%" border="1">
				<tbody>
						<tr valign="top" align="middle">
								<td>
										<b>
												<font size="2">步骤</font>
										</b>
								</td>
								<td>
										<b>
												<font size="2">Struts</font>
										</b>
								</td>
								<td>
										<b>
												<font size="2">Rails</font>
										</b>
								</td>
						</tr>
						<tr>
								<td>
										<font size="2">框架调用动作</font>
								</td>
								<td>
										<font size="2">
												<b>行 03：</b>
												<code>
														<font face="新宋体">execute()</font>
												</code>
										</font>
								</td>
								<td>
										<font size="2">
												<b>行 07：</b>
												<code>
														<font face="新宋体">delete</font>
												</code>
										</font>
								</td>
						</tr>
						<tr>
								<td>
										<font size="2">从请求中检索到的 ID </font>
								</td>
								<td>
										<font size="2">
												<b>行 06-07：</b>从请求对象中取出</font>
								</td>
								<td>
										<font size="2">
												<b>行 08：</b>从所有参数的实例哈希中取出</font>
								</td>
						</tr>
						<tr>
								<td>
										<font size="2">从数据库删除订单记录</font>
								</td>
								<td>
										<font size="2">
												<b>行 09、14-24：</b>调用 <code><font face="新宋体">delete()</font></code> 方法，用 Hibernate 删除记录</font>
								</td>
								<td>
										<font size="2">
												<b>行 09：</b>用 ActiveRecord 删除记录</font>
								</td>
						</tr>
						<tr>
								<td>
										<font size="2">重定向到列出剩余订单</font>
								</td>
								<td>
										<font size="2">
												<b>行 11：</b>用 <code><font face="新宋体">ActionMapping</font></code> 对象查找将要转发处理的下一个组件。</font>
										<a href="http://www-128.ibm.com/developerworks/cn/java/wa-rubyonrails/#figure2">
												<font color="#996699" size="2">图 2</font>
										</a>
										<font size="2"> 中的 XML 映射显示，<code><font face="新宋体">success</font></code> 将映射到 <code><font face="新宋体">/listOrders</font></code>，这是另一个 <code><font face="新宋体">Action</font></code>，负责查找剩余订单，并以 JSP 的形式呈现它们</font>
								</td>
								<td>
										<font size="2">
												<b>行 10：</b>用将调用的下一动作的哈希来调用 <code><font face="新宋体">redirect_to</font></code> 方法；在这种情况下，它只是调用同一控制器的 <code><font face="新宋体">list</font></code> 方法</font>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<font size="2">
												<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
												<br />
												<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
										</font>
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<font size="2">
												<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
												<br />
										</font>
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<font size="2">
																				<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																				<br />
																		</font>
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www-128.ibm.com/developerworks/cn/java/wa-rubyonrails/#main">
																				<b>
																						<font color="#996699" size="2">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="2">
						<span class="atitle">
								<font size="2">持久性框架</font>
						</span>
				</a>
		</p>
		<p>
				<font size="2">
						<i>持久性框架</i> 用来在应用程序层和数据库之间来回移动数据。Hibernate 和 Rails 的持久性框架可以归类为对象/关系映射（ORM）工具，这意味着它们接受数据的对象视图，并将该视图映射到关系数据库内的表中。使用两种框架的目的都是为了减少与关系数据库有关的开发时间。但是，</font>
				<a href="http://www-128.ibm.com/developerworks/cn/java/wa-rubyonrails/#figure4">
						<font color="#996699" size="2">图 4</font>
				</a>
				<font size="2"> 演示了两者在设计和配置上的一些根本区别。 </font>
		</p>
		<br />
		<br />
		<a name="figure4">
				<b>
						<font size="2">图 4. Active Record 和 Hibernate 持久性框架的比较 </font>
				</b>
		</a>
		<br />
		<font size="2">
				<img style="WIDTH: 647px; HEIGHT: 248px" height="206" alt=" Active Record 和 Hibernate 持久性框架的比较" src="http://www-128.ibm.com/developerworks/cn/java/wa-rubyonrails/persistence.jpg" width="600" />  <br /></font>
		<p>
				<a name="2.1">
						<span class="smalltitle">
								<strong>
										<font face="Arial" size="2">Hibernate</font>
								</strong>
						</span>
				</a>
		</p>
		<p>
				<font size="2">Hibernate 基于 Data Mapper 模式，在这种模式中，特定的映射器类 <code><font face="新宋体">Session</font></code> 负责在数据库中持久存储和检索数据。Hibernate 可以持久存储任何 Java 对象，只要这个对象符合 JavaBean 规范。XML 映射文件描述了如何将类映射到数据库中具体的表，并描述了类与其他类的关系。</font>
		</p>
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/java/wa-rubyonrails/#listing3">
						<font color="#996699" size="2">清单 3</font>
				</a>
				<font size="2"> 显示了 Hibernate 映射文件的一个实例。<code><font face="新宋体">class</font></code> 标签把 <code><font face="新宋体">Order</font></code> 对象映射到 <code><font face="新宋体">ORDERS</font></code> 表，还有许多子标签用于描述其属性、ID 订单名称，以及同 <code><font face="新宋体">models.Item</font></code> 的一对多关系。</font>
				<a href="http://www-128.ibm.com/developerworks/cn/java/wa-rubyonrails/#listing4">
						<font color="#996699" size="2">清单 4</font>
				</a>
				<font size="2"> 显示了 <code><font face="新宋体">Order</font></code> 类本身。</font>
		</p>
		<br />
		<br />
		<a name="listing3">
				<b>
						<font size="2">清单 3. Order.hbm.xml</font>
				</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">
												<font size="2">...
01 &lt;hibernate-mapping&gt;
02    &lt;class name="models.Order" table="ORDERS"
03        dynamic-update="true" dynamic-insert="false"
04        discriminator-value="null"&gt;
05
06 	&lt;id name="id" column="id" type="java.lang.Long" 
07             unsaved-value="null"&gt;
08             &lt;generator class="identity"/&gt;
09         &lt;/id&gt;
10 
11         &lt;set name="items" lazy="false" inverse="false"
12            cascade="none" sort="unsorted"&gt;
13             &lt;key column="id"/&gt;
14             &lt;one-to-many class="models.Item"/&gt;
15         &lt;/set&gt;
16 
17         &lt;property name="name" type="java.lang.String"
18             update="true" insert="true"
19             access="property" column="name"/&gt;
20     &lt;/class&gt;
21 &lt;/hibernate-mapping&gt;
</font>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<br />
		<a name="listing4">
				<b>
						<font size="2">清单 4. Order.java</font>
				</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">
												<font size="2">01 public class Order {
02    private Set items;
03     private String name;
04     private Long id;
05 
06     public Long getId() { return id;}
07 
08     public void setId(Long id) { this.id = id;}
09 	
10     public Set getItems() { return items;}
11 	
12     public void setItems(Set items) { this.items = items; }
13 	
14     public String getName() { return name; }
15 
16     public void setName(String name) { this.name = name; }
17 }
</font>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>
				<a name="2.2">
						<span class="smalltitle">
								<strong>
										<font face="Arial" size="2">Active Record</font>
								</strong>
						</span>
				</a>
		</p>
		<table cellspacing="0" cellpadding="0" width="45%" align="right" border="0">
				<tbody>
						<tr>
								<td width="10">
										<strong>
												<font face="Arial" size="2">
														<img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="10" />
												</font>
										</strong>
								</td>
								<td>
										<table cellspacing="0" cellpadding="5" width="100%" border="1">
												<tbody>
														<tr>
																<td bgcolor="#eeeeee">
																		<a name="sidebar3">
																				<strong>
																						<font size="2">反射和元编程</font>
																				</strong>
																		</a>
																		<br />
																		<p>
																				<font size="2">Wikipedia 中（请参阅 </font>
																				<a href="http://www-128.ibm.com/developerworks/cn/java/wa-rubyonrails/#resources">
																						<font color="#996699" size="2">参考资料</font>
																				</a>
																				<font size="2">）简要地把 <i>反射</i> 定义为“程序在运行的时候检查和修改其高级结构的能力”。在那里，还将 <i>元编程</i> 定义为“编写那些能够编写和操作其他其他程序（或它们自己），将其他程序作为自己的数据的程序，或者编写那些完成其他程序在运行时所做的部分工作的程序。”</font>
																		</p>
																		<p>
																				<font size="2">以下代码将实现反射：</font>
																		</p>
																		<table cellspacing="0" cellpadding="0" width="100%" border="0">
																				<tbody>
																						<tr>
																								<td class="code-outline">
																										<pre class="displaycode">
																												<font size="2">01 obj = "some_string"
02 if obj.respond_to?('length'):
03   puts "obj length = #{obj.length}" 
03 end
&gt;&gt; obj length = 5
</font>
																										</pre>
																								</td>
																						</tr>
																				</tbody>
																		</table>
																		<br />
																		<p>
																				<font size="2">这个代码将实现元编程：</font>
																		</p>
																		<table cellspacing="0" cellpadding="0" width="100%" border="0">
																				<tbody>
																						<tr>
																								<td class="code-outline">
																										<pre class="displaycode">
																												<font size="2">01 class SomeClass
02 end
03 newMethod = %q{def msg() puts "A message!" end}
04 SomeClass.class_eval(newMethod)
05 aClass = SomeClass.new
06 aClass.msg
&gt;&gt; A message!
</font>
																										</pre>
																								</td>
																						</tr>
																				</tbody>
																		</table>
																		<br />
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<p>
				<font size="2">Rails 的 ORM 框架叫作 <i>Active Record</i>，它基于同名的设计模式。Martin Fowler 将 Active Record 描述为“包装数据库表或视图中数据行的对象，封装数据库访问，在数据上添加域逻辑”。在 Rails 中，每个域对象都将扩展提供 CRUD 操作的 <code><font face="新宋体">ActiveRecord::Base</font></code>。</font>
		</p>
		<p>
				<font size="2">与 Hibernate 一样，Active Record 不需要映射文件；实际上，使用 Active Record 的开发人员不需要对 getter 或 setter、甚至类的属性进行编码。通过一些漂亮的词汇分析，Active Record 能够判断出，<code><font face="新宋体">Order</font></code> 类将映射到数据库中的 <code><font face="新宋体">ORDERS</font></code> 表。使用 Ruby 反射和元编程的组合，表的列可以变成对象的属性。访问器和调整器也添加了进来。</font>
		</p>
		<p>
				<a href="http://www-128.ibm.com/developerworks/cn/java/wa-rubyonrails/#listing5">
						<font color="#996699" size="2">清单 5</font>
				</a>
				<font size="2"> 显示了 <code><font face="新宋体">Order</font></code> 类的完成后的代码。在 <code><font face="新宋体">Order</font></code> 类体中有一行代码定义了它与 <code><font face="新宋体">Item</font></code> 对象的关系。<code><font face="新宋体">has_many</font></code> 是一个静态方法调用，符号 <code><font face="新宋体">:items</font></code> 是它的参数。ActiveRecord 用 <code><font face="新宋体">:items</font></code> 发现 <code><font face="新宋体">Item</font></code> 域对象，然后将这个 <code><font face="新宋体">Item</font></code> 对象映射回数据库中的 <code><font face="新宋体">ITEMS</font></code> 表。</font>
		</p>
		<br />
		<br />
		<a name="listing5">
				<b>
						<font size="2">清单 5. order.rb</font>
				</b>
		</a>
		<br />
		<table cellspacing="0" cellpadding="0" width="40%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">
												<font size="2">01 class Order &lt; ActiveRecord::Base
02	has_many :items
03 end
</font>
										</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>
				<font size="2">像 </font>
				<a href="http://www-128.ibm.com/developerworks/cn/java/wa-rubyonrails/#listing5">
						<font color="#996699" size="2">清单 5</font>
				</a>
				<font size="2"> 那样编码的 <code><font face="新宋体">Order</font></code> 类在运行时提供了一些类和实例方法。表 2 提供了可在 <code><font face="新宋体">Order</font></code> 上使用的操作和属性的部分列表： </font>
		</p>
		<br />
		<br />
		<a name="table2">
				<b>
						<font size="2">表 2. 在 Order 上可用的属性和操作</font>
				</b>
		</a>
		<br />
		<table cellspacing="1" cellpadding="3" width="80%" border="1">
				<tbody>
						<tr valign="top" align="middle">
								<td>
										<b>
												<font size="2">类方法</font>
										</b>
								</td>
								<td>
										<b>
												<font size="2">实例方法</font>
										</b>
								</td>
								<td>
										<b>
												<font size="2">属性</font>
										</b>
								</td>
						</tr>
						<tr valign="top">
								<td>
										<ul>
												<li>
														<font size="2">
																<code>
																		<font face="新宋体">find(*args)</font>
																</code>
														</font>
												</li>
												<li>
														<font size="2">
																<code>
																		<font face="新宋体">find_by_sql(sql)</font>
																</code>
														</font>
												</li>
												<li>
														<font size="2">
																<code>
																		<font face="新宋体">exists?(id)</font>
																</code>
														</font>
												</li>
												<li>
														<font size="2">
																<code>
																		<font face="新宋体">create(attributes)</font>
																</code>
														</font>
												</li>
												<li>
														<font size="2">
																<code>
																		<font face="新宋体">update(id, attributes)</font>
																</code>
														</font>
												</li>
												<li>
														<font size="2">
																<code>
																		<font face="新宋体">update_all(updates, conditions</font>
																</code>
														</font>
												</li>
												<li>
														<font size="2">
																<code>
																		<font face="新宋体">delete(id)</font>
																</code>
														</font>
												</li>
												<li>
														<font size="2">
																<code>
																		<font face="新宋体">delete_all(conditions)</font>
																</code>
														</font>
												</li>
												<li>
														<font size="2">... </font>
												</li>
										</ul>
								</td>
								<td>
										<ul>
												<li>
														<font size="2">
																<code>
																		<font face="新宋体">add_items</font>
																</code>
														</font>
												</li>
												<li>
														<font size="2">
																<code>
																		<font face="新宋体">build_to_items</font>
																</code>
														</font>
												</li>
												<li>
														<font size="2">
																<code>
																		<font face="新宋体">create_in_items</font>
																</code>
														</font>
												</li>
												<li>
														<font size="2">
																<code>
																		<font face="新宋体">find_all_in_items</font>
																</code>
														</font>
												</li>
												<li>
														<font size="2">
																<code>
																		<font face="新宋体">find_in_items</font>
																</code>
														</font>
												</li>
												<li>
														<font size="2">
																<code>
																		<font face="新宋体">has_items?</font>
																</code>
														</font>
												</li>
												<li>
														<font size="2">
																<code>
																		<font face="新宋体">items</font>
																</code>
														</font>
												</li>
												<li>
														<font size="2">
																<code>
																		<font face="新宋体">items=</font>
																</code>
														</font>
												</li>
												<li>
														<font size="2">
																<code>
																		<font face="新宋体">items_count</font>
																</code>
														</font>
												</li>
												<li>
														<font size="2">
																<code>
																		<font face="新宋体">remove_items</font>
																</code>
														</font>
												</li>
										</ul>
								</td>
								<td>
										<ul>
												<li>
														<font size="2">
																<code>
																		<font face="新宋体">id</font>
																</code>
														</font>
												</li>
												<li>
														<font size="2">
																<code>
																		<font face="新宋体">name</font>
																</code>
														</font>
												</li>
										</ul>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<font size="2">
												<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
												<br />
												<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
										</font>
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<font size="2">
												<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
												<br />
										</font>
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<font size="2">
																				<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																				<br />
																		</font>
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www-128.ibm.com/developerworks/cn/java/wa-rubyonrails/#main">
																				<b>
																						<font color="#996699" size="2">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="3">
						<span class="atitle">
								<font size="2">结束语</font>
						</span>
				</a>
		</p>
		<p>
				<font size="2">虽然 Ruby on Rails 是一个非常新、令人兴奋的框架，并且在 Web 社区中已经引起了人们相当的兴趣，但是它的核心架构仍然遵循在 J2EE 中发现的基本模式。开发把两个框架分开的 Web 应用程序是一种合理的方法。Rails 更喜欢清楚的代码而不是配置文件，而 Ruby 语言的动态性质在运行时生成了大部分<i>管道</i> 代码。大多数 Rails 框架都是作为独立项目创建的，而且应用程序开发能够从一组同类组件受益。相比之下，典型的 J2EE 堆栈倾向于构建在通常独立开发的最好的组件之上，常常用 XML 进行配置并将组件组合在一起。</font>
		</p>
		<p>
				<font size="2">那么，是否应该考虑对下一个 Web 应用程序使用 Rails 呢？嗯，为什么不呢？它是编写得很好的组件堆栈，它们彼此之间工作得很好，并且基于行业接受的企业模式。Ruby 语言支持快速开发，并通过生产大多数应用程序管道来添加到框架。熟悉 Java 世界中的 MVC 和 ORM 框架的人们在用 Rails 表达自己的思想时没有任何困难。</font>
		</p>
		<p>
				<font size="2">与 J2EE 一起分发会不会有利于 Rails？绝对不要。J2EE 是一个已经设置好的标准，有许多固定的实现，而且，最重要的是，它是一个经过验证的技术。我建议您下载一份 Rails 的副本，并开始自己钻研它。许多可用的教程都是介绍性的，这些教程可以让您立即开始使用 Rails。再次声明，我并不能保证您会通过使用 Rails 得到快乐，但是我敢打赌您会感到满意。</font>
		</p><img src ="http://www.blogjava.net/aawanghuan/aggbug/83835.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/aawanghuan/" target="_blank">萝卜青菜</a> 2006-11-27 17:10 <a href="http://www.blogjava.net/aawanghuan/articles/83835.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>初学者如何开发出一个高质量的J2EE系统？ </title><link>http://www.blogjava.net/aawanghuan/articles/82829.html</link><dc:creator>萝卜青菜</dc:creator><author>萝卜青菜</author><pubDate>Wed, 22 Nov 2006 09:18:00 GMT</pubDate><guid>http://www.blogjava.net/aawanghuan/articles/82829.html</guid><wfw:comment>http://www.blogjava.net/aawanghuan/comments/82829.html</wfw:comment><comments>http://www.blogjava.net/aawanghuan/articles/82829.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/aawanghuan/comments/commentRss/82829.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/aawanghuan/services/trackbacks/82829.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 初学者如何开发出一个高质量的J2EE系统？																																				发表时间: Jun 21, 2005 12:02 PM 																																																																																											...&nbsp;&nbsp;<a href='http://www.blogjava.net/aawanghuan/articles/82829.html'>阅读全文</a><img src ="http://www.blogjava.net/aawanghuan/aggbug/82829.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/aawanghuan/" target="_blank">萝卜青菜</a> 2006-11-22 17:18 <a href="http://www.blogjava.net/aawanghuan/articles/82829.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>正则表达式语法</title><link>http://www.blogjava.net/aawanghuan/articles/76338.html</link><dc:creator>萝卜青菜</dc:creator><author>萝卜青菜</author><pubDate>Fri, 20 Oct 2006 02:56:00 GMT</pubDate><guid>http://www.blogjava.net/aawanghuan/articles/76338.html</guid><wfw:comment>http://www.blogjava.net/aawanghuan/comments/76338.html</wfw:comment><comments>http://www.blogjava.net/aawanghuan/articles/76338.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/aawanghuan/comments/commentRss/76338.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/aawanghuan/services/trackbacks/76338.html</trackback:ping><description><![CDATA[
		<div id="TitleRow" style="PADDING-RIGHT: 10px; PADDING-LEFT: 22px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px">
				<h1 class="dtH1">
						<a title="jsgrpregexpsyntax" name="jsgrpregexpsyntax">
						</a>正则表达式语法</h1>
		</div>
		<div id="nstext">
				<p>一个正则表达式就是由普通字符（例如字符 a 到 z）以及特殊字符（称为<em>元字符</em>）组成的文字模式。该模式描述在查找文字主体时待匹配的一个或多个字符串。正则表达式作为一个模板，将某个字符模式与所搜索的字符串进行匹配。</p>
				<p>这里有一些可能会遇到的正则表达式示例：</p>
				<div class="tablediv">
						<table class="dtTABLE" cellspacing="0">
								<tbody>
										<tr>
												<th>JScript</th>
												<th>VBScript</th>
												<th>匹配</th>
										</tr>
										<tr>
												<td>/^\[ \t]*$/</td>
												<td>"^\[ \t]*$"</td>
												<td>匹配一个空白行。</td>
										</tr>
										<tr>
												<td>/\d{2}-\d{5}/</td>
												<td>"\d{2}-\d{5}"</td>
												<td>验证一个ID 号码是否由一个2位数字，一个连字符以及一个5位数字组成。</td>
										</tr>
										<tr>
												<td>/&lt;(.*)&gt;.*&lt;\/\1&gt;/</td>
												<td>"&lt;(.*)&gt;.*&lt;\/\1&gt;"</td>
												<td>匹配一个 HTML 标记。</td>
										</tr>
								</tbody>
						</table>
				</div>
				<p>下表是元字符及其在正则表达式上下文中的行为的一个完整列表：</p>
				<div class="tablediv">
						<table class="dtTABLE" cellspacing="0">
								<tbody>
										<tr>
												<th>字符</th>
												<th>描述</th>
										</tr>
										<tr>
												<td>\</td>
												<td>将下一个字符标记为一个特殊字符、或一个原义字符、或一个 向后引用、或一个八进制转义符。例如，'n' 匹配字符 "n"。'\n' 匹配一个换行符。序列 '\\' 匹配 "\" 而 "\(" 则匹配 "("。</td>
										</tr>
										<tr>
												<td>^</td>
												<td>匹配输入字符串的开始位置。如果设置了 <strong>RegExp</strong> 对象的 <strong>Multiline</strong> 属性，^ 也匹配 '\n' 或 '\r' 之后的位置。</td>
										</tr>
										<tr>
												<td>$</td>
												<td>匹配输入字符串的结束位置。如果设置了<strong>RegExp</strong> 对象的 <strong>Multiline</strong> 属性，$ 也匹配 '\n' 或 '\r' 之前的位置。</td>
										</tr>
										<tr>
												<td>*</td>
												<td>匹配前面的子表达式零次或多次。例如，zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。</td>
										</tr>
										<tr>
												<td>+</td>
												<td>匹配前面的子表达式一次或多次。例如，'zo+' 能匹配 "zo" 以及 "zoo"，但不能匹配 "z"。+ 等价于 {1,}。</td>
										</tr>
										<tr>
												<td>?</td>
												<td>匹配前面的子表达式零次或一次。例如，"do(es)?" 可以匹配 "do" 或 "does" 中的"do" 。? 等价于 {0,1}。</td>
										</tr>
										<tr>
												<td>{<em>n</em>}</td>
												<td>
														<em>n</em> 是一个非负整数。匹配确定的 <em>n</em> 次。例如，'o{2}' 不能匹配 "Bob" 中的 'o'，但是能匹配 "food" 中的两个 o。</td>
										</tr>
										<tr>
												<td>{<em>n</em>,}</td>
												<td>
														<em>n</em> 是一个非负整数。至少匹配<em>n</em> 次。例如，'o{2,}' 不能匹配 "Bob" 中的 'o'，但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。</td>
										</tr>
										<tr>
												<td>{<em>n</em>,<em>m</em>}</td>
												<td>
														<em>m</em> 和 <em>n</em> 均为非负整数，其中<em>n</em> &lt;= <em>m</em>。最少匹配 <em>n</em> 次且最多匹配 <em>m</em> 次。例如，"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。</td>
										</tr>
										<tr>
												<td>?</td>
												<td>当该字符紧跟在任何一个其他限制符 (*, +, ?, {<em>n</em>}, {<em>n</em>,}, {<em>n</em>,<em>m</em>}) 后面时，匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串，而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如，对于字符串 "oooo"，'o+?' 将匹配单个 "o"，而 'o+' 将匹配所有 'o'。</td>
										</tr>
										<tr>
												<td>.</td>
												<td>匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符，请使用象 '[.\n]' 的模式。</td>
										</tr>
										<tr>
												<td>(<em>pattern</em>)</td>
												<td>匹配 <em>pattern</em> 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到，在VBScript 中使用 <strong>SubMatches</strong> 集合，在JScript 中则使用 <strong>$0</strong>…<strong>$9</strong> 属性。要匹配圆括号字符，请使用 '\(' 或 '\)'。</td>
										</tr>
										<tr>
												<td>(?:<em>pattern</em>)</td>
												<td>匹配 <em>pattern</em> 但不获取匹配结果，也就是说这是一个非获取匹配，不进行存储供以后使用。这在使用 "或" 字符 (|) 来组合一个模式的各个部分是很有用。例如， 'industr(?:y|ies) 就是一个比 'industry|industries' 更简略的表达式。</td>
										</tr>
										<tr>
												<td>(?=<em>pattern</em>)</td>
												<td>正向预查，在任何匹配 <em>pattern</em> 的字符串开始处匹配查找字符串。这是一个非获取匹配，也就是说，该匹配不需要获取供以后使用。例如，'Windows (?=95|98|NT|2000)' 能匹配 "Windows 2000" 中的 "Windows" ，但不能匹配 "Windows 3.1" 中的 "Windows"。预查不消耗字符，也就是说，在一个匹配发生后，在最后一次匹配之后立即开始下一次匹配的搜索，而不是从包含预查的字符之后开始。</td>
										</tr>
										<tr>
												<td>(?!<em>pattern</em>)</td>
												<td>负向预查，在任何不匹配 <em>pattern</em> 的字符串开始处匹配查找字符串。这是一个非获取匹配，也就是说，该匹配不需要获取供以后使用。例如'Windows (?!95|98|NT|2000)' 能匹配 "Windows 3.1" 中的 "Windows"，但不能匹配 "Windows 2000" 中的 "Windows"。预查不消耗字符，也就是说，在一个匹配发生后，在最后一次匹配之后立即开始下一次匹配的搜索，而不是从包含预查的字符之后开始 </td>
										</tr>
										<tr>
												<td>
														<em>x</em>|<em>y</em></td>
												<td>匹配 <em>x</em> 或 <em>y</em>。例如，'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 则匹配 "zood" 或 "food"。</td>
										</tr>
										<tr>
												<td>[<em>xyz</em>]</td>
												<td>字符集合。匹配所包含的任意一个字符。例如， '[abc]' 可以匹配 "plain" 中的 'a'。</td>
										</tr>
										<tr>
												<td>[^<em>xyz</em>]</td>
												<td>负值字符集合。匹配未包含的任意字符。例如， '[^abc]' 可以匹配 "plain" 中的'p'。</td>
										</tr>
										<tr>
												<td>[<em>a-z</em>]</td>
												<td>字符范围。匹配指定范围内的任意字符。例如，'[a-z]' 可以匹配 'a' 到 'z' 范围内的任意小写字母字符。</td>
										</tr>
										<tr>
												<td>[^<em>a-z</em>]</td>
												<td>负值字符范围。匹配任何不在指定范围内的任意字符。例如，'[^a-z]' 可以匹配任何不在 'a' 到 'z' 范围内的任意字符。</td>
										</tr>
										<tr>
												<td>\b</td>
												<td>匹配一个单词边界，也就是指单词和空格间的位置。例如， 'er\b' 可以匹配"never" 中的 'er'，但不能匹配 "verb" 中的 'er'。</td>
										</tr>
										<tr>
												<td>\B</td>
												<td>匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er'，但不能匹配 "never" 中的 'er'。</td>
										</tr>
										<tr>
												<td>\c<em>x</em></td>
												<td>匹配由 <em>x </em>指明的控制字符。例如， \cM 匹配一个 Control-M 或回车符。<em>x</em> 的值必须为 A-Z 或 a-z 之一。否则，将 c 视为一个原义的 'c' 字符。</td>
										</tr>
										<tr>
												<td>\d</td>
												<td>匹配一个数字字符。等价于 [0-9]。</td>
										</tr>
										<tr>
												<td>\D</td>
												<td>匹配一个非数字字符。等价于 [^0-9]。</td>
										</tr>
										<tr>
												<td>\f</td>
												<td>匹配一个换页符。等价于 \x0c 和 \cL。</td>
										</tr>
										<tr>
												<td>\n</td>
												<td>匹配一个换行符。等价于 \x0a 和 \cJ。</td>
										</tr>
										<tr>
												<td>\r</td>
												<td>匹配一个回车符。等价于 \x0d 和 \cM。</td>
										</tr>
										<tr>
												<td>\s</td>
												<td>匹配任何空白字符，包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。</td>
										</tr>
										<tr>
												<td>\S</td>
												<td>匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。</td>
										</tr>
										<tr>
												<td>\t</td>
												<td>匹配一个制表符。等价于 \x09 和 \cI。</td>
										</tr>
										<tr>
												<td>\v</td>
												<td>匹配一个垂直制表符。等价于 \x0b 和 \cK。</td>
										</tr>
										<tr>
												<td>\w</td>
												<td>匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。</td>
										</tr>
										<tr>
												<td>\W</td>
												<td>匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。</td>
										</tr>
										<tr>
												<td>\x<em>n</em></td>
												<td>匹配 <em>n</em>，其中 <em>n</em> 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如，'\x41' 匹配 "A"。'\x041' 则等价于 '\x04' &amp; "1"。正则表达式中可以使用 ASCII 编码。.</td>
										</tr>
										<tr>
												<td>\<em>num</em></td>
												<td>匹配 <em>num</em>，其中 <em>num</em> 是一个正整数。对所获取的匹配的引用。例如，'(.)\1' 匹配两个连续的相同字符。</td>
										</tr>
										<tr>
												<td>\<em>n</em></td>
												<td>标识一个八进制转义值或一个向后引用。如果 \<em>n</em> 之前至少 <em>n</em> 个获取的子表达式，则 <em>n</em> 为向后引用。否则，如果 <em>n</em> 为八进制数字 (0-7)，则 <em>n</em> 为一个八进制转义值。</td>
										</tr>
										<tr>
												<td>\<em>nm</em></td>
												<td>标识一个八进制转义值或一个向后引用。如果 \<em>nm</em> 之前至少有 <em>nm</em> 个获得子表达式，则 <em>nm</em> 为向后引用。如果 \<em>nm</em> 之前至少有 <em>n</em> 个获取，则 <em>n</em> 为一个后跟文字 <em>m </em>的向后引用。如果前面的条件都不满足，若 <em>n</em> 和 <em>m</em> 均为八进制数字 (0-7)，则 \<em>nm</em> 将匹配八进制转义值 <em>nm</em>。</td>
										</tr>
										<tr>
												<td>\<em>nml</em></td>
												<td>如果 <em>n</em> 为八进制数字 (0-3)，且 <em>m</em> 和 <em>l</em> 均为八进制数字 (0-7)，则匹配八进制转义值 <em>nml。</em></td>
										</tr>
										<tr>
												<td>\u<em>n</em></td>
												<td>匹配 <em>n</em>，其中 <em>n</em> 是一个用四个十六进制数字表示的 Unicode 字符。例如， \u00A9 匹配版权符号 (©)。</td>
										</tr>
								</tbody>
						</table>
				</div>
		</div>
		<div class="postfoot">
				<div class="em"> </div>
		</div>
<img src ="http://www.blogjava.net/aawanghuan/aggbug/76338.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/aawanghuan/" target="_blank">萝卜青菜</a> 2006-10-20 10:56 <a href="http://www.blogjava.net/aawanghuan/articles/76338.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>正则表达式学习日记 </title><link>http://www.blogjava.net/aawanghuan/articles/76339.html</link><dc:creator>萝卜青菜</dc:creator><author>萝卜青菜</author><pubDate>Fri, 20 Oct 2006 02:56:00 GMT</pubDate><guid>http://www.blogjava.net/aawanghuan/articles/76339.html</guid><wfw:comment>http://www.blogjava.net/aawanghuan/comments/76339.html</wfw:comment><comments>http://www.blogjava.net/aawanghuan/articles/76339.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/aawanghuan/comments/commentRss/76339.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/aawanghuan/services/trackbacks/76339.html</trackback:ping><description><![CDATA[
		<div class="post">
				<h5 class="posthead">
						<a id="bp___v___r___postlist___EntryItems_ctl08_PostTitle" href="http://myblog.workgroup.cn/blogs/other/archive/2006/07/07/_636B19526888BE8F0F5F665B604EE565B08B_.aspx">正则表达式学习日记</a>
				</h5>1、“.”为通配符，表示任何一个字符，例如：“a.c”可以匹配“anc”、“abc”、“acc”；<br />2、“[]”，在[]内可以指定要求匹配的字符，例如：“a[nbc]c”可以匹配“anc”、“abc”、“acc”<br /><br />；但不可以匹配“ancc”,a到z可以写成[a-z],0到9可以写成[0-9];<br /><br />3、数量限定符号，表示匹配次数（或者叫做长度）的符号：<br /><br />包括：“*”——0次或者多次<br />“+”——1次或者多次<br />“?”——0次或者1次<br />“{n}”——匹配n次，n为整数<br />“{n,m}”——匹配从n到m之间的某个数的次数；n和m都是整数；<br />“{n,}”——匹配n到无穷次之间任意次数；<br />“{,m}”——匹配0到m之间任意次数；<br />他们放到匹配格式的后面：<br />例如：<br />电话号码：024－84820482，02484820482(假设前面3或者4位，后面7或者8位，并且中间的减号可有可无)<br /><br />都是符合规定的，那么可以用如下格式来匹配：[0-9]{3,4} \-? [0-9]{7,8}；<br />注意：“\”为转义字符，因为“-”在正则表达式用有代表一个范围的意义，例如：前面所说的[0-9]，<br /><br />所以它需要转义字符“\”进行转义才可使用；<br />4、“^”为否符号，表示不想匹配的符号，例如：[^z][a-z]+可以匹配所有除“z”开头的以外的所有字<br /><br />符串（长度大于2，因为“+”表示大于等于1的次数，从第二位开始都是小写英文字符）；<br />如果^放到[]的外边则表示以[]开头的字符串；^[az][a-z]+表示a或者z开头的长度大于等于2的英文字符<br /><br />串；<br />5、“|”或运算符，例如：a[n|bc|cb]c可以匹配“abcc”,“anc”,“acbc”；<br />6、“$”以它前面的字符结尾的；例如：ab+$就可以被“abb”，“ab”匹配；<br />7、一些简单表示方法：<br />\d表示[0-9];\D表示[^0-9];\w表示[A-Z0-9];\W表示[^A-Z0-9];\s表示[\t\n\r\f],就是空格字符包括tab<br /><br />，空格等等;\S表示[^\t\n\r\f]，就是非空格字符;<br />8、常用的匹配：<br />匹配中文字符： “[\u4e00-\u9fa5]”；<br />匹配双字节字符(包括汉字在内)：“[^\x00-\xff]”；<br />匹配空行的正则表达式：“\n[\s| ]*\r”；<br />匹配HTML标记的正则表达式：“/&lt;(.*)&gt;.*&lt;\/\1&gt;|&lt;(.*) \/&gt;/”；<br />匹配首尾空格的正则表达式：“(^\s*)|(\s*$)”；<br />匹配非负整数（正整数 + 0）：“^\d+$”；　　 <br />匹配正整数：“^[0-9]*[1-9][0-9]*$”； <br />匹配非正整数（负整数 + 0）：“^((-\d+)|(0+))$”；<br />匹配负整数：“^-[0-9]*[1-9][0-9]*$”；<br />匹配整数：“^-?\d+$”；<br />匹配非负浮点数（正浮点数 + 0）：“^\d+(\.\d+)?$”<br />匹配正浮点数：“^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*<br /><br />))$”；<br />^((-\d+(\.\d+)?)|(0+(\.0+)?))$　　//匹配非正浮点数（负浮点数 + 0） <br />^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$　　//匹配<br /><br />负浮点数 <br />匹配浮点数：“^(-?\d+)(\.\d+)?$”；<br />匹配由数字、26个英文字母或者下划线组成的字符串：“^\w+$”；<br />匹配email地址：“^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$”；<br />匹配url：“^[a-zA-z]+://匹配(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\S*)?$”<br /></div>
<img src ="http://www.blogjava.net/aawanghuan/aggbug/76339.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/aawanghuan/" target="_blank">萝卜青菜</a> 2006-10-20 10:56 <a href="http://www.blogjava.net/aawanghuan/articles/76339.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>正则表达式基础知识 </title><link>http://www.blogjava.net/aawanghuan/articles/76337.html</link><dc:creator>萝卜青菜</dc:creator><author>萝卜青菜</author><pubDate>Fri, 20 Oct 2006 02:55:00 GMT</pubDate><guid>http://www.blogjava.net/aawanghuan/articles/76337.html</guid><wfw:comment>http://www.blogjava.net/aawanghuan/comments/76337.html</wfw:comment><comments>http://www.blogjava.net/aawanghuan/articles/76337.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/aawanghuan/comments/commentRss/76337.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/aawanghuan/services/trackbacks/76337.html</trackback:ping><description><![CDATA[
		<div>
				<div class="post"> </div>
				<div class="post">
						<div class="postfoot">
								<div class="em"> </div>
						</div>
				</div>
				<div class="post">
						<h5 class="posthead">
								<a id="bp___v___r___postlist___EntryItems_ctl06_PostTitle" href="http://myblog.workgroup.cn/blogs/other/archive/2006/07/07/_636B19526888BE8F0F5FFA574078E577C68B_.aspx">正则表达式基础知识</a>
						</h5>一个正则表达式就是由普通字符（例如字符 a 到 z）以及特殊字符（称为元字符）组成的文字模式。该模式描述在查找文字主体时待匹配的一个或多个字符串。正则表达式作为一个模板，将某个字符模式与所搜索的字符串进行匹配。如： <br /><br />JScript VBScript 匹配 <br />/^\[ \t]*$/ "^\[ \t]*$" 匹配一个空白行。 <br />/\d{2}-\d{5}/ "\d{2}-\d{5}" 验证一个ID 号码是否由一个2位数字，一个连字符以及一个5位数字组成。 <br />/&lt;(.*)&gt;.*&lt;\/\1&gt;/ "&lt;(.*)&gt;.*&lt;\/\1&gt;" 匹配一个 HTML 标记。 <br /><br /><br />下表是元字符及其在正则表达式上下文中的行为的一个完整列表：<br />字符 描述 <br />\ 将下一个字符标记为一个特殊字符、或一个原义字符、或一个 向后引用、或一个八进制转义符。例如，'n' 匹配字符 "n"。'\n' 匹配一个换行符。序列 '\\' 匹配 "\" 而 "\(" 则匹配 "("。 <br />^ 匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性，^ 也匹配 '\n' 或 '\r' 之后的位置。 <br />$ 匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性，$ 也匹配 '\n' 或 '\r' 之前的位置。 <br />* 匹配前面的子表达式零次或多次。例如，zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。 <br />+ 匹配前面的子表达式一次或多次。例如，'zo+' 能匹配 "zo" 以及 "zoo"，但不能匹配 "z"。+ 等价于 {1,}。 <br />? 匹配前面的子表达式零次或一次。例如，"do(es)?" 可以匹配 "do" 或 "does" 中的"do" 。? 等价于 {0,1}。 <br />{n} n 是一个非负整数。匹配确定的 n 次。例如，'o{2}' 不能匹配 "Bob" 中的 'o'，但是能匹配 "food" 中的两个 o。 <br />{n,} n 是一个非负整数。至少匹配n 次。例如，'o{2,}' 不能匹配 "Bob" 中的 'o'，但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。 <br />{n,m} m 和 n 均为非负整数，其中n &lt;= m。最少匹配 n 次且最多匹配 m 次。例如，"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。 <br />? 当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时，匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串，而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如，对于字符串 "oooo"，'o+?' 将匹配单个 "o"，而 'o+' 将匹配所有 'o'。 <br />. 匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符，请使用象 '[.\n]' 的模式。 <br />(pattern) 匹配 pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到，在VBScript 中使用 SubMatches 集合，在JScript 中则使用 $0…$9 属性。要匹配圆括号字符，请使用 '\(' 或 '\)'。 <br />(?:pattern) 匹配 pattern 但不获取匹配结果，也就是说这是一个非获取匹配，不进行存储供以后使用。这在使用 "或" 字符 (|) 来组合一个模式的各个部分是很有用。例如， 'industr(?:y|ies) 就是一个比 'industry|industries' 更简略的表达式。 <br />(?=pattern) 正向预查，在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配，也就是说，该匹配不需要获取供以后使用。例如，'Windows (?=95|98|NT|2000)' 能匹配 "Windows 2000" 中的 "Windows" ，但不能匹配 "Windows 3.1" 中的 "Windows"。预查不消耗字符，也就是说，在一个匹配发生后，在最后一次匹配之后立即开始下一次匹配的搜索，而不是从包含预查的字符之后开始。 <br />(?!pattern) 负向预查，在任何不匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配，也就是说，该匹配不需要获取供以后使用。例如'Windows (?!95|98|NT|2000)' 能匹配 "Windows 3.1" 中的 "Windows"，但不能匹配 "Windows 2000" 中的 "Windows"。预查不消耗字符，也就是说，在一个匹配发生后，在最后一次匹配之后立即开始下一次匹配的搜索，而不是从包含预查的字符之后开始 <br />x|y 匹配 x 或 y。例如，'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 则匹配 "zood" 或 "food"。 <br />[xyz] 字符集合。匹配所包含的任意一个字符。例如， '[abc]' 可以匹配 "plain" 中的 'a'。 <br />[^xyz] 负值字符集合。匹配未包含的任意字符。例如， '[^abc]' 可以匹配 "plain" 中的'p'。 <br />[a-z] 字符范围。匹配指定范围内的任意字符。例如，'[a-z]' 可以匹配 'a' 到 'z' 范围内的任意小写字母字符。 <br />[^a-z] 负值字符范围。匹配任何不在指定范围内的任意字符。例如，'[^a-z]' 可以匹配任何不在 'a' 到 'z' 范围内的任意字符。 <br />\b 匹配一个单词边界，也就是指单词和空格间的位置。例如， 'er\b' 可以匹配"never" 中的 'er'，但不能匹配 "verb" 中的 'er'。 <br />\B 匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er'，但不能匹配 "never" 中的 'er'。 <br />\cx 匹配由 x 指明的控制字符。例如， \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则，将 c 视为一个原义的 'c' 字符。 <br />\d 匹配一个数字字符。等价于 [0-9]。 <br />\D 匹配一个非数字字符。等价于 [^0-9]。 <br />\f 匹配一个换页符。等价于 \x0c 和 \cL。 <br />\n 匹配一个换行符。等价于 \x0a 和 \cJ。 <br />\r 匹配一个回车符。等价于 \x0d 和 \cM。 <br />\s 匹配任何空白字符，包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。 <br />\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。 <br />\t 匹配一个制表符。等价于 \x09 和 \cI。 <br />\v 匹配一个垂直制表符。等价于 \x0b 和 \cK。 <br />\w 匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。 <br />\W 匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。 <br />\xn 匹配 n，其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如，'\x41' 匹配 "A"。'\x041' 则等价于 '\x04' &amp; "1"。正则表达式中可以使用 ASCII 编码。. <br />\num 匹配 num，其中 num 是一个正整数。对所获取的匹配的引用。例如，'(.)\1' 匹配两个连续的相同字符。 <br />\n 标识一个八进制转义值或一个向后引用。如果 \n 之前至少 n 个获取的子表达式，则 n 为向后引用。否则，如果 n 为八进制数字 (0-7)，则 n 为一个八进制转义值。 <br />\nm 标识一个八进制转义值或一个向后引用。如果 \nm 之前至少有 nm 个获得子表达式，则 nm 为向后引用。如果 \nm 之前至少有 n 个获取，则 n 为一个后跟文字 m 的向后引用。如果前面的条件都不满足，若 n 和 m 均为八进制数字 (0-7)，则 \nm 将匹配八进制转义值 nm。 <br />\nml 如果 n 为八进制数字 (0-3)，且 m 和 l 均为八进制数字 (0-7)，则匹配八进制转义值 nml。 <br />\un 匹配 n，其中 n 是一个用四个十六进制数字表示的 Unicode 字符。例如， \u00A9 匹配版权符号 (©)。 <br /><br /><br />下面看几个例子：<br />"^The"：表示所有以"The"开始的字符串（"There"，"The cat"等）； <br />"of despair$"：表示所以以"of despair"结尾的字符串； <br />"^abc$"：表示开始和结尾都是"abc"的字符串——呵呵，只有"abc"自己了； <br />"notice"：表示任何包含"notice"的字符串。 <br /><br />'*'，'+'和'?'这三个符号，表示一个或一序列字符重复出现的次数。它们分别表示“没有或 <br />更多”，“一次或更多”还有“没有或一次”。下面是几个例子： <br /><br />"ab*"：表示一个字符串有一个a后面跟着零个或若干个b。（"a", "ab", "abbb",……）； <br />"ab+"：表示一个字符串有一个a后面跟着至少一个b或者更多； <br />"ab?"：表示一个字符串有一个a后面跟着零个或者一个b； <br />"a?b+$"：表示在字符串的末尾有零个或一个a跟着一个或几个b。 <br /><br />也可以使用范围，用大括号括起，用以表示重复次数的范围。 <br /><br />"ab{2}"：表示一个字符串有一个a跟着2个b（"abb"）； <br />"ab{2,}"：表示一个字符串有一个a跟着至少2个b； <br />"ab{3,5}"：表示一个字符串有一个a跟着3到5个b。 <br /><br />请注意，你必须指定范围的下限（如："{0,2}"而不是"{,2}"）。还有，你可能注意到了，'*'，'+'和 <br />'?'相当于"{0,}"，"{1,}"和"{0,1}"。 <br />还有一个'¦'，表示“或”操作： <br /><br />"hi¦hello"：表示一个字符串里有"hi"或者"hello"； <br />"(b¦cd)ef"：表示"bef"或"cdef"； <br />"(a¦b)*c"：表示一串"a""b"混合的字符串后面跟一个"c"； <br /><br />'.'可以替代任何字符： <br /><br />"a.[0-9]"：表示一个字符串有一个"a"后面跟着一个任意字符和一个数字； <br />"^.{3}$"：表示有任意三个字符的字符串（长度为3个字符）； <br /><br />方括号表示某些字符允许在一个字符串中的某一特定位置出现： <br /><br />"[ab]"：表示一个字符串有一个"a"或"b"（相当于"a¦b"）； <br />"[a-d]"：表示一个字符串包含小写的'a'到'd'中的一个（相当于"a¦b¦c¦d"或者"[abcd]"）； <br />"^[a-zA-Z]"：表示一个以字母开头的字符串； <br />"[0-9]%"：表示一个百分号前有一位的数字； <br />",[a-zA-Z0-9]$"：表示一个字符串以一个逗号后面跟着一个字母或数字结束。 <br /><br />你也可以在方括号里用'^'表示不希望出现的字符，'^'应在方括号里的第一位。（如："%[^a-zA-Z]%"表 <br />示两个百分号中不应该出现字母）。 <br /><br />为了逐字表达，必须在"^.$()¦*+?{\"这些字符前加上转移字符'\'。 <br /><br />请注意在方括号中，不需要转义字符。<br /><div class="postfoot"> </div></div>
				<div class="post">
						<p>
								<a title="jsgrpregexpsyntax" name="jsgrpregexpsyntax">
								</a> </p>
				</div>
		</div>
<img src ="http://www.blogjava.net/aawanghuan/aggbug/76337.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/aawanghuan/" target="_blank">萝卜青菜</a> 2006-10-20 10:55 <a href="http://www.blogjava.net/aawanghuan/articles/76337.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JScript 和 VBScript 正则表达式 特殊字符 </title><link>http://www.blogjava.net/aawanghuan/articles/76336.html</link><dc:creator>萝卜青菜</dc:creator><author>萝卜青菜</author><pubDate>Fri, 20 Oct 2006 02:53:00 GMT</pubDate><guid>http://www.blogjava.net/aawanghuan/articles/76336.html</guid><wfw:comment>http://www.blogjava.net/aawanghuan/comments/76336.html</wfw:comment><comments>http://www.blogjava.net/aawanghuan/articles/76336.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/aawanghuan/comments/commentRss/76336.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/aawanghuan/services/trackbacks/76336.html</trackback:ping><description><![CDATA[
		<h5 class="posthead">
				<a id="bp___v___r___postlist___EntryItems_ctl05_PostTitle" href="http://myblog.workgroup.cn/blogs/other/archive/2006/07/07/JScript-_8C54_-VBScript-_636B19526888BE8F0F5F_-_79728A6B575B267B_.aspx">JScript 和 VBScript 正则表达式 特殊字符</a>
		</h5>有不少元字符在试图对其进行匹配时需要进行特殊的处理。要匹配这些特殊字符，必须首先将这些字符转义，也就是在前面使用一个反斜杠 (\)。下表给出了这些特殊字符及其含义：<br /><br />特殊字符 说明 <br />$ 匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性，则 $ 也匹配 '\n' 或 '\r'。要匹配 $ 字符本身，请使用 \$。 <br />( ) 标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符，请使用 \( 和 \)。 <br />* 匹配前面的子表达式零次或多次。要匹配 * 字符，请使用 \*。 <br />+ 匹配前面的子表达式一次或多次。要匹配 + 字符，请使用 \+。 <br />. 匹配除换行符 \n之外的任何单字符。要匹配 .，请使用 \。 <br />[ 标记一个中括号表达式的开始。要匹配 [，请使用 \[。 <br />? 匹配前面的子表达式零次或一次，或指明一个非贪婪限定符。要匹配 ? 字符，请使用 \?。 <br />\ 将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如， 'n' 匹配字符 'n'。'\n' 匹配换行符。序列 '\\' 匹配 "\"，而 '\(' 则匹配 "("。 <br />^ 匹配输入字符串的开始位置，除非在方括号表达式中使用，此时它表示不接受该字符集合。要匹配 ^ 字符本身，请使用 \^。 <br />{ 标记限定符表达式的开始。要匹配 {，请使用 \{。 <br />| 指明两项之间的一个选择。要匹配 |，请使用 \|。 <br /><img src ="http://www.blogjava.net/aawanghuan/aggbug/76336.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/aawanghuan/" target="_blank">萝卜青菜</a> 2006-10-20 10:53 <a href="http://www.blogjava.net/aawanghuan/articles/76336.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>正则表达式概述</title><link>http://www.blogjava.net/aawanghuan/articles/76335.html</link><dc:creator>萝卜青菜</dc:creator><author>萝卜青菜</author><pubDate>Fri, 20 Oct 2006 02:52:00 GMT</pubDate><guid>http://www.blogjava.net/aawanghuan/articles/76335.html</guid><wfw:comment>http://www.blogjava.net/aawanghuan/comments/76335.html</wfw:comment><comments>http://www.blogjava.net/aawanghuan/articles/76335.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/aawanghuan/comments/commentRss/76335.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/aawanghuan/services/trackbacks/76335.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 正则表达式概述								在前面已经涉及了一些正则表达式的用法，现在将系统地学习正则表达式的语法和用途。正则表达式主要用于进行字符串的模式匹配，例如判断一个字符串是否符合指定格式等。例如在windows下搜索文件，可以用“*”或者“?”这样的通配符。在正则表达式的语法中，有更多这样的符号用于表示一个字符串的模式，表7.1列出了所有的特殊符号，它们也被称为元字符。								...&nbsp;&nbsp;<a href='http://www.blogjava.net/aawanghuan/articles/76335.html'>阅读全文</a><img src ="http://www.blogjava.net/aawanghuan/aggbug/76335.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/aawanghuan/" target="_blank">萝卜青菜</a> 2006-10-20 10:52 <a href="http://www.blogjava.net/aawanghuan/articles/76335.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SVN使用技巧</title><link>http://www.blogjava.net/aawanghuan/articles/75840.html</link><dc:creator>萝卜青菜</dc:creator><author>萝卜青菜</author><pubDate>Wed, 18 Oct 2006 02:43:00 GMT</pubDate><guid>http://www.blogjava.net/aawanghuan/articles/75840.html</guid><wfw:comment>http://www.blogjava.net/aawanghuan/comments/75840.html</wfw:comment><comments>http://www.blogjava.net/aawanghuan/articles/75840.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/aawanghuan/comments/commentRss/75840.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/aawanghuan/services/trackbacks/75840.html</trackback:ping><description><![CDATA[
		<div>
				<h2 class="title">
						<br />
						<a name="_Toc121547260">
						</a> </h2>
				<div class="mybody">
						<div class="Section1">
								<p class="a" style="TEXT-INDENT: 24pt">
										<span style="FONT-FAMILY: 宋体">程序员编写程序的过程中，每个程序都会有很多不同的版本，这就需要程序员很好的管理代码，在需要的时间可以取出需要的版本，并且每个版本都有一个完整的说明。</span>
								</p>
								<p class="a" style="TEXT-INDENT: 24pt">
										<span style="FONT-FAMILY: 宋体">我们使用</span>Sub Version<span style="FONT-FAMILY: 宋体">（简称</span>SVN<span style="FONT-FAMILY: 宋体">）作为版本管理工具。这里着重介绍</span>SVN<span style="FONT-FAMILY: 宋体">作为跨平台的多人协作使用方法。在多个程序员管理同一段代码的过程中，版本的管理显得尤为重要，使用</span>SVN<span style="FONT-FAMILY: 宋体">可以方便的进行分支、合并，记录下所有的版本。</span></p>
								<a name="_Toc121547261">
								</a>
								<span>
										<span style="FONT-FAMILY: 宋体">基本配置</span>
								</span>
								<p class="a" style="TEXT-INDENT: 24pt">
										<span style="FONT-FAMILY: 宋体">在开始某项软件、文档的开发与撰写时，首先由配置管理负责人建立</span>SVN<span style="FONT-FAMILY: 宋体">仓库、用户名及其权限，并通知相关人员</span>SVN<span style="FONT-FAMILY: 宋体">仓库地址、</span>SVN<span style="FONT-FAMILY: 宋体">仓库负责人。</span></p>
								<a name="_Toc121547262">
								</a>
								<p class="a" style="TEXT-INDENT: 24pt">SVN<span style="FONT-FAMILY: 宋体">仓库的负责人把工程的</span>tsvn:logminisize<span style="FONT-FAMILY: 宋体">设置为</span>1<span style="FONT-FAMILY: 宋体">，以便强制注释。设置方法：在你的工程文件夹右键</span>-&gt;<span style="FONT-FAMILY: 宋体">属性中，进入</span>Subversion<span style="FONT-FAMILY: 宋体">标签，选中</span>tsvn: logminisize<span style="FONT-FAMILY: 宋体">，确保复选框</span>recursive<span style="FONT-FAMILY: 宋体">选中，然后点击</span>Set<span style="FONT-FAMILY: 宋体">按钮把它的值设为</span>1<span style="FONT-FAMILY: 宋体">，其意思是指提交的注释最短长度为一个字。如图：</span></p>
								<p class="a" style="MARGIN-LEFT: 60pt; TEXT-INDENT: 24pt">
										<img height="541" src="file:///D:/Documents/其他技术文档/SVN使用技巧%20-%20xyz黑板.files/image002.jpg" width="397" border="0" />
								</p>
								<p class="MsoCaption">
										<span style="FONT-FAMILY: 宋体">图</span>
										<span>
												<span>2</span>
										</span>
										<span>.</span>
										<span>
												<span>1</span>
										</span>
								</p>
								<a name="_Toc121547263">
								</a>
								<span>
										<span style="FONT-FAMILY: 宋体">软件配置</span>
								</span>
								<p class="a" style="MARGIN-LEFT: 45pt; TEXT-INDENT: -21pt">
										<span style="FONT-FAMILY: Wingdings">
												<span>l<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">        </span></span>
										</span>
										<span style="FONT-FAMILY: 宋体">忽略文件</span>
								</p>
								<p class="a" style="TEXT-INDENT: 24pt">
										<span style="FONT-FAMILY: 宋体">在</span>
										<span>SVN </span>
										<span style="FONT-FAMILY: 宋体">的</span>
										<span>[Setting]</span>
										<span style="FONT-FAMILY: 宋体">的</span>
										<span>[General]</span>
										<span style="FONT-FAMILY: 宋体">中</span>
										<span style="FONT-FAMILY: 宋体">，</span>
										<span style="FONT-FAMILY: 宋体">设置需要忽略的文件以便忽略掉一些临时的、无用的文件</span>
										<span style="FONT-FAMILY: 宋体">，</span>
										<span style="FONT-FAMILY: 宋体">常被忽略的文件有</span>
										<span>*.opt *.ncb *.suo *.plg *.pch *.idb *.pdb *.scc *.obj Debug Release *.o *.bin *.out *.ilk *.aps debug release *.clw *.bak</span>
										<span style="FONT-FAMILY: 宋体">。每个程序员可以根据自己的需要进行修改忽略文件，上面只是使用</span>VC++<span style="FONT-FAMILY: 宋体">与</span>Tornado<span style="FONT-FAMILY: 宋体">编程时常用的一些忽略文件。</span><img height="371" src="file:///D:/Documents/其他技术文档/SVN使用技巧%20-%20xyz黑板.files/image004.jpg" width="586" border="0" /></p>
								<p class="MsoCaption">
										<span style="FONT-FAMILY: 宋体">图</span>
										<span>
												<span>2</span>
										</span>
										<span>.</span>
										<span>
												<span>2</span>
										</span>
								</p>
								<p class="a" style="TEXT-INDENT: 24pt">
										<span style="FONT-FAMILY: 宋体">以上说的忽略文件是指全局的忽略文件。</span>SVN<span style="FONT-FAMILY: 宋体">还能在特定的目录中指定需要忽略的文件。忽略文件支持通配符。</span></p>
								<p class="a" style="MARGIN-LEFT: 45pt; TEXT-INDENT: -21pt">
										<span style="FONT-FAMILY: Wingdings">
												<span>l<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">        </span></span>
										</span>
										<span style="FONT-FAMILY: 宋体">合并比较工具</span>
								</p>
								<p class="a" style="TEXT-INDENT: 24pt">
										<span style="FONT-FAMILY: 宋体">在</span>Merge Tool<span style="FONT-FAMILY: 宋体">中可以选择用来合并的工具，强烈推荐用</span>Araxis Merge<span style="FONT-FAMILY: 宋体">。在</span>[Setting]-&gt;[Diff]<span style="FONT-FAMILY: 宋体">中填入</span>"C:\Program Files\Araxis\Araxis Merge v6.5\Merge.exe"<span style="FONT-FAMILY: 宋体">；在</span>[Setting]-&gt;[Merge]<span style="FONT-FAMILY: 宋体">的选项中，填入</span>"C:\Program Files\Araxis\Araxis Merge v6.5\Merge.exe" %theirs %mine %merged <span style="FONT-FAMILY: 宋体">；其中</span>"C:\Program Files\Araxis\Araxis Merge v6.5\Merge.exe"<span style="FONT-FAMILY: 宋体">是指合并工具的路径，</span>%theirs %mine %merged<span style="FONT-FAMILY: 宋体">分别指</span>..<span style="FONT-FAMILY: 宋体">将要合并到主干的分支，主干，及合并后的结果。</span></p>
								<p class="a" style="TEXT-INDENT: 24pt">
										<img height="371" src="file:///D:/Documents/其他技术文档/SVN使用技巧%20-%20xyz黑板.files/image006.jpg" width="586" border="0" />
								</p>
								<p class="MsoCaption">
										<span style="FONT-FAMILY: 宋体">图</span>
										<span>
												<span>2</span>
										</span>
										<span>.</span>
										<span>
												<span>3</span>
										</span>
								</p>
								<a name="_Toc121547264">
								</a>
								<span>
										<span style="FONT-FAMILY: 宋体">仓库目录结构</span>
								</span>
								<p class="a" style="TEXT-INDENT: 24pt">SVN<span style="FONT-FAMILY: 宋体">仓库的负责人规划好仓库的目录结构。推荐的目录结构如下图所示。</span></p>
								<p class="a" style="TEXT-INDENT: 24pt">
										<span style="FONT-FAMILY: 宋体">仓库的一级目录只有两个，分别为</span>code<span style="FONT-FAMILY: 宋体">和</span>doc<span style="FONT-FAMILY: 宋体">。其中，</span>doc<span style="FONT-FAMILY: 宋体">主要用来放置先期的文档，</span>code<span style="FONT-FAMILY: 宋体">主要用来放置工程的代码，也可以包含后期的文档。</span></p>
								<p class="a" style="TEXT-INDENT: 24pt">
										<span style="FONT-FAMILY: 宋体">仓库的二级目录只可以是</span>branch<span style="FONT-FAMILY: 宋体">与</span>trunk<span style="FONT-FAMILY: 宋体">两个目录，分别存放主干与分支。</span>trunk<span style="FONT-FAMILY: 宋体">目录下直接存放工程文件。</span>branch<span style="FONT-FAMILY: 宋体">目录下包括一些子目录分别对应各个分支。</span></p>
								<p class="MsoNormal" style="TEXT-ALIGN: center" align="center">
										<span>
												<img height="445" src="file:///D:/Documents/其他技术文档/SVN使用技巧%20-%20xyz黑板.files/image008.jpg" width="586" border="0" />
										</span>
								</p>
								<p class="MsoCaption">
										<span style="FONT-FAMILY: 宋体">图</span>
										<span>
												<span>2</span>
										</span>
										<span>.</span>
										<span>
												<span>4</span>
										</span>
								</p>
								<a name="_Toc121547265">
								</a>
								<p class="a" style="TEXT-INDENT: 24pt">
										<span style="FONT-FAMILY: 宋体">从</span>
										<span>SVN</span>
										<span style="FONT-FAMILY: 宋体">仓库中取出代码时</span>
										<span style="FONT-FAMILY: 宋体">，一定</span>
										<span style="FONT-FAMILY: 宋体">不要把整个仓库取出来</span>
										<span style="FONT-FAMILY: 宋体">，</span>
										<span style="FONT-FAMILY: 宋体">而应该只取出</span>
										<span>trunk</span>
										<span style="FONT-FAMILY: 宋体">目录</span>
										<span style="FONT-FAMILY: 宋体">，</span>
										<span style="FONT-FAMILY: 宋体">或只取出</span>
										<span>branch</span>
										<span style="FONT-FAMILY: 宋体">下的某个分支目录</span>
										<span style="FONT-FAMILY: 宋体">（比</span>
										<span style="FONT-FAMILY: 宋体">如上图中的</span>
										<span>svn:\\code\branch\xw_051206</span>
										<span style="FONT-FAMILY: 宋体">）</span>
										<span style="FONT-FAMILY: 宋体">。</span>
								</p>
								<a name="_Toc121547266">
								</a>
								<a name="_Toc121547267">
								</a>
								<p class="a" style="TEXT-INDENT: 24pt">
										<span style="FONT-FAMILY: 宋体">一个项目会有多个人共同合作开发完成。基本流程是：</span>
								</p>
								<p class="a" style="MARGIN-LEFT: 45pt; TEXT-INDENT: -21pt">
										<span style="FONT-FAMILY: Wingdings">
												<span>l<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">        </span></span>
										</span>
										<span style="FONT-FAMILY: 宋体">各开发成员建立自己的分支，并在此分支上开发；</span>
								</p>
								<p class="a" style="MARGIN-LEFT: 45pt; TEXT-INDENT: -21pt">
										<span style="FONT-FAMILY: Wingdings">
												<span>l<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">        </span></span>
										</span>
										<span style="FONT-FAMILY: 宋体">各开发成员把分支合并到主干上并形成较为稳定的版本；</span>
								</p>
								<p class="a" style="MARGIN-LEFT: 45pt; TEXT-INDENT: -21pt">
										<span style="FONT-FAMILY: Wingdings">
												<span>l<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">        </span></span>
										</span>
										<span style="FONT-FAMILY: 宋体">各个成员重新从主干上建立新的分支，在此分支上开发</span>
										<span>(</span>
										<span style="FONT-FAMILY: 宋体">即回到第一步</span>
										<span>)</span>
								</p>
								<p class="a" style="MARGIN-LEFT: 45pt; TEXT-INDENT: -21pt">
										<span style="FONT-FAMILY: Wingdings">
												<span>l<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">        </span></span>
										</span>
										<span style="FONT-FAMILY: 宋体">循环往复，直到工程结束。</span>
								</p>
								<p class="a" style="TEXT-INDENT: 24pt">
										<span style="FONT-FAMILY: 宋体">下面我用一个例子来说明合作开发的基本流程。</span>
								</p>
								<p class="a" style="TEXT-INDENT: 24pt">
										<span style="FONT-FAMILY: 宋体">现在</span>xb<span style="FONT-FAMILY: 宋体">与</span>lzj<span style="FONT-FAMILY: 宋体">两个开发人员要共同开发一个工程</span>onlytest<span style="FONT-FAMILY: 宋体">，其这个工程的主干的</span>SVN<span style="FONT-FAMILY: 宋体">仓库地址如下图。</span></p>
								<p class="MsoNormal" style="TEXT-ALIGN: center" align="center">
										<span>
												<img height="309" src="file:///D:/Documents/其他技术文档/SVN使用技巧%20-%20xyz黑板.files/image010.jpg" width="450" border="0" />
										</span>
								</p>
								<p class="MsoCaption">
										<span style="FONT-FAMILY: 宋体">图</span>
										<span>
												<span>2</span>
										</span>
										<span>.</span>
										<span>
												<span>5</span>
										</span>
								</p>
								<a name="_Toc121547268">
								</a>
								<p class="a" style="TEXT-INDENT: 24pt">xb<span style="FONT-FAMILY: 宋体">与</span>lzj<span style="FONT-FAMILY: 宋体">分别在</span>onlytest<span style="FONT-FAMILY: 宋体">这个工程中建立两个分支，分别为</span>xb _051115<span style="FONT-FAMILY: 宋体">和</span>lz_051115<span style="FONT-FAMILY: 宋体">。</span></p>
								<p class="a" style="TEXT-INDENT: 24pt">
										<span style="FONT-FAMILY: 宋体">在这里分支命名要采用</span>[<span style="COLOR: rgb(51,153,102); FONT-FAMILY: 宋体">姓名缩写</span><span style="COLOR: rgb(51,153,102)">_6</span><span style="COLOR: rgb(51,153,102); FONT-FAMILY: 宋体">个数的日期</span><span style="COLOR: rgb(51,153,102)">_</span><span style="COLOR: rgb(51,153,102); FONT-FAMILY: 宋体">后缀</span>(<span style="FONT-FAMILY: 宋体">可选</span>)]<span style="FONT-FAMILY: 宋体">的形式，比如</span>xb_051208_1<span style="FONT-FAMILY: 宋体">，</span>xb_051212<span style="FONT-FAMILY: 宋体">之类的。创建完分支后我们可以看到这个工程的目录结构如下图所示：</span></p>
								<p class="MsoNormal" style="TEXT-ALIGN: center" align="center">
										<span>
												<img height="426" src="file:///D:/Documents/其他技术文档/SVN使用技巧%20-%20xyz黑板.files/image012.jpg" width="586" border="0" />
										</span>
								</p>
								<p class="MsoCaption">
										<span style="FONT-FAMILY: 宋体">图</span>
										<span>
												<span>2</span>
										</span>
										<span>.</span>
										<span>
												<span>6</span>
										</span>
										<span style="FONT-FAMILY: 宋体">分支目录</span>
								</p>
								<p class="a" style="TEXT-INDENT: 24pt">
										<span style="FONT-FAMILY: 宋体">建完之后，</span> xb<span style="FONT-FAMILY: 宋体">和</span>lzj<span style="FONT-FAMILY: 宋体">分别在本地取出对应的分支进行开发。</span></p>
								<a name="_Toc121547269">
								</a>
								<p class="a" style="TEXT-INDENT: 24pt">
										<span style="FONT-FAMILY: 宋体">当</span>
										<span style="FONT-FAMILY: 宋体">程序到达一个比较稳定的阶段，就需要把分支合并到主干上，下面讲述一下合并的流程。</span>
								</p>
								<p class="a" style="TEXT-INDENT: 24pt">
										<span style="FONT-FAMILY: 宋体">在本节中继续使用上一节中所示的工程与</span>SVN<span style="FONT-FAMILY: 宋体">仓库讲解。</span></p>
								<span>
										<span>1.2.3.1 </span>
								</span>
								<span>xb</span>
								<span style="FONT-FAMILY: 黑体">与</span>
								<span>lzj</span>
								<span style="FONT-FAMILY: 黑体">分别修改自己分支上的代码</span>
								<p class="a" style="TEXT-INDENT: 24pt">
										<span style="FONT-FAMILY: 宋体">现在</span>
										<span style="FONT-FAMILY: 宋体">，</span>
										<span style="FONT-FAMILY: 宋体">主干上的</span>
										<span>test_SVN.txt</span>
										<span style="FONT-FAMILY: 宋体">是空文档。</span>
								</p>
								<p class="a" style="TEXT-INDENT: 24pt">
										<span style="FONT-FAMILY: 宋体">由</span>
										<span>xb</span>
										<span style="FONT-FAMILY: 宋体">与</span>
										<span>lzj</span>
										<span style="FONT-FAMILY: 宋体">修改提交后</span>
										<span style="FONT-FAMILY: 宋体">，</span>
										<span style="FONT-FAMILY: 宋体">两个分支中</span>
										<span>test_SVN.txt</span>
										<span style="FONT-FAMILY: 宋体">分别如下两图所示</span>
										<span style="FONT-FAMILY: 宋体">：</span>
								</p>
								<p class="MsoNormal" style="TEXT-ALIGN: center" align="center">
										<span>
												<img height="130" src="file:///D:/Documents/其他技术文档/SVN使用技巧%20-%20xyz黑板.files/image014.jpg" width="321" border="0" />
										</span>
								</p>
								<p class="MsoCaption">
										<span style="FONT-FAMILY: 宋体">图</span>
										<span>
												<span>2</span>
										</span>
										<span>.</span>
										<span>
												<span>7</span>
										</span>
										<span>xb_051129</span>
										<span style="FONT-FAMILY: 宋体">分支下的</span>
										<span>test_SVN.txt</span>
								</p>
								<p class="MsoNormal" style="TEXT-ALIGN: center" align="center">
										<span>
												<img height="130" src="file:///D:/Documents/其他技术文档/SVN使用技巧%20-%20xyz黑板.files/image016.jpg" width="321" border="0" />
										</span>
								</p>
								<p class="MsoCaption">
										<span style="FONT-FAMILY: 宋体">图</span>
										<span>
												<span>2</span>
										</span>
										<span>.</span>
										<span>
												<span>8</span>
										</span>
										<span>lzj_051129</span>
										<span style="FONT-FAMILY: 宋体">分支下的</span>
										<span>test_SVN.txt</span>
								</p>
								<span>
										<span>1.2.3.2 </span>
								</span>
								<span>xb</span>
								<span style="FONT-FAMILY: 黑体">将</span>
								<span>xb_051129</span>
								<span style="FONT-FAMILY: 黑体">分支合并到主干</span>
								<p class="a" style="TEXT-INDENT: 24pt">
										<span>xb</span>
										<span style="FONT-FAMILY: 宋体">先把主干</span>
										<span>check out</span>
										<span style="FONT-FAMILY: 宋体">到本地。然后在主干的目录上右键</span>
										<span style="FONT-FAMILY: 宋体">选择</span>svn-&gt;merge<span style="FONT-FAMILY: 宋体">，弹出如下窗口：</span></p>
								<p class="MsoNormal" style="TEXT-ALIGN: center" align="center">
										<span>
												<img height="466" src="file:///D:/Documents/其他技术文档/SVN使用技巧%20-%20xyz黑板.files/image018.jpg" width="524" border="0" />
										</span>
								</p>
								<p class="MsoCaption">
										<span style="FONT-FAMILY: 宋体">图</span>
										<span>
												<span>2</span>
										</span>
										<span>.</span>
										<span>
												<span>9</span>
										</span>
										<span style="FONT-FAMILY: 宋体">合并对话框</span>
								</p>
								<p class="a" style="TEXT-INDENT: 24pt">
										<span style="FONT-FAMILY: 宋体">此对话框的含义是把</span>From<span style="FONT-FAMILY: 宋体">指定的分支版本到</span>To<span style="FONT-FAMILY: 宋体">指定的分支版本之间的差异合并到主干上。</span></p>
								<p class="a" style="TEXT-INDENT: 24pt">
										<span style="FONT-FAMILY: 宋体">在这里分支选的是</span>xb_051129<span style="FONT-FAMILY: 宋体">。版本号的选定方法是点击</span>From<span style="FONT-FAMILY: 宋体">中的</span>Show Log<span style="FONT-FAMILY: 宋体">，在</span>Log<span style="FONT-FAMILY: 宋体">窗口中按住</span>Ctrl<span style="FONT-FAMILY: 宋体">键，点击选择</span>”made a copy”<span style="FONT-FAMILY: 宋体">之上的那个版本，以及最顶上的那个版本，如</span><span style="FONT-FAMILY: 宋体">图</span><span>2</span>.<span>11</span><span style="FONT-FAMILY: 宋体">所示。然后点击确定回到上图中的对话框，会自动填写</span>From<span style="FONT-FAMILY: 宋体">与</span>To<span style="FONT-FAMILY: 宋体">中的</span>Revision<span style="FONT-FAMILY: 宋体">号。</span></p>
								<p class="MsoNormal" style="TEXT-INDENT: 21pt">
										<span>
												<img height="581" src="file:///D:/Documents/其他技术文档/SVN使用技巧%20-%20xyz黑板.files/image020.jpg" width="585" border="0" />
										</span>
								</p>
								<p class="MsoCaption">
										<a name="_Ref121716988">
										</a>
										<span>
												<span>
														<span>2</span>
												</span>
										</span>
										<span>
												<span>.</span>
										</span>
										<span>
												<span>
														<span>10</span>
												</span>
										</span>
										<span style="FONT-FAMILY: 宋体">选择需要合并的版本</span>
								</p>
								<p class="a" style="TEXT-INDENT: 24pt">
										<span style="FONT-FAMILY: 宋体">然后直接点击</span>merge<span style="FONT-FAMILY: 宋体">进行合并，你也可以通过</span>dry run<span style="FONT-FAMILY: 宋体">来看是不是两者之间有差异。由于没有其它人修改主干，所以合并的很顺利，下图是</span>xb_051115<span style="FONT-FAMILY: 宋体">与主干合并后的结果。合并完毕之后，由</span>xb<span style="FONT-FAMILY: 宋体">对主干进行提交。</span></p>
								<p class="a" style="TEXT-INDENT: 24pt; TEXT-ALIGN: center" align="center">
										<img height="130" src="file:///D:/Documents/其他技术文档/SVN使用技巧%20-%20xyz黑板.files/image022.jpg" width="321" border="0" />
								</p>
								<p class="MsoCaption">
										<span style="FONT-FAMILY: 宋体">图</span>
										<span>
												<span>2</span>
										</span>
										<span>.</span>
										<span>
												<span>11</span>
										</span>
										<span style="FONT-FAMILY: 宋体">合并后，主干上的</span>
										<span>test_SVN.txt</span>
								</p>
								<p class="a" style="TEXT-INDENT: 24pt"> </p>
								<span>
										<span>1.2.3.3 </span>
								</span>
								<span>lzj</span>
								<span style="FONT-FAMILY: 黑体">将</span>
								<span>lzj_051129</span>
								<span style="FONT-FAMILY: 黑体">分支合并到主干，解决冲突</span>
								<p class="a" style="TEXT-INDENT: 24pt">xb<span style="FONT-FAMILY: 宋体">合并完毕之后，</span>lzj<span style="FONT-FAMILY: 宋体">要将他的分支合并到主干上去，方法同上。但是由于</span>xb<span style="FONT-FAMILY: 宋体">已经修改过主干，所以产生了冲突，会弹出一个冲突对话框。双击对话框中的产生冲突的文件名，就可以调出工具对此文件进行合并，下图是我们用</span>merge<span style="FONT-FAMILY: 宋体">工具显示的界面。</span></p>
								<p class="MsoNormal">
										<span>
												<img height="382" src="file:///D:/Documents/其他技术文档/SVN使用技巧%20-%20xyz黑板.files/image023.jpg" width="585" border="0" />
										</span>
								</p>
								<p class="MsoCaption">
										<span style="FONT-FAMILY: 宋体">图</span>
										<span>
												<span>2</span>
										</span>
										<span>.</span>
										<span>
												<span>12</span>
										</span>
								</p>
								<p class="a" style="MARGIN-LEFT: 45pt; TEXT-INDENT: -21pt">
										<span style="FONT-FAMILY: Wingdings">
												<span>l<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">        </span></span>
										</span>
										<span style="FONT-FAMILY: 宋体">首先比较第一个窗口与第二个窗口，把结果修改合并到第二个窗口。</span>
								</p>
								<p class="a" style="MARGIN-LEFT: 45pt; TEXT-INDENT: -21pt">
										<span style="FONT-FAMILY: Wingdings">
												<span>l<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">        </span></span>
										</span>
										<span style="FONT-FAMILY: 宋体">然后确保光标处于第二个窗口时，点击上图中红色圈圈所示的按钮。这样会把第二个窗口的内容全部复制到第三个容口。之后保存，退出。</span>
								</p>
								<p class="a" style="MARGIN-LEFT: 45pt; TEXT-INDENT: -21pt">
										<span style="FONT-FAMILY: Wingdings">
												<span>l<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">        </span></span>
										</span>
										<span style="FONT-FAMILY: 宋体">然后在工程目录上点右键，进行</span>SVN-&gt;Resolved<span style="FONT-FAMILY: 宋体">。这样会删除无用的临时文件。</span></p>
								<p class="a" style="MARGIN-LEFT: 45pt; TEXT-INDENT: -21pt">
										<span style="FONT-FAMILY: Wingdings">
												<span>l<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">        </span></span>
										</span>
										<span style="FONT-FAMILY: 宋体">最后提交所作的修改，并添加详细的注释。</span>
								</p>
								<a name="_Toc121547270">
								</a>
								<a name="_Toc121547271">
								</a>
								<span>
										<span style="FONT-FAMILY: 宋体">中的标签</span>
								</span>
								<p class="a" style="TEXT-INDENT: 24pt">
										<span style="FONT-FAMILY: 宋体">与</span>CVS<span style="FONT-FAMILY: 宋体">不同，使用</span>SVN<span style="FONT-FAMILY: 宋体">时不用专门为目录添加标签，因为</span>SVN<span style="FONT-FAMILY: 宋体">也对目录进行版本管理。</span></p>
								<p class="MsoNormal" style="TEXT-INDENT: 21pt">
										<span style="FONT-FAMILY: 宋体">我们在提交时写好注释（比如重要的版本提交时使用</span>
										<span>051201</span>
										<span style="FONT-FAMILY: 宋体">之类的日期作为开头），就可以通过注释来查找比较重要的目录版本号，相当于</span>
										<span>CVS</span>
										<span style="FONT-FAMILY: 宋体">或</span>
										<span>VSS</span>
										<span style="FONT-FAMILY: 宋体">中的标签。</span>
								</p>
								<p class="MsoNormal" style="TEXT-INDENT: 21pt">
										<span style="FONT-FAMILY: 宋体">另外，每个工程都会有一个版本说明文件，通过此文件可以查找关键版本。</span>
								</p>
								<a name="_Toc121547272">
								</a>
								<p class="a" style="TEXT-INDENT: 24pt">
										<span style="FONT-FAMILY: 宋体">你可以重命名、移动或删除你的文件或文件夹，但请使用</span>SVN<span style="FONT-FAMILY: 宋体">进行这些操作，否则之前的版本信息会丢失。</span></p>
								<p class="a" style="TEXT-INDENT: 24pt">
										<span style="FONT-FAMILY: 宋体">使用</span>SVN<span style="FONT-FAMILY: 宋体">删除、移动与重命名文件夹的方法是在文件</span>/<span style="FONT-FAMILY: 宋体">文件夹上点右键进行</span>SVN<span style="FONT-FAMILY: 宋体">操作，或直接在资源浏览器中使用右键拖放（会弹出</span>SVN<span style="FONT-FAMILY: 宋体">选项）。</span></p>
								<p class="a" style="TEXT-INDENT: 24pt">
										<span style="FONT-FAMILY: 宋体">文件的删除、移动与重命名之前，必须保证工作目录是最新的版本；进行这些操作之后，需要进行提交。</span>
								</p>
								<span>
										<span>1.3.3 </span>
								</span>
								<span style="FONT-FAMILY: 宋体">版本的回退</span>
								<p class="a" style="TEXT-INDENT: 24pt">
										<span style="FONT-FAMILY: 宋体">在代码的编写过程中，难免会有不尽人意的地方，你也许需要回退到某一个版本，但是在这个过程中可能有一些文件你想保留，也有一些文件你不想保留，这就牵扯到很复杂的版本管理过程，在这里给大家推荐几种方法。</span>
								</p>
								<p class="a" style="MARGIN-LEFT: 45pt; TEXT-INDENT: -21pt">
										<span>
												<span>1.<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">        </span></span>
										</span>
										<span style="FONT-FAMILY: 宋体">若是你编辑了工程，在没有提交的前提下，你想放弃这些修改，你可以直接选择</span>
										<span>revert</span>
										<span style="FONT-FAMILY: 宋体">就可以更新到工程的最新的版本。</span>
								</p>
								<p class="a" style="MARGIN-LEFT: 45pt; TEXT-INDENT: -21pt">
										<span>
												<span>2.<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">        </span></span>
										</span>
										<span style="FONT-FAMILY: 宋体">若是你想退回到某一个版本，你就可以直接选择</span>
										<span>update to reversion</span>
										<span style="FONT-FAMILY: 宋体">如图</span>
										<span>,</span>
										<span style="FONT-FAMILY: 宋体">这样我们就可以把我们的版本回退到你选中的版本去，这种情况下</span>
										<span>SVN</span>
										<span style="FONT-FAMILY: 宋体">并没有显示出有什么冲突，并且新建立的文件也还在，但是在这种情况下你并不能直接在你回退后的版本上进行编辑，因为</span>
										<span>SVN</span>
										<span style="FONT-FAMILY: 宋体">的版本控制还是在最新的主干上。我们需要</span>
										<span>update</span>
										<span style="FONT-FAMILY: 宋体">并解决冲突。</span>
										<span>
										</span>
								</p>
								<p class="a" style="MARGIN-LEFT: 45pt; TEXT-INDENT: -21pt">
										<span>
												<span>3.<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">        </span></span>
										</span>
										<span style="FONT-FAMILY: 宋体">你可以直接选择</span>
										<span>revert changes from this revision</span>
										<span style="FONT-FAMILY: 宋体">如图，这样的话你可以直接解决冲突并提交。不过这种方法的不足是，你新建的文件都没有了，整个工程都回退到之前的版本了。</span>
								</p>
								<p class="a" style="MARGIN-LEFT: 45pt; TEXT-INDENT: -21pt">
										<span>
												<span>4.<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">        </span></span>
										</span>
										<span style="FONT-FAMILY: 宋体">我推荐的一种方法是，直接</span>
										<span>export</span>
										<span style="FONT-FAMILY: 宋体">一个你需要的版本，然后用你</span>
										<span>export</span>
										<span style="FONT-FAMILY: 宋体">的版本覆盖你的最新的版本，这样你就可以不丢失你新建的文件，同时获得</span>
										<span>head</span>
										<span style="FONT-FAMILY: 宋体">的</span>
										<span>SVN</span>
										<span style="FONT-FAMILY: 宋体">控制文件。</span>
								</p>
								<p class="a" style="MARGIN-LEFT: 24pt; TEXT-INDENT: 0pt">
										<span>
												<img height="563" src="file:///D:/Documents/其他技术文档/SVN使用技巧%20-%20xyz黑板.files/image025.jpg" width="586" border="0" />
										</span>
								</p>
								<p class="MsoCaption">
										<span style="FONT-FAMILY: 宋体">图</span>
										<span>
												<span>13</span>
										</span>
								</p>
								<p class="MsoNormal">
										<span>
										</span> </p>
								<a name="_Toc121547273">
								</a>
								<p class="a" style="TEXT-INDENT: 24pt">
										<span style="FONT-FAMILY: 宋体">每个工程会有很多个小模块，当某个模块达到稳定的时候，你就需要提交一次，以免写下个模块代码的时候出现不可恢复的错误。</span>
								</p>
								<p class="a" style="TEXT-INDENT: 24pt">
										<span style="FONT-FAMILY: 宋体">每一次提交需要前，需要通过</span>pclint<span style="FONT-FAMILY: 宋体">检查，保证是一个编译没有错误的版本。当提交比较稳定的版本的时候，同时要修改你的版本号。</span></p>
								<p class="a" style="TEXT-INDENT: 24pt">
										<a name="_Toc121547274">
										</a>
								</p>
								<span>
										<span>
												<span>1.3.5 </span>
										</span>
										<span style="FONT-FAMILY: 宋体">版本说明文件</span>
								</span>
								<p class="a" style="TEXT-INDENT: 24pt">
										<span style="FONT-FAMILY: 宋体">版本说明文件为</span>xml<span style="FONT-FAMILY: 宋体">表格，可用</span>excel<span style="FONT-FAMILY: 宋体">编辑，它会记录下关键的版本信息。</span></p>
								<p class="a" style="TEXT-INDENT: 24pt">
										<span style="FONT-FAMILY: 宋体">版本说明文件内容如下表。发布版本是指用户对外公布的版本号，后文中有详细描述；</span>Revision<span style="FONT-FAMILY: 宋体">是</span>SVN<span style="FONT-FAMILY: 宋体">内部的工程文件夹的版本号。一个发布版本可能对应多个</span>Revision<span style="FONT-FAMILY: 宋体">：</span></p>
								<table class="MsoTableGrid" style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse" cellspacing="0" cellpadding="0" border="1">
										<tbody>
												<tr>
														<td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0pt; BORDER-LEFT: windowtext 1pt solid; WIDTH: 65.4pt; PADDING-TOP: 0pt; BORDER-BOTTOM: windowtext 1pt solid" valign="top" width="87">
																<p class="a" style="TEXT-INDENT: 0pt; TEXT-ALIGN: justify">
																		<span style="FONT-FAMILY: 宋体">发布版本</span>
																</p>
														</td>
														<td style="BORDER-RIGHT: 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0pt; BORDER-LEFT: medium none; WIDTH: 65.4pt; PADDING-TOP: 0pt; BORDER-BOTTOM: 1pt solid" valign="top" width="87">
																<p class="a" style="TEXT-INDENT: 0pt; TEXT-ALIGN: justify">Revision </p>
														</td>
														<td style="BORDER-RIGHT: 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: 1pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0pt; BORDER-LEFT: medium none; WIDTH: 312.6pt; PADDING-TOP: 0pt; BORDER-BOTTOM: 1pt solid" valign="top" width="417">
																<p class="a" style="TEXT-INDENT: 0pt; TEXT-ALIGN: justify">
																		<span style="FONT-FAMILY: 宋体">详细说明</span>
																</p>
														</td>
												</tr>
												<tr>
														<td style="BORDER-RIGHT: 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0pt; BORDER-LEFT: 1pt solid; WIDTH: 65.4pt; PADDING-TOP: 0pt; BORDER-BOTTOM: 1pt solid" valign="top" width="87" rowspan="3">
																<p class="a" style="TEXT-INDENT: 0pt; TEXT-ALIGN: justify">1,0,0,12</p>
														</td>
														<td style="BORDER-RIGHT: 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0pt; BORDER-LEFT: medium none; WIDTH: 65.4pt; PADDING-TOP: 0pt; BORDER-BOTTOM: 1pt solid" valign="top" width="87">
																<p class="a" style="TEXT-INDENT: 0pt; TEXT-ALIGN: justify">76</p>
														</td>
														<td style="BORDER-RIGHT: 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0pt; BORDER-LEFT: medium none; WIDTH: 312.6pt; PADDING-TOP: 0pt; BORDER-BOTTOM: 1pt solid" valign="top" width="417">
																<p class="MsoNormal" style="TEXT-ALIGN: justify">
																		<span style="FONT-FAMILY: 宋体">加入了抗干扰日志，需长时间测试</span>
																</p>
																<p class="MsoNormal" style="TEXT-ALIGN: justify">
																		<span style="FONT-FAMILY: 宋体">程序代码进行了重构，已经调试通过</span>
																</p>
														</td>
												</tr>
												<tr>
														<td style="BORDER-RIGHT: 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0pt; BORDER-LEFT: medium none; WIDTH: 65.4pt; PADDING-TOP: 0pt; BORDER-BOTTOM: 1pt solid" valign="top" width="87">
																<p class="a" style="TEXT-INDENT: 0pt; TEXT-ALIGN: justify">77</p>
														</td>
														<td style="BORDER-RIGHT: 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0pt; BORDER-LEFT: medium none; WIDTH: 312.6pt; PADDING-TOP: 0pt; BORDER-BOTTOM: 1pt solid" valign="top" width="417">
																<p class="MsoNormal" style="TEXT-ALIGN: justify">
																		<span>xxx @#$%^&amp;</span>
																</p>
														</td>
												</tr>
												<tr>
														<td style="BORDER-RIGHT: 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0pt; BORDER-LEFT: medium none; WIDTH: 65.4pt; PADDING-TOP: 0pt; BORDER-BOTTOM: 1pt solid" valign="top" width="87">
																<p class="a" style="TEXT-INDENT: 0pt; TEXT-ALIGN: justify">78</p>
														</td>
														<td style="BORDER-RIGHT: 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0pt; BORDER-LEFT: medium none; WIDTH: 312.6pt; PADDING-TOP: 0pt; BORDER-BOTTOM: 1pt solid" valign="top" width="417">
																<p class="a" style="TEXT-INDENT: 0pt; TEXT-ALIGN: justify">
																		<span style="FONT-FAMILY: 宋体">啥</span>...</p>
														</td>
												</tr>
												<tr>
														<td style="BORDER-RIGHT: 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0pt; BORDER-LEFT: 1pt solid; WIDTH: 65.4pt; PADDING-TOP: 0pt; BORDER-BOTTOM: 1pt solid" valign="top" width="87">
																<p class="a" style="TEXT-INDENT: 0pt; TEXT-ALIGN: justify">1,0,0,13</p>
														</td>
														<td style="BORDER-RIGHT: 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0pt; BORDER-LEFT: medium none; WIDTH: 65.4pt; PADDING-TOP: 0pt; BORDER-BOTTOM: 1pt solid" valign="top" width="87">
																<p class="a" style="TEXT-INDENT: 0pt; TEXT-ALIGN: justify">81</p>
														</td>
														<td style="BORDER-RIGHT: 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0pt; BORDER-LEFT: medium none; WIDTH: 312.6pt; PADDING-TOP: 0pt; BORDER-BOTTOM: 1pt solid" valign="top" width="417">
																<p class="a" style="TEXT-INDENT: 0pt; TEXT-ALIGN: justify">
																		<span style="FONT-FAMILY: 宋体">测试过的稳定版本</span>
																</p>
														</td>
												</tr>
												<tr>
														<td style="BORDER-RIGHT: 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0pt; BORDER-LEFT: 1pt solid; WIDTH: 65.4pt; PADDING-TOP: 0pt; BORDER-BOTTOM: 1pt solid" valign="top" width="87">
																<p class="a" style="TEXT-INDENT: 0pt; TEXT-ALIGN: justify">1,0,0,14</p>
														</td>
														<td style="BORDER-RIGHT: 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0pt; BORDER-LEFT: medium none; WIDTH: 65.4pt; PADDING-TOP: 0pt; BORDER-BOTTOM: 1pt solid" valign="top" width="87">
																<p class="a" style="TEXT-INDENT: 0pt; TEXT-ALIGN: justify">99</p>
														</td>
														<td style="BORDER-RIGHT: 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0pt; BORDER-LEFT: medium none; WIDTH: 312.6pt; PADDING-TOP: 0pt; BORDER-BOTTOM: 1pt solid" valign="top" width="417">
																<p class="a" style="TEXT-INDENT: 0pt; TEXT-ALIGN: justify">fix some bug<span style="FONT-FAMILY: 宋体">，没有测试</span></p>
														</td>
												</tr>
												<tr>
														<td style="BORDER-RIGHT: 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0pt; BORDER-LEFT: 1pt solid; WIDTH: 65.4pt; PADDING-TOP: 0pt; BORDER-BOTTOM: 1pt solid" valign="top" width="87">
																<p class="a" style="TEXT-INDENT: 0pt; TEXT-ALIGN: justify"> </p>
														</td>
														<td style="BORDER-RIGHT: 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0pt; BORDER-LEFT: medium none; WIDTH: 65.4pt; PADDING-TOP: 0pt; BORDER-BOTTOM: 1pt solid" valign="top" width="87">
																<p class="a" style="TEXT-INDENT: 0pt; TEXT-ALIGN: justify"> </p>
														</td>
														<td style="BORDER-RIGHT: 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: medium none; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0pt; BORDER-LEFT: medium none; WIDTH: 312.6pt; PADDING-TOP: 0pt; BORDER-BOTTOM: 1pt solid" valign="top" width="417">
																<p class="a" style="TEXT-INDENT: 0pt; TEXT-ALIGN: justify"> </p>
														</td>
												</tr>
										</tbody>
								</table>
								<span> </span>
						</div>
						<table id="attachments">
								<tbody>
										<tr>
												<th>附件</th>
												<th>大小</th>
										</tr>
										<tr class="dark">
												<td>
														<a href="http://xyzboard.com/files/svn版本管理教程.rar">svn版本管理教程.rar</a>
												</td>
												<td>474.51 KB</td>
										</tr>
								</tbody>
						</table>
				</div>
		</div>
<img src ="http://www.blogjava.net/aawanghuan/aggbug/75840.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/aawanghuan/" target="_blank">萝卜青菜</a> 2006-10-18 10:43 <a href="http://www.blogjava.net/aawanghuan/articles/75840.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>