﻿<?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-往前走</title><link>http://www.blogjava.net/xlbdeshr/</link><description /><language>zh-cn</language><lastBuildDate>Thu, 30 Apr 2026 06:23:26 GMT</lastBuildDate><pubDate>Thu, 30 Apr 2026 06:23:26 GMT</pubDate><ttl>60</ttl><item><title>如何提高代码质量（管理篇）：代码复查</title><link>http://www.blogjava.net/xlbdeshr/archive/2011/12/11/366104.html</link><dc:creator>三石</dc:creator><author>三石</author><pubDate>Sun, 11 Dec 2011 13:29:00 GMT</pubDate><guid>http://www.blogjava.net/xlbdeshr/archive/2011/12/11/366104.html</guid><wfw:comment>http://www.blogjava.net/xlbdeshr/comments/366104.html</wfw:comment><comments>http://www.blogjava.net/xlbdeshr/archive/2011/12/11/366104.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xlbdeshr/comments/commentRss/366104.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xlbdeshr/services/trackbacks/366104.html</trackback:ping><description><![CDATA[<p>也许你是一位项目经理，也许你是一位项目骨干成员，或者开发小组长。在我发表&#8220;如何提高代码质量&#8221;的这一系统文章后，有许多网友都向我抱怨，说他无法把握整个项目组成员的代码质量。我想，这也是所有项目组普遍存在的问题吧，它通常表现为以下几个问题：<br />软件项目普遍存在的问题 </p>
<p>1）新手。任何项目组成员都不可避免地出现新手，他们往往是刚刚从大学毕业的学生。这些新手由于软件开发时间太短，往往技术不成熟，没有形成良好的开发习惯，所以编写代码质量较差，问题很多。他们常常成为项目组的&#8220;鸡肋&#8221;，用多了项目质量无法得到保证，不用则又人手不够。</p>
<p>2）人员变动。一个维护时间稍长一点儿的软件项目，人员变动是在所难免的。老员工被调动到其它项目去了，由新员工来接替他们的工作。在我的项目组中，人员调动达到了90%，唯一没有调走的就是我自己。新员工在接替老员工进行代码维护，甚至继续进行新的开发的时，由于对原有代码以及设计思路理解的偏差，也会出现大量的低劣代码。</p>
<p>3）不规范的代码编写。即使除去以上两个问题的影响，项目组成员编写的代码同样会出现问题。在项目开发之初，我们往往会制定一个代码编写的规范，但在项目开发过程中，许多成员往往会忽视这些代码规范而进行随意的编写。随意地代码编写会降低代码的可读性、可维护性和易变更性。那么，我们应当采用什么样的管理措施，保证代码的规范，提高代码的质量呢？</p>
<p>以上问题，也是我在项目开发中不断摸索和思考的问题，而一些有经验的项目经理给出了他们的解决之道，那就是&#8220;代码复查&#8221;。<br />什么是代码复查 </p>
<p>代码复查（Code Review），又叫&#8220;代码审查&#8221;，其基本思想就是，在开发人员编写完自己的代码后，由其他人来复查他写的代码，从而有效地发现代码中存在的缺陷。代码复查的一个基本理论就是，当我们越早发现代码存在的缺陷，我们解决缺陷的代价就越低。代码复查往往分成以下一个方面进行审查：</p>
<p>1）代码风格。在项目开发之初，我们往往会制定一个代码编写的规范，实际上，这个代码规范就包含了整个项目组的代码风格。由于软件开发人员的设计习惯不同，如果不统一代码风格，一个项目中的代码将五花八门，如变量和常量的命名、接口与实现类的注释、何时回车、怎样缩进等等。一个五花八门的设计风格，必将为日后的维护与改进带来困难。我们通过代码复查，一方面督促开发人员按照规范编写代码，另一方面也使开发人员自身形成良好的编程习惯。代码风格的审查，由于内容比较单一，我们常常可以通过一些代码复查的工具来自动完成，提高复查的效率。</p>
<p>2）重大缺陷。在一些关于代码复查的文章中，列出了一个常常的单子，描述了代码复查应当着重注意的重大缺陷，它们包括：存在SQL注入、易受跨站点脚本攻击、缓存区溢出、托管代码等等。项目组可以不断积累重大缺陷的审查项目，并在每次审查中逐一检查。重大缺陷审查是一个繁琐而细致的工作，如果能编写或使用一些审查软件，可以大大提高我们的审查效率。</p>
<p>3）设计逻辑与思路的审查。我认为，这部分的审查是代码复查中最核心、最有价值的部分。代码风格与重大缺陷的审查，虽然重要但简单而机械，可以通过软件自动检查；而设计逻辑与思路的审查，却是复杂而有深度的审查，需要有一定理论深度和编码经验的人才能完成，而且对新手尤其重要。前面提到，新手是任何项目组不可避免的问题。但遗憾的是，许多项目经理的办法是，只将一些简单而少量的工作交给新手完成，而将大量复杂的工作交给人数不多的那些老手来完成。这样的结果是，新手始终是新手，他们没有经过足够的锻炼；老手累死累活，无法指望新手予以分担工作。对于这个问题，我的办法是，通过代码复查，让老手去指导新手，让团队整体素质达到提高。具体办法就是，在新手完成编码以后，让老手去进行代码复查，指出新手的问题，指导新手设计。这样的过程最初可能需要重构，甚至重新编码。但经过这样的过程，新手将逐渐熟练，迅速成为老手，使整体团队素质提高。<br />代码复查的形式及优缺点 </p>
<p>经过以上的描述，我们可以发现代码复查的优点显而易见。首先，通过对代码风格与规范的审查，可以大大提高代码的可读性与可维护性。现在的软件，往往需要持续的维护与升级，人员变动也在所难免，因此代码的可读性与可维护性尤为重要。代码复查是一种鞭策，因为它的存在，督促着开发人员自觉地规范编码，养成好的编码习惯，提高代码质量。一个值得注意的问题是，如果你不去读别人的代码，永远不能深刻理解什么是可读的代码，而自己的代码不让别人去读并且反馈，也永远不知道自己的代码是否可读，即使你是一个编码多年的老手。代码复查恰恰解决了这个问题，值得你去尝试。</p>
<p>其次，代码复查是一次程序员之间的交流。新手可以有更多的机会向老手学习和指导，提高自身的设计水平（应当说这对于他们是非常宝贵的）；老手通过对新手的指导，整理和升华自己的设计思路与理论，同时也是对自己另一方面的锻炼与提高。另外，当你发现并指出了别人的一个问题以后，同时也是在警示自己不要犯同样的错误，这对审查与被审查者都是有益的。</p>
<p>虽然代码复查有如此突出的优点，但它的缺点也是非常显著的，那就是它需要付出如此巨大的代价。当一个人完成编码以后，还需要另外的人去解读和审查，并要求编程人员完成相应的修改，甚至重构和重写，这本身就是一种巨大的代价。这对于其本身就已经人员和时间非常紧张的软件开发项目来说，无疑是一种雪上加霜。时间、人力与代码质量，其本身就是鱼和熊掌不可兼得，关键是如何去权衡。正因为如此，不同公司选择了不同的代码复查策略。</p>
<p>前不久，我听了韩国一家大型游戏软件公司谈他们的代码复查。由于这家公司在软件开发时，时间和人力不是最关键和紧要的问题而代码质量，所以他们采用了一种严格的代码复查策略。严格的代码复查策略，一种方式是由专人进行代码复查。这种方式，在人员组织形式上，从软件开发人员中单独提出了一些经验丰富的人，组成一个代码复查小组，专职对其它软件开发小组进行代码复查。这种方式，代码复查小组以第三方的身份去复查各个项目组的代码，可以保证复查的公平公正，但压力无疑是巨大的（想想他们要查看那么多的代码）。</p>
<p>另一种方式，是以一个项目开发小组为单元进行代码互查，即一个人的代码，要为小组所有成员进行审查。这种方式毫无疑问，其付出的代价太大了。对这种方式的一种变通方式是将XP中的结对编程进行结合，然结对编程中的两个人相互进行代码互查。采用结对编程的项目组可以尝试这样方式，遗憾的是目前国内采用结对编程的项目组实在太少了。以上两种代码复查的最大弊病就是责任制，即审查者没有太多的责任去发现被审查者的问题，发现了问题对审查者没有任何好处，反倒与被审查者结怨；相反，审查者没有发现问题也不会担负任何责任。这样的结果就导致了代码复查流于形式：审查者草草审查，各方皆大欢喜，问题依然存在。</p>
<p>综上所述，虽然代码复查优势明显，但以上几种形式都不能为普通的软件开发团队所接受，就此我祭出了我的最佳实践：以小组为单位，组长责任制的代码复查形式。<br />代码复查的最佳实践 </p>
<p>代码复查是有代价的，甚至有时是巨大的，因此代码复查不宜频繁，最好一份代码只审查一次。同时，代码复查者应当对所审查的代码负有责任，即能够大胆地审查并指出被审查者的问题，并要求被审查者限期整改。与此同时，被审查后的代码如果还出现缺陷，审查者应当负有责任。只有满足了以上三个条件，代码复查才能为我们所接受。毫无疑问，项目开发小组的组长来担当此责任是最合适的。</p>
<p>一个项目开发组，根据其功能的划分，可以划分为多个小组，每个小组负责一个子模块。在这样一个小组中，小组长无疑是最有经验的开发人员，由他去负责组织和指导其它成员是合适的。小组成员不要太多，往往是3~5人。小组长不要分配太多的开发任务，他的主要工作是指导和监督小组其它成员进行开发。将他从繁重的开发任务中解脱出来，他可以有更多的精力去指导其他成员的设计，并且复查他们的代码。最终，他要对小组所有成员的代码质量负责，由项目经理或质量管理员进行抽查，检验其整体情况。</p>
<p>如果你只是一个小型项目，人员总共在5人之内，那么你不用这样分组。作为项目经理的你就是那个小组长，指导和监督你的成员。这样安排是因为在现代的管理理论中认为，一个人最多只能管理5个人，超过5个人就应当分组管理。而如果你在5人之内当然就不需要分开啦。</p>
<p>作为组长，你可以有效地审查和管理你的小组成员。同时，由于你负有责任，你也不得不认真有效地去完成审查工作。通过以上的组织形式，代码复查可以简便有效地在项目组中开展起来，从而从管理上有效地提高软件开发的代码质量。<br /><br />转自：<a href="http://summerbell.iteye.com/blog/601483">http://summerbell.iteye.com/blog/601483</a></p> <img src ="http://www.blogjava.net/xlbdeshr/aggbug/366104.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xlbdeshr/" target="_blank">三石</a> 2011-12-11 21:29 <a href="http://www.blogjava.net/xlbdeshr/archive/2011/12/11/366104.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Boolean类--学习问题</title><link>http://www.blogjava.net/xlbdeshr/archive/2011/12/03/365473.html</link><dc:creator>三石</dc:creator><author>三石</author><pubDate>Sat, 03 Dec 2011 09:28:00 GMT</pubDate><guid>http://www.blogjava.net/xlbdeshr/archive/2011/12/03/365473.html</guid><wfw:comment>http://www.blogjava.net/xlbdeshr/comments/365473.html</wfw:comment><comments>http://www.blogjava.net/xlbdeshr/archive/2011/12/03/365473.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xlbdeshr/comments/commentRss/365473.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xlbdeshr/services/trackbacks/365473.html</trackback:ping><description><![CDATA[<div><font style="background-color: #baefd2">直入正题。<br /><br />JDK1.6<br />
<h3>getBoolean</h3><pre>public static boolean <strong>getBoolean</strong>(<a title="java.lang 中的类" href="mk:@MSITStore:E:\01%20Java编程应用\03%20Java\03%20工具\JDK_API_1_6_zh_CN.CHM::/java/lang/String.html">String</a>&nbsp;name)</pre>
<dl>
<dd>当且仅当以参数命名的系统属性存在，且等于 <code>"true"</code> 字符串时，才返回 <code>true</code>。（从 Java<small><sup>TM</sup></small> 平台的 1.0.2 版本开始，字符串的测试不再区分大小写。）通过 <code>getProperty</code> 方法可访问系统属性，此方法由 <code>System</code> 类定义。 
<p>如果没有以指定名称命名的属性或者指定名称为空或 null，则返回 <code>false</code>。 <br /><br />源码：</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">1</span><img id="Codehighlighter1_50_283_Open_Image" onclick="this.style.display='none'; Codehighlighter1_50_283_Open_Text.style.display='none'; Codehighlighter1_50_283_Closed_Image.style.display='inline'; Codehighlighter1_50_283_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"><img id="Codehighlighter1_50_283_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_50_283_Closed_Text.style.display='none'; Codehighlighter1_50_283_Open_Image.style.display='inline'; Codehighlighter1_50_283_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">boolean</span><span style="color: #000000">&nbsp;getBoolean(String&nbsp;name)&nbsp;</span><span id="Codehighlighter1_50_283_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_50_283_Open_Text"><span style="color: #000000">{<br /></span><span style="color: #008080">2</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">boolean</span><span style="color: #000000">&nbsp;result&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">false</span><span style="color: #000000">;<br /></span><span style="color: #008080">3</span><span style="color: #000000"><img id="Codehighlighter1_96_164_Open_Image" onclick="this.style.display='none'; Codehighlighter1_96_164_Open_Text.style.display='none'; Codehighlighter1_96_164_Closed_Image.style.display='inline'; Codehighlighter1_96_164_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"><img id="Codehighlighter1_96_164_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_96_164_Closed_Text.style.display='none'; Codehighlighter1_96_164_Open_Image.style.display='inline'; Codehighlighter1_96_164_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">try</span><span style="color: #000000">&nbsp;</span><span id="Codehighlighter1_96_164_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_96_164_Open_Text"><span style="color: #000000">{<br /></span><span style="color: #008080">4</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;toBoolean(System.getProperty(name));<br /></span><span style="color: #008080">5</span><span style="color: #000000"><img id="Codehighlighter1_201_211_Open_Image" onclick="this.style.display='none'; Codehighlighter1_201_211_Open_Text.style.display='none'; Codehighlighter1_201_211_Closed_Image.style.display='inline'; Codehighlighter1_201_211_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"><img id="Codehighlighter1_201_211_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_201_211_Closed_Text.style.display='none'; Codehighlighter1_201_211_Open_Image.style.display='inline'; Codehighlighter1_201_211_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">catch</span><span style="color: #000000">&nbsp;(IllegalArgumentException&nbsp;e)&nbsp;</span><span id="Codehighlighter1_201_211_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_201_211_Open_Text"><span style="color: #000000">{<br /></span><span style="color: #008080">6</span><span style="color: #000000"><img id="Codehighlighter1_244_254_Open_Image" onclick="this.style.display='none'; Codehighlighter1_244_254_Open_Text.style.display='none'; Codehighlighter1_244_254_Closed_Image.style.display='inline'; Codehighlighter1_244_254_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"><img id="Codehighlighter1_244_254_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_244_254_Closed_Text.style.display='none'; Codehighlighter1_244_254_Open_Image.style.display='inline'; Codehighlighter1_244_254_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">catch</span><span style="color: #000000">&nbsp;(NullPointerException&nbsp;e)&nbsp;</span><span id="Codehighlighter1_244_254_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_244_254_Open_Text"><span style="color: #000000">{<br /></span><span style="color: #008080">7</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br /></span><span style="color: #008080">8</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;result;<br /></span><span style="color: #008080">9</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span></div>
<p><br />result&nbsp;<span style="color: #000000">=</span><span style="color: #000000">&nbsp;toBoolean(System.getProperty(name)); //当且仅当以参数命名的系统属性存在，且等于 <code>"true"</code> 字符串时，才返回 <code>true；<br /><br />测试：</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080">&nbsp;1</span><img id="Codehighlighter1_0_95_Open_Image" onclick="this.style.display='none'; Codehighlighter1_0_95_Open_Text.style.display='none'; Codehighlighter1_0_95_Closed_Image.style.display='inline'; Codehighlighter1_0_95_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"><img id="Codehighlighter1_0_95_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_0_95_Closed_Text.style.display='none'; Codehighlighter1_0_95_Open_Image.style.display='inline'; Codehighlighter1_0_95_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"><span id="Codehighlighter1_0_95_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff">/**&nbsp;*/</span><span id="Codehighlighter1_0_95_Open_Text"><span style="color: #008000">/**</span><span style="color: #008000"><br /></span><span style="color: #008080">&nbsp;2</span><span style="color: #008000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;*&nbsp;测试Boolean类getBoolean(String&nbsp;name)方法<br /></span><span style="color: #008080">&nbsp;3</span><span style="color: #008000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;*&nbsp;</span><span style="color: #808080">@author</span><span style="color: #008000">&nbsp;dood<br /></span><span style="color: #008080">&nbsp;4</span><span style="color: #008000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;*&nbsp;</span><span style="color: #808080">@version</span><span style="color: #008000">&nbsp;1.0<br /></span><span style="color: #008080">&nbsp;5</span><span style="color: #008000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;*&nbsp;创建时间：2011-12-2<br /></span><span style="color: #008080">&nbsp;6</span><span style="color: #008000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />&nbsp;</span><span style="color: #008000">*/</span></span><span style="color: #000000"><br /></span><span style="color: #008080">&nbsp;7</span><span style="color: #000000"><img id="Codehighlighter1_122_307_Open_Image" onclick="this.style.display='none'; Codehighlighter1_122_307_Open_Text.style.display='none'; Codehighlighter1_122_307_Closed_Image.style.display='inline'; Codehighlighter1_122_307_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"><img id="Codehighlighter1_122_307_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_122_307_Closed_Text.style.display='none'; Codehighlighter1_122_307_Open_Image.style.display='inline'; Codehighlighter1_122_307_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;BooleanTest&nbsp;</span><span id="Codehighlighter1_122_307_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_122_307_Open_Text"><span style="color: #000000">{<br /></span><span style="color: #008080">&nbsp;8</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;<br /></span><span style="color: #008080">&nbsp;9</span><span style="color: #000000"><img id="Codehighlighter1_166_305_Open_Image" onclick="this.style.display='none'; Codehighlighter1_166_305_Open_Text.style.display='none'; Codehighlighter1_166_305_Closed_Image.style.display='inline'; Codehighlighter1_166_305_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"><img id="Codehighlighter1_166_305_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_166_305_Closed_Text.style.display='none'; Codehighlighter1_166_305_Open_Image.style.display='inline'; Codehighlighter1_166_305_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;main(String[]&nbsp;args)&nbsp;</span><span id="Codehighlighter1_166_305_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_166_305_Open_Text"><span style="color: #000000">{<br /></span><span style="color: #008080">10</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Boolean&nbsp;bool&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;Boolean.valueOf(</span><span style="color: #0000ff">true</span><span style="color: #000000">);<br /></span><span style="color: #008080">11</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.setProperty(</span><span style="color: #000000">"</span><span style="color: #000000">isTrue</span><span style="color: #000000">"</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">true</span><span style="color: #000000">"</span><span style="color: #000000">);<br /></span><span style="color: #008080">12</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(bool.getBoolean(</span><span style="color: #000000">"</span><span style="color: #000000">isTrue</span><span style="color: #000000">"</span><span style="color: #000000">));&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">true</span><span style="color: #008000"><br /></span><span style="color: #008080">13</span><span style="color: #008000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br /></span><span style="color: #008080">14</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="color: #000000"><br /></span><span style="color: #008080">15</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div>
<p><br /><br /><br /></code><br /></span><br />&nbsp;</p></dd></dl></font></div><img src ="http://www.blogjava.net/xlbdeshr/aggbug/365473.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xlbdeshr/" target="_blank">三石</a> 2011-12-03 17:28 <a href="http://www.blogjava.net/xlbdeshr/archive/2011/12/03/365473.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>什么是事务(Transaction)</title><link>http://www.blogjava.net/xlbdeshr/archive/2009/03/21/261201.html</link><dc:creator>三石</dc:creator><author>三石</author><pubDate>Sat, 21 Mar 2009 07:00:00 GMT</pubDate><guid>http://www.blogjava.net/xlbdeshr/archive/2009/03/21/261201.html</guid><wfw:comment>http://www.blogjava.net/xlbdeshr/comments/261201.html</wfw:comment><comments>http://www.blogjava.net/xlbdeshr/archive/2009/03/21/261201.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xlbdeshr/comments/commentRss/261201.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xlbdeshr/services/trackbacks/261201.html</trackback:ping><description><![CDATA[<p><span style="color: #ff0000">　&nbsp;&nbsp; 什么叫事务？ 这些就是数据库特有的术语了。解释：就是把多件事情当做一件事情来处理。也就是大家同在一条船上，要活一起活，要over一起over ！</span></p>
<p><span style="color: #ff0000">事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。事务通常由高级数据库操纵语言或编程语言（如SQL，C++或Java）书写的用户程序的执行所引起，并用形如begin transaction和end transaction语句（或函数调用）来界定。事务由事务开始(begin transaction)和事务结束(end transaction)之间执行的全体操作组成。</span></p>
<p><span style="color: #ff0000">例如：在关系数据库中，一个事务可以是一条SQL语句，一组SQL语句或整个程序。</span></p>
<p><span style="color: #ff0000">事务是恢复和并发控制的基本单位。</span></p>
<p><span style="color: #ff0000">事务应该具有4个属性：原子性、一致性、隔离性、持续性。这四个属性通常称为ACID特性。</span></p>
<p><span style="color: #ff0000">原子性（atomicity）。一个事务是一个不可分割的工作单位，事务中包括的诸操作要么都做，要么都不做。</span></p>
<p><span style="color: #ff0000">一致性（consistency）。事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。</span></p>
<p><span style="color: #ff0000">隔离性（isolation）。一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的，并发执行的各个事务之间不能互相干扰。</span></p>
<p><span style="color: #ff0000">持久性（durability）。持续性也称永久性（permanence），指一个事务一旦提交，它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。</span></p>
<font style="background-color: #cce8cf">
<p><br />
<span style="color: #ff0000">　　　我为什么要使用事务？ 这里再举个很俗很俗的例子：</span></p>
<p><span style="color: #ff0000">　　　　　我到银行存钱，于是有这么几个步骤： <br />
　　　　　　 1、把钱交给工作人员；2、工作人员填单；3、将单子给我签字；4、工作人员确认并输入电脑。</span></p>
<p><span style="color: #ff0000">　　　要是，要是我把钱交给工作人员之后，进行到3我签字了。那哥们突然心脏病发作，over掉了，那，我的钱还没有输入电脑，但我却交了钱又签字确认了，而并没有其他任何记录。我岂不是要亏死了？？？我的血汗钱啊！赶紧退给我！！</span></p>
<p><span style="color: #ff0000">　　　于是，在数据库里产生了这么一个术语：事务(Transaction)，也就是要么成功，要么失败，并恢复原状。<br />
　　 <br />
　　　还是写程序把：</span></p>
<p><span style="color: #ff0000">　　　Create Proc sp我去存款(@M Money , @iOperator Int)<br />
　　　As<br />
　　　Begin<br />
　　　　Declare @i int</span></p>
<p><span style="color: #ff0000">　　　　Begin Tran　　　　　　　　　　　--激活事务<br />
　　　　　Exec @i=sp交钱 @m,@iOperator<br />
　　　　　if @i&lt;&gt;0　　　　　　　　　　　--这里一般用系统错误号 @@Error。 我这里为了举例子没有用到。需要根据实际情况。<br />
　　　　　begin<br />
　　　　　　Rollback Tran　　　　　　　　　　　　　　　　　　　--回滚事务<br />
　　　　　　RaisError ('银行的窗口太少了，我懒得排队，不交了！：（ ', 16, 1) with Log　--记录日志<br />
　　　　　　Return -1　　　　　　　　　　　　　　　　　　　　　--返回错误号 <br />
　　　　　end</span></p>
<p><span style="color: #ff0000">　　　　　Exec @i=sp填单 @m,@iOperator<br />
　　　　　if @i&lt;&gt;0<br />
　　　　　begin<br />
　　　　　　Rollback Tran　　　　　　　　　　　　　　　　　　　--回滚事务<br />
　　　　　　RaisError ('银行的哥们打印机出了点毛病，打印不出单子来，把钱退回来给我吧？？', 16, 1) with Log <br />
　　　　　　Return -2　　　　　　　　　　　　　　　　　　　　　<br />
　　　　　end</span></p>
<p><span style="color: #ff0000">　　　　　Exec @i=sp签字 @m<br />
　　　　　if @i&lt;&gt;0<br />
　　　　　begin<br />
　　　　　　Rollback Tran　　　　　　　　　　　　　　　　　　　--回滚事务<br />
　　　　　　RaisError ('我 靠？什么烂银行，换了3支笔都写不出水来！！老子不存了！！不签！', 16, 1) with Log　<br />
　　　　　　Return -3　　　　　　　　　　　　　　　　　　　　　<br />
　　　　　end</span></p>
<p><span style="color: #ff0000">　　　　　Exec @i=sp输入电脑 @m,@iOperator<br />
　　　　　if @i&lt;&gt;0<br />
　　　　　begin<br />
　　　　　　Rollback Tran　　　　　　　　　　　　　　　　　　　--回滚事务<br />
　　　　　　RaisError ('什么意思？磁盘空间已满？好了好了，把钱给我，我到旁边的这家银行！', 16, 1) with Log　<br />
　　　　　　Return -4　　　　　　　　　　　　　　　　　　　　　<br />
　　　　　end<br />
　<br />
　　　　Commit Tran　　　　　　　 --提交事务<br />
　　　　Return 0<br />
　　End</span></font></p>
 <img src ="http://www.blogjava.net/xlbdeshr/aggbug/261201.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xlbdeshr/" target="_blank">三石</a> 2009-03-21 15:00 <a href="http://www.blogjava.net/xlbdeshr/archive/2009/03/21/261201.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java购物车</title><link>http://www.blogjava.net/xlbdeshr/archive/2009/03/18/260586.html</link><dc:creator>三石</dc:creator><author>三石</author><pubDate>Wed, 18 Mar 2009 13:22:00 GMT</pubDate><guid>http://www.blogjava.net/xlbdeshr/archive/2009/03/18/260586.html</guid><wfw:comment>http://www.blogjava.net/xlbdeshr/comments/260586.html</wfw:comment><comments>http://www.blogjava.net/xlbdeshr/archive/2009/03/18/260586.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xlbdeshr/comments/commentRss/260586.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xlbdeshr/services/trackbacks/260586.html</trackback:ping><description><![CDATA[下面是实例的源码!注释已经很清楚了[JDK1.5 或者JDK1.5以上]<br />
<br />
CartItems 如下<br />
<br />
&nbsp;public class CartItems {<br />
&nbsp;&nbsp;&nbsp; //商品的信息<br />
&nbsp;private Product product=new Product();<br />
&nbsp;&nbsp;&nbsp; //商品的数量<br />
&nbsp;private int namount=0;<br />
&nbsp;public CartItems(Product product,int namount)<br />
&nbsp;{<br />
&nbsp; this.product=product;<br />
&nbsp; this.namount=namount;<br />
&nbsp;}<br />
&nbsp;public Product getProduct() {<br />
&nbsp; return product;<br />
&nbsp;}<br />
&nbsp;public void setProduct(Product product) {<br />
&nbsp; this.product = product;<br />
&nbsp;}<br />
&nbsp;public int getNamount() {<br />
&nbsp; return namount;<br />
&nbsp;}<br />
&nbsp;public void setNamount(int namount) {<br />
&nbsp; this.namount = namount;<br />
&nbsp;}<br />
}<br />
&nbsp;<br />
<br />
action如下<br />
<br />
&nbsp; //得到商品的编号<br />
<br />
&nbsp; String productId=request.getParameter("productId");<br />
<br />
&nbsp;//根据商品的编号查询该商品的信息 返回商品的对象Product <br />
&nbsp; Product product=this.productBo.getProductInfo(new Integer(Integer.parseInt(productId)));<br />
&nbsp; //创建HttpSession的对象<br />
&nbsp; HttpSession session=request.getSession();<br />
&nbsp; //判读Map集合里面是否 存在着对象 就是说map里面是否已经添加了商品<br />
&nbsp; Map&lt;Integer,CartItems&gt; cart=(Map&lt;Integer, CartItems&gt;) session.getAttribute("cart");<br />
&nbsp; if (null==cart) {<br />
<br />
&nbsp; //如果没有添加就创建一个HashMap<br />
&nbsp;&nbsp; cart=new HashMap&lt;Integer, CartItems&gt;();<br />
&nbsp;&nbsp; session.setAttribute("cart", cart);<br />
&nbsp; }<br />
&nbsp; //如果Map集合里面存在着对象 就根据对象的编号得到该对象<br />
&nbsp; CartItems items=cart.get(product.getProductId());<br />
&nbsp; if (null==items) {<br />
&nbsp;&nbsp; //如果没有商品就将商品添加到里面<br />
&nbsp;&nbsp; cart.put(product.getProductId(), new CartItems(product,1));<br />
&nbsp; }<br />
&nbsp; else<br />
&nbsp; {<br />
&nbsp;&nbsp; //如果存在商品数量+1<br />
&nbsp;&nbsp; items.setNamount(items.getNamount()+1);<br />
&nbsp; }<br />
&nbsp; List&lt;CartItems&gt; arrayList=new ArrayList&lt;CartItems&gt;();<br />
&nbsp;&nbsp;&nbsp; //将map里面的商品对象遍历出来<br />
&nbsp; for (Map.Entry&lt;Integer, CartItems&gt; entry:cart.entrySet()) {<br />
&nbsp; <br />
&nbsp;&nbsp; CartItems cartItems=entry.getValue();<br />
&nbsp;&nbsp; <br />
&nbsp;&nbsp; arrayList.add(cartItems);<br />
&nbsp; }<br />
&nbsp; request.setAttribute("arrayList",arrayList);<br />
<br />
&nbsp; //发送到遍历的页面<br />
&nbsp; return mapping.findForward("success");<br />
<img src ="http://www.blogjava.net/xlbdeshr/aggbug/260586.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xlbdeshr/" target="_blank">三石</a> 2009-03-18 21:22 <a href="http://www.blogjava.net/xlbdeshr/archive/2009/03/18/260586.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[深入浅出Hibernate笔记] Oracle中的大字段 Blob/Clob</title><link>http://www.blogjava.net/xlbdeshr/archive/2009/03/16/260004.html</link><dc:creator>三石</dc:creator><author>三石</author><pubDate>Mon, 16 Mar 2009 06:09:00 GMT</pubDate><guid>http://www.blogjava.net/xlbdeshr/archive/2009/03/16/260004.html</guid><wfw:comment>http://www.blogjava.net/xlbdeshr/comments/260004.html</wfw:comment><comments>http://www.blogjava.net/xlbdeshr/archive/2009/03/16/260004.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xlbdeshr/comments/commentRss/260004.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xlbdeshr/services/trackbacks/260004.html</trackback:ping><description><![CDATA[<p><font style="background-color: #cce8cf">数据库中提供了两种字段类型 Blob&nbsp; 和 Clob 用于存储大型字符串或二进制数据（如图片）。</font></p>
<p><font style="background-color: #cce8cf">Blob 采用单字节存储，适合保存二进制数据，如图片文件。<br />
Clob 采用多字节存储，适合保存大型文本数据。</font></p>
<p><font style="background-color: #cce8cf">Oracle中处理BLOB/CLOB字段的方式比较特别，所以需要特别注意下面两点：</font></p>
<p><font style="background-color: #cce8cf">1. 在Oracle JDBC中采用流机制对 BLOB/CLOB 进行读写操作，所以要注意不能在批处理中读写 BLOB/CLOB字段，否则将出现<br />
Stream type cannot be used in batching 异常。</font></p>
<p><font style="background-color: #cce8cf">2. Oracle BLOB/CLOB 字段本身拥有一个游标（cursor），JDBC通过游标对Blob/Clob字段进行操作，在Blob/Clob字段创建之前，无法获取其游标句柄，会出现<br />
Connection reset by peer: socket write error 异常。</font></p>
<p><font style="background-color: #cce8cf">正确的做法是：首先创建一个空 Blob/Clob 字段，再从这个空 Blob/Clob字段获取游标，例如下面的代码：</font></p>
<p><font style="background-color: #cce8cf">&nbsp;PreparedStatement ps&nbsp; =&nbsp; conn.prepareStatement( " insert into PICTURE(image,resume) values(?,?) " );<br />
&nbsp;//&nbsp; 通过oralce.sql.BLOB/CLOB.empty_lob()构造空Blob/Clob对象 <br />
&nbsp;ps.setBlob( 1 ,oracle.sql.BLOB.empty_lob());<br />
ps.setClob( 2 ,oracle.sql.CLOB.empty_lob());</font></p>
<p><font style="background-color: #cce8cf">ps.excuteUpdate();<br />
ps.close();</font></p>
<p><font style="background-color: #cce8cf">&nbsp;//&nbsp; 再次对读出Blob/Clob句柄 <br />
&nbsp;ps&nbsp; =&nbsp; conn.prepareStatement( " select image,resume from PICTURE where id=? for update " );<br />
ps.setInt( 1 , 100 );</font></p>
<p><font style="background-color: #cce8cf">ResultSet rs&nbsp; =&nbsp; ps.executeQuery();<br />
rs.next();</font></p>
<p><font style="background-color: #cce8cf">oracle.sql.BLOB imgBlob&nbsp; =&nbsp; (oracle.sql.BLOB)rs.getBlob( 1 );<br />
oracle.sql.CLOB resClob&nbsp; =&nbsp; (oracle.sql.CLOB)rs.getClob( 2 );</font></p>
<p><font style="background-color: #cce8cf">&nbsp;//&nbsp; 将二进制数据写入Blob <br />
&nbsp;FileInputStream inStream&nbsp; =&nbsp;&nbsp; new&nbsp; FileInputStream( " c://image.jpg " );<br />
OutputStream outStream&nbsp; =&nbsp; imgBlob.getBinaryOutputStream();</font></p>
<p><font style="background-color: #cce8cf">&nbsp;byte [] buf&nbsp; =&nbsp;&nbsp; new&nbsp;&nbsp; byte [ 10240 ];<br />
&nbsp;int&nbsp; len;<br />
&nbsp;while (len = inStream.read(buf) &gt; 0 ) {<br />
&nbsp; outStream.write(buf, 0 ,len);<br />
} <br />
inStream.close();<br />
outStream.cloese();</font></p>
<p><font style="background-color: #cce8cf">&nbsp;//&nbsp; 将字符串写入Clob <br />
&nbsp;resClob.putString( 1 , " this is a clob " );</font></p>
<p><font style="background-color: #cce8cf">&nbsp;//&nbsp; 再将Blob/Clob字段更新到数据库 <br />
&nbsp;ps&nbsp; =&nbsp; conn.prepareStatement( " update PICTURE set image=? and resume=? where id=? " );<br />
ps.setBlob( 1 ,imgBlob);<br />
ps.setClob( 2 ,resClob);<br />
ps.setInt( 3 , 100 );</font></p>
<p><font style="background-color: #cce8cf">ps.executeUpdate();<br />
ps.close();</font></p>
<img src ="http://www.blogjava.net/xlbdeshr/aggbug/260004.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xlbdeshr/" target="_blank">三石</a> 2009-03-16 14:09 <a href="http://www.blogjava.net/xlbdeshr/archive/2009/03/16/260004.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>