﻿<?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-stone2083-随笔分类-java</title><link>http://www.blogjava.net/stone2083/category/28155.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 18 Nov 2008 11:54:02 GMT</lastBuildDate><pubDate>Tue, 18 Nov 2008 11:54:02 GMT</pubDate><ttl>60</ttl><item><title>ibatis支持枚举类型</title><link>http://www.blogjava.net/stone2083/archive/2008/11/05/238899.html</link><dc:creator>stone2083</dc:creator><author>stone2083</author><pubDate>Wed, 05 Nov 2008 15:08:00 GMT</pubDate><guid>http://www.blogjava.net/stone2083/archive/2008/11/05/238899.html</guid><wfw:comment>http://www.blogjava.net/stone2083/comments/238899.html</wfw:comment><comments>http://www.blogjava.net/stone2083/archive/2008/11/05/238899.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stone2083/comments/commentRss/238899.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stone2083/services/trackbacks/238899.html</trackback:ping><description><![CDATA[很多应用中，数据库表结构都会存在一些状态字段。在关系性数据库中，一般会用VARCHAR类型。使用ibatis的应用，传统做法，往往会使用String的属性，与之对应。<br />
例如一张member表，结构设计如下：<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/stone2083/java/db_member.png" height="39" width="805" /><br />
其中status为状态字段。<br />
<br />
ibatis中，使用class MemberPO 与之mapping，设计往往如下：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;MemberPO&nbsp;</span><span style="color: #0000ff;">implements</span><span style="color: #000000;">&nbsp;Serializable&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;Integer&nbsp;id;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;String&nbsp;loginId;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;String&nbsp;password;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;String&nbsp;name;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;String&nbsp;profile;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;Date&nbsp;gmtCreated;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;Date&nbsp;gmtModified;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;String&nbsp;status;<br />
<br />
&nbsp;&nbsp;&nbsp; </span><span style="color: #008000;">//</span><span style="color: #008000;">getter/setters<img src="http://www.blogjava.net/Images/dot.gif" alt="" /></span><br />
<span style="color: #000000;">｝</span></div>
<br />
缺点：<br />
1）不直观，没人会知道status具体有哪些值。在缺乏文档，并且历史悠久的系统中，只能使用&#8220;select distinct(status) from member&#8221;，才能得到想要的数据。如果是在千万级数据中，代价太大了；<br />
2）类型不安全，如果有人不小心拼写错误，将会导致错误状态。假设上面列子中，status只允许ENABLED／DISABLED，如果一不小心，memberPO.setStatus("ENABLEDD"),那么将会造成脏数据。<br />
<br />
既然jdk5之后，引入了enum，是否可以让ibatis支持enum类型呢？事实上，最新的ibatis版本，已经支持enum类型（本文使用的是2.3.4.726版本－－mvn repsitory上最新的版本）。<br />
以上代码可以修改成：<br />
1）Status类：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">&nbsp;Status&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">/**</span><span style="color: #008000;">&nbsp;enabled&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;ENABLED,<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">/**</span><span style="color: #008000;">&nbsp;disabled&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;DISABLED;<br />
<br />
｝</span></div>
2）MemberPO类：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;MemberPO&nbsp;</span><span style="color: #0000ff;">implements</span><span style="color: #000000;">&nbsp;Serializable&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;Integer&nbsp;id;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;String&nbsp;loginId;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;String&nbsp;password;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;String&nbsp;name;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;String&nbsp;profile;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;Date&nbsp;gmtCreated;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;Date&nbsp;gmtModified;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;Status&nbsp;status;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">getter/setters<img src="http://www.blogjava.net/Images/dot.gif" alt="" /></span><span style="color: #008000;"><br />
</span><span style="color: #000000;">｝</span></div>
<br />
除此之外，其他均无需改动。<br />
为什么呢？ibatis如何知道VARCHAR／Enum的mapping呢？<br />
看过ibatis源码的同学，知道，ibatis是通过jdbcType/javaType得到对应的TypeHandler做mapping处理的。ibatis有基本类型的TypeHandler，比如StringTypeHandler,IntegerTypeHandler等等。在最新版本中，为了支持enum，增加了一个EnumTypeHandler。<br />
<br />
并且在TypeHandlerFactory中，加了对enum类型的判断，请看：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;TypeHandler&nbsp;getTypeHandler(Class&nbsp;type,&nbsp;String&nbsp;jdbcType)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;Map&nbsp;jdbcHandlerMap&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(Map)&nbsp;typeHandlerMap.get(type);<br />
&nbsp;&nbsp;&nbsp;&nbsp;TypeHandler&nbsp;handler&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(jdbcHandlerMap&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;handler&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(TypeHandler)&nbsp;jdbcHandlerMap.get(jdbcType);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(handler&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;handler&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(TypeHandler)&nbsp;jdbcHandlerMap.get(</span><span style="color: #0000ff;">null</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(handler&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;type&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;Enum.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">.isAssignableFrom(type))&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;handler&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;EnumTypeHandler(type);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;handler;<br />
&nbsp;&nbsp;}</span></div>
ibatis使用了取巧的方法，当取不到基本类型的handler时候，判断javaType是否是Enum类型－－<span style="color: #000000;">Enum.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">.isAssignableFrom(type)，如果是，则使用</span><span style="color: #000000;"> EnumTypeHandler进行mapping处理。<br />
<br />
为什么说它取巧，原因是早期ibatis设计过程中，自定义的接口无法得到具体的java class type。故早期的ibatis中，要实现对enmu的支持，非常苦难。而新版本中，为了达到这个功能，作者直接修改了TypeHandlerFactory的实现，打了一个补丁，如下：<br />
</span>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(handler&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;type&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;Enum.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">.isAssignableFrom(type))&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;handler&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;EnumTypeHandler(type);<br />
}</span></div>
这个设计有悖于和早前的设计思想。早期，TypeHandler都是通过public void register(Class type, String jdbcType, TypeHandler handler)方式事先注册到factory中的，而这次，是在运行期，通过new方法动态得到<span style="color: #000000;">EnumTypeHandler。<br />
当然，新版本ibatis能支持enum，已经是一件开心的事情了。<br />
<br />
Status枚举类除了描述状态，就足够了吗？回想起很多应用，我是做web开发的，在view层（velocity，jsp，等），见多了类似这样的代码：<br />
</span>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">#if($member.getStatus()==Status.ENABLED)开通#elseif($member.getStatus()==Status.DISABLED)关闭#end<br />
<br />
</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">select</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">option&nbsp;</span><span style="color: #ff0000;">value</span><span style="color: #0000ff;">="ENABLED"</span><span style="color: #ff0000;">&nbsp;#if($member.getStatus()</span><span style="color: #0000ff;">==Status.ENABLED)&nbsp;</span><span style="color: #ff0000;">selected</span><span style="color: #0000ff;">="selected"</span><span style="color: #ff0000;">#end&nbsp;</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">开通</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">option</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">option&nbsp;</span><span style="color: #ff0000;">value</span><span style="color: #0000ff;">="DISABLED"</span><span style="color: #ff0000;">&nbsp;#if($member.getStatus()</span><span style="color: #0000ff;">==Status.DISABLED)&nbsp;</span><span style="color: #ff0000;">selected</span><span style="color: #0000ff;">="selected"</span><span style="color: #ff0000;">#end&nbsp;</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">关闭</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">option</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">select</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
<br />
</span></div>
web层需要多少个页面，就需要维护多少份这样的代码；以后每添加／删除一种状态，多个地方都需要修改，还要担心逻辑不一致。<br />
<br />
而事实上，关于状态的信息描述，按照职责分，就应该由枚举类来维护：<br />
1）制定一个接口，<span style="color: #000000;">EnumDescription.java<br />
</span>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">interface</span><span style="color: #000000;">&nbsp;EnumDescription&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;String&nbsp;getDescription();<br />
<br />
}</span></div>
2）写一个ResourceBundleUtil.java，通过Properties文件得到描述信息：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;ResourceBundleUtil&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;ResourceBundle&nbsp;resourceBundle;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;ResourceBundleUtil(String&nbsp;resource)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.resourceBundle&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;ResourceBundle.getBundle(resource);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;ResourceBundleUtil(String&nbsp;resource,&nbsp;Locale&nbsp;locale)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.resourceBundle&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;ResourceBundle.getBundle(resource,&nbsp;locale);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;String&nbsp;getProperty(String&nbsp;key)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;resourceBundle.getString(key);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
}</span></div>
3）Status等枚举类实现<span style="color: #000000;">EnumDescription：<br />
</span>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">enum</span><span style="color: #000000;">&nbsp;Status&nbsp;</span><span style="color: #0000ff;">implements</span><span style="color: #000000;">&nbsp;EnumDescription&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">/**</span><span style="color: #008000;">&nbsp;enabled&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;ENABLED,<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">/**</span><span style="color: #008000;">&nbsp;disabled&nbsp;</span><span style="color: #008000;">*/</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;DISABLED;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;ResourceBundleUtil&nbsp;util&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;ResourceBundleUtil(Status.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">.getName());<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;String&nbsp;getDescription()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;util.getProperty(</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.toString());<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
}</span></div>
<br />
这样，有什么好处：<br />
1）通过Properties文件，支持国际化。<br />
2）描述信息统一由自己来维护，方便维护，并且显示层逻辑简化，如：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">$member.getStatus().getDescription()<br />
<br />
</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">select</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;#foreach($status&nbsp;in&nbsp;$Status.values())<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">option&nbsp;</span><span style="color: #ff0000;">value</span><span style="color: #0000ff;">="$status"</span><span style="color: #ff0000;">&nbsp;#if($member.getStatus()</span><span style="color: #0000ff;">==$status)selected="selected"#end&nbsp;</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">$status.getDescription()</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">option</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;#end<br />
</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">select</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span></div>
<span style="color: #000000;"><br />
##############################################################################<br />
那么使用老版本ibatis的客户怎么办呢？就像我们公司使用ibatis 2.3.0，难道只能眼馋着？解决方案：<br />
1）升级到最新版本。 ：）<br />
2）ibatis提供了TypeHandler/TypeHandlerCallback接口，针对每种枚举类型，写相应的TypeHandler/TypeHandlerCallback的接口实现即可－－工作量大，重复的劳动力。<br />
主要是早期ibatis TypeHandler无法得到javaType类型，无法从jdbc value转成对应的枚举。在我看来，TypeHandler是作mapping用的，它至少有权知道javaType。<br />
3）实现伪枚举类型（允许继承）来实现状态类型安全，而抛弃jdk5的方式－－不方便日后升级。<br />
<br />
<br />
不知道大家是否还有更好的方案？<br />
<br />
本文涉及演示代码如下：<br />
</span><span style="color: #000000;"><a href="http://www.blogjava.net/Files/stone2083/java/ibatis-enum.zip" title="演示代码">演示代码</a><br />
workspace file encoding：utf-8<br />
build tool: maven<br />
repository:spring/2.5.5;ibatis/2.3.4.726</span><br />
<img src ="http://www.blogjava.net/stone2083/aggbug/238899.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stone2083/" target="_blank">stone2083</a> 2008-11-05 23:08 <a href="http://www.blogjava.net/stone2083/archive/2008/11/05/238899.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ajax原理简介以及简单demo演示</title><link>http://www.blogjava.net/stone2083/archive/2008/09/21/230278.html</link><dc:creator>stone2083</dc:creator><author>stone2083</author><pubDate>Sun, 21 Sep 2008 11:05:00 GMT</pubDate><guid>http://www.blogjava.net/stone2083/archive/2008/09/21/230278.html</guid><wfw:comment>http://www.blogjava.net/stone2083/comments/230278.html</wfw:comment><comments>http://www.blogjava.net/stone2083/archive/2008/09/21/230278.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stone2083/comments/commentRss/230278.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stone2083/services/trackbacks/230278.html</trackback:ping><description><![CDATA[如今web应用上，ajax技术是大行其道。<br />
ajax框架层出不穷，prototype，dojo，jquery，mootools，dwr，buffalo，ext，yui，spry。。。<br />
ajax框架的出现，在提升开发生产效率的同时，也让不少同学不明其内在原理，仅仅成为了某些框架的使用者。<br />
（对于产品生产是好事，对于技术追求是坏事）<br />
<br />
本文不涉及任何ajax框架的使用，本文仅通过一个模拟需求，在不使用任何ajax框架的前提下，以demo演示的方式，<br />
向大家介绍ajax的原理以及应用场景。<br />
<br />
ajax全称是：<a title="AsynchronousJavaScript And XML " href="http://en.wikipedia.org/wiki/AJAX">Asynchronous JavaScript And XML。</a><br />
其本意是，通过javascript技术（JavaScript），通过异步http请求方式（Asynchronous），得到XML文本内容（XML）之后，通过javascript技术局部刷新web页面内容。<br />
从广义的概念看，只要符合&#8220;异步请求，局部刷新web页面&#8221;的技术，都可以成为ajax。<br />
未必一定要使用javascript，一般情况下，大多数client端脚本代码都可以；返回内容也未必一定要是xml，目前json格式，更为流行。<br />
<br />
如何异步请求内容呢？<br />
以javascript代码作演示，如下：<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">&nbsp;xmlhttpPost(url,func)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">var</span><span style="color: rgb(0, 0, 0);">&nbsp;xmlHttpReq&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">false</span><span style="color: rgb(0, 0, 0);">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">var</span><span style="color: rgb(0, 0, 0);">&nbsp;self&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">&nbsp;Mozilla/Safari</span><span style="color: rgb(0, 128, 0);"><br />
</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">&nbsp;(window.XMLHttpRequest)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.xmlHttpReq&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;XMLHttpRequest();<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">&nbsp;IE</span><span style="color: rgb(0, 128, 0);"><br />
</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">&nbsp;(window.ActiveXObject)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.xmlHttpReq&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;ActiveXObject(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Microsoft.XMLHTTP</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;self.xmlHttpReq.open('POST',&nbsp;url,&nbsp;</span><span style="color: rgb(0, 0, 255);">true</span><span style="color: rgb(0, 0, 0);">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;self.xmlHttpReq.setRequestHeader('Content</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">Type',&nbsp;'application</span><span style="color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 0);">x</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">www</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">form</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">urlencoded');<br />
&nbsp;&nbsp;&nbsp;&nbsp;self.xmlHttpReq.onreadystatechange&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">&nbsp;(self.xmlHttpReq.readyState&nbsp;</span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;func(self.xmlHttpReq.responseText);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;self.xmlHttpReq.send(</span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">);<br />
&nbsp;&nbsp;}</span></div>
参数一，url：表明异步请求的资源地址<br />
参数二，func：表明请求结束后，采用什么函数对请求结果内容进行回调处理<br />
<br />
其实，这一个js代码，就诠释了ajax的全部含义－－异步请求资源，将得到的资源内容，使用指定的function进行处理。<br />
所以，ajax很简单，大家千万别被如今层出不穷的ajax框架给吓怕了。要了解ajax的原理，就只要参看这段代码即可。<br />
如今的一些框架，仅仅在此基础上，是封装了一些公用的函数，方便开发人员调用。（当然，说说简单，其实所谓的这些函数，大大方便了开发人员使用ajax技术。具体请参看ajax framework的官方介绍。）<br />
<br />
特别说明：这个xmlhttpost方法改进了<a title="simple-ajax" href="http://www.degraeve.com/reference/simple-ajax-example.php">simple-ajax</a>。在原基础上，将回调方法作为参数传递。<br />
<br />
<br />
解释了原理性的内容之后，接下来，以一个模拟的应用场景，demo说明ajax的使用，以及它的主要应用场景。<br />
模拟场景：<br />
目录选择，即当选择一个目录的时候，需要显示这个目录下的所有子目录。<br />
<br />
首先，我们来虚拟一个目录结构，如下：<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/stone2083/java/tree_node.png" height="245" width="184" /><br />
<br />
那么，要实现目录选择，有三个方式：<br />
1）页面初始化的时候，服务端将所有的目录信息都put到页面中。<br />
&nbsp;&nbsp; 优点：选择操作简单，有了全部的目录信息，做选择操作，都可以使用js完成，无需和服务端进行交互<br />
&nbsp;&nbsp; 缺点：当目录信息很大的时候，比如有上万个节点，整个目录信息有1m左右大小，那么要渲染这个页面，估计得20秒左右（视网速）<br />
并且，很可能用户仅仅只要选择有限的几个节点就可以，比如上万个节点中选择6－7个节点，那么浪费太大了；<br />
2）页面初始化的时候，服务端将当前需要的节点信息put到页面上，一旦有选择操作，重新刷新页面。<br />
&nbsp;&nbsp; 优点：选择操作简单，对于节点信息，每次取需要的内容，不存在浪费现象<br />
&nbsp;&nbsp; 缺点：每次都要刷新整个页面，除节点信息外，其他不变的东西都需要重新从服务端取，增加无谓的消耗。<br />
3）页面初始化的时候，服务端将当前需要的节点信息put到页面上，一旦有选择操作，只刷新节点相关的内容；<br />
&nbsp;&nbsp; 优点：每次只load需要的信息，局部刷新页面内容，不存在任何浪费现象<br />
&nbsp;&nbsp; 缺点：需要异步请求数据，每次请求都需要和服务器交互，选择操作稍显复杂（异步请求，局部刷新）<br />
<br />
通过这三种方式做对比，发现ajax主要适用的场景如下：<br />
1）整体内容量大（几百k，几m，甚至几十m），而页面只需要其中一小部分信息即可；<br />
2）数据显示，只涉及一个页面中部分数据信息的变动；<br />
<br />
特别说明：至于使用ajax性能如何，需要对1，3两个情况做性能测试，权衡使用。<br />
<br />
针对第三种方案，<br />
首先需要一个取节点资源的url，<br />
演示代码中，为了演示方便，使用php语言，而非使用主要语言java；<br />
tree_node.php<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">&lt;?</span><span style="color: rgb(0, 0, 0);">php<br />
</span><span style="color: rgb(128, 0, 128);">$id</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;</span><span style="color: rgb(128, 0, 128);">$_GET</span><span style="color: rgb(0, 0, 0);">[</span><span style="color: rgb(0, 0, 0);">'</span><span style="color: rgb(0, 0, 0);">id</span><span style="color: rgb(0, 0, 0);">'</span><span style="color: rgb(0, 0, 0);">];&nbsp;<br />
</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$id</span><span style="color: rgb(0, 0, 0);">)&nbsp;{<br />
&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">echo</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">{\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">id\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:1,\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">parentId\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:-1,\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">name\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">children\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:[{\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">id\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:2,\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">name\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">},{\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">id\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:3,\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">name\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">},{\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">id\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:4,\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">name\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">}]}</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />
}&nbsp;</span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$id</span><span style="color: rgb(0, 0, 0);">)&nbsp;{<br />
&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">echo</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">{\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">id\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:2,\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">parentId\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:1,\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">name\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">children\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:[]}</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />
}&nbsp;</span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$id</span><span style="color: rgb(0, 0, 0);">)&nbsp;{<br />
&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">echo</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">{\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">id\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:3,\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">parentId\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:1,\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">name\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">children\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:[]}</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />
}&nbsp;</span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$id</span><span style="color: rgb(0, 0, 0);">)&nbsp;{<br />
&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">echo</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">{\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">id\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:4,\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">parentId\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:1,\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">name\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">children\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:[{\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">id\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:5,\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">name\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">},{\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">id\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:6,\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">name\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">}]}</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />
}&nbsp;</span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">5</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$id</span><span style="color: rgb(0, 0, 0);">)&nbsp;{<br />
&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">echo</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">{\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">id\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:5,\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">parentId\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:4,\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">name\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">children\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:[]}</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />
}&nbsp;</span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">6</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$id</span><span style="color: rgb(0, 0, 0);">)&nbsp;{<br />
&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">echo</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">{\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">id\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:6,\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">parentId\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:4,\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">name\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">children\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:[{\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">id\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:7,\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">name\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">}]}</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />
}&nbsp;</span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">7</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(128, 0, 128);">$id</span><span style="color: rgb(0, 0, 0);">)&nbsp;{<br />
&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">echo</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">{\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">id\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:7,\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">parentId\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:6,\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">name\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">4</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">children\</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">:[]}</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />
}&nbsp;</span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);">&nbsp;{<br />
&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">echo</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">""</span><span style="color: rgb(0, 0, 0);">);<br />
}<br />
</span><span style="color: rgb(0, 0, 0);">?&gt;</span></div>
该文件中，写死了目录结构（一般情况下，往往根据树对象，动态取得需要的节点）。<br />
<br />
<br />
通过js，动态请求节点信息，部分刷新页面内容：<br />
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">script&nbsp;type</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">text/javascript</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">模拟需求js</span><span style="color: rgb(0, 128, 0);"><br />
</span><span style="color: rgb(0, 0, 0);">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">var</span><span style="color: rgb(0, 0, 0);">&nbsp;nodeSelect&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">(text)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">var</span><span style="color: rgb(0, 0, 0);">&nbsp;tree&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;toJsonObje(text);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">var</span><span style="color: rgb(0, 0, 0);">&nbsp;options&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;document.getElementById(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">tree</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">).options;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;options.length&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;options.add(</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;Option(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">请选择</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">-1</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(tree&nbsp;</span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: rgb(0, 0, 255);">else</span><span style="color: rgb(0, 0, 0);">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">var</span><span style="color: rgb(0, 0, 0);">&nbsp;children&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;tree.children;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">for</span><span style="color: rgb(0, 0, 0);">(i&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">;&nbsp;i&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">&nbsp;children.length;&nbsp;i</span><span style="color: rgb(0, 0, 0);">++</span><span style="color: rgb(0, 0, 0);">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">var</span><span style="color: rgb(0, 0, 0);">&nbsp;child&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;children[i];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;options.add(</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;Option(child.name,child.id));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(tree.parentId&nbsp;</span><span style="color: rgb(0, 0, 0);">!=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">-1</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;options.add(</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;Option(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">上一级</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,tree.parentId));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;document.getElementById(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">l</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">).innerHTML&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">当前位置：</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);">&nbsp;tree.name;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">function</span><span style="color: rgb(0, 0, 0);">&nbsp;nodeSelectAjax(id)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">var</span><span style="color: rgb(0, 0, 0);">&nbsp;TREE_NODE_URL&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">tree_node.php</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 255);">var</span><span style="color: rgb(0, 0, 0);">&nbsp;url&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;TREE_NODE_URL&nbsp;</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">?id=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);">&nbsp;id;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xmlhttpPost(url,nodeSelect);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;</span><span style="color: rgb(0, 0, 0);">&lt;/</span><span style="color: rgb(0, 0, 0);">script</span><span style="color: rgb(0, 0, 0);">&gt;</span></div>
nodeSelectAjax，异步请求节点资源<br />
<span style="color: rgb(0, 0, 0);">nodeSelect，回调函数，根据请求信息，局部刷新页面<br />
<br />
<br />
至于请求资源信息格式，任何方式都可以，只要client端能解析就行。<br />
目前json格式，比较流行。<br />
最后，附上java使用<a title="json" href="http://www.json.org/">json</a>库，生成json格式的方法：<br />
</span>
<div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: rgb(0, 0, 0);">JSONObject&nbsp;node&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;JSONObject();<br />
node.put(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">id</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">);<br />
node.put(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">parentId</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 0);">);<br />
node.put(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">name</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">1-1</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />
JSONArray&nbsp;children&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;JSONArray();<br />
JSONObject&nbsp;c1&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;JSONObject();<br />
c1.put(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">id</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">2</span><span style="color: rgb(0, 0, 0);">);<br />
c1.put(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">name</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">2-1</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />
JSONObject&nbsp;c2&nbsp;</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">&nbsp;</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);">&nbsp;JSONObject();<br />
c2.put(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">id</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">3</span><span style="color: rgb(0, 0, 0);">);<br />
c2.put(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">name</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,&nbsp;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">2-2</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />
children.put(c1);<br />
children.put(c2);<br />
node.put(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">children</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,&nbsp;children);<br />
System.out.println(node.toString());</span></div>
<br />
<br />
<br />
<span style="color: rgb(0, 0, 0);"><a href="/Files/stone2083/java/ajax.zip" title="ajax demo">ajax demo</a><br />
工程文件编码：utf－8<br />
工程运行：http server with php supported<br />
ubuntu firefox下测试通过<br />
<br />
<br />
其他：<br />
不知道是不是ie的bug，居然不支持 select.innerHTML = value的方式<br />
只能通过select.options.add(new Option("content","value") 动态往select中添加选项。<br />
<br />
</span>
<img src ="http://www.blogjava.net/stone2083/aggbug/230278.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stone2083/" target="_blank">stone2083</a> 2008-09-21 19:05 <a href="http://www.blogjava.net/stone2083/archive/2008/09/21/230278.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>单元测试分享</title><link>http://www.blogjava.net/stone2083/archive/2008/07/17/215302.html</link><dc:creator>stone2083</dc:creator><author>stone2083</author><pubDate>Thu, 17 Jul 2008 14:04:00 GMT</pubDate><guid>http://www.blogjava.net/stone2083/archive/2008/07/17/215302.html</guid><wfw:comment>http://www.blogjava.net/stone2083/comments/215302.html</wfw:comment><comments>http://www.blogjava.net/stone2083/archive/2008/07/17/215302.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stone2083/comments/commentRss/215302.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stone2083/services/trackbacks/215302.html</trackback:ping><description><![CDATA[最近，在小组内部做了一次关于&#8220;单元测试&#8221;的分享。把自己两年来做单元测试遇到的问题和对单元测试的认识做了一次总结和讨论。<br />
<br />
本文不会详细地讲述分享的内容，仅仅是ppt的大纲显示：<br />
<span style="color: #0010ff;"><br />
使用单元测试前提：<br />
</span>最小的成本，换来最大的收益<br />
<span style="color: #0010ff;"><br />
单元测试目的</span>：<br />
1）测试代码错误(?) －－ 不是主要目的<br />
2）便于重构时的测试<br />
3）改善既有代码的设计<br />
<br />
<span style="color: #0010ff;">分享核心</span>：<br />
1）如何脱离&#8220;webx&#8220;－－做隔离测试<br />
2）dal／biz／web 层如何做单元测试<br />
3）如何通过改善代码设计，更方便测试<br />
<br />
<span style="color: #0010ff;">dal层</span><span style="color: #0010ff;">（数据库访问层）</span><span style="color: #0010ff;">特点：</span><br />
1)独立，逻辑单一，对表做操作<br />
2)业务相对比较稳定<br />
3)采用ibatis，写sql的方式<br />
<br />
<span style="color: #0010ff;">dal层测试方式</span>：<br />
1）压根儿就不需要测试<br />
2）仅仅配置spring bean，通过日志打印的方式（无法达到自检）<br />
3) 自检方式 -- AbstractTransactionalDataSourceSpringContextTests （高成本，不轻易使用）<br />
需要权衡<br />
<br />
<span style="color: #0010ff;">biz</span><span style="color: #0010ff;">层</span><span style="color: #0010ff;">（业务层）测试方式－－分BO和AO：<br />
BO：（即所谓的Service／Manager）<br />
AO：（一个UseCase对应的业务流）<br />
</span>隔离 ＋ 设计 （主要通过代码演示－－见附件）<br />
<br />
<span style="color: #0010ff;">单元测试的缺点</span>：<br />
专注于单一业务测试，衔接点容易出错<br />
<br />
<span style="color: #0010ff;">解决</span><span style="color: #0010ff;">方案</span>：<br />
接口输入输出明确<br />
集成测试<br />
<br />
<span style="color: #0010ff;">web层：<br />
</span>
集成测试的入口<br />
<br />
<a href="/Files/stone2083/java/webx_test.zip" title="分享文档和演示代码">分享文档和演示代码</a> （ppt是在ubuntu下制作，可能效果并不是很好）<br />
<br />
备注：<br />
自己对单元测试了解也比较肤浅，欢迎一起探讨<br />
<img src ="http://www.blogjava.net/stone2083/aggbug/215302.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stone2083/" target="_blank">stone2083</a> 2008-07-17 22:04 <a href="http://www.blogjava.net/stone2083/archive/2008/07/17/215302.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ibatis--部分更新表记录字段的方法</title><link>http://www.blogjava.net/stone2083/archive/2008/06/26/210969.html</link><dc:creator>stone2083</dc:creator><author>stone2083</author><pubDate>Thu, 26 Jun 2008 14:46:00 GMT</pubDate><guid>http://www.blogjava.net/stone2083/archive/2008/06/26/210969.html</guid><wfw:comment>http://www.blogjava.net/stone2083/comments/210969.html</wfw:comment><comments>http://www.blogjava.net/stone2083/archive/2008/06/26/210969.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stone2083/comments/commentRss/210969.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stone2083/services/trackbacks/210969.html</trackback:ping><description><![CDATA[使用ibatis,如果要更新表记录,一般常用的做法就是,查找出记录,然后修改部分字段,进行update操作.<br />
以member表为例:<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">MemberDO&nbsp;member&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;memberDAO.findById(</span><span style="color: #000000;">1</span><span style="color: #000000;">);<br />
member.setName(</span><span style="color: #000000;">"</span><span style="color: #000000;">stone</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
memberDAO.update(member);</span></div>
<br />
这种是最常用的方法.不错,在很多应用场景下,这么干,完全没有问题.<br />
但是(往往存在但是),如果member表中存在一个或者多个text(或者blob)字段.难道仅仅为了更新一个name字段,需要重新update那些本不需要更新的text/blob字段吗?<br />
<br />
于是乎,人们又想出了一个办法,参数采用map,把需要更新的字段put到map中,<br />
演示代码(省略ibatis的sqlmap文件):<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">Map</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">String,Object</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;map&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;HashMap</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">String,Object</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">();<br />
map.put(</span><span style="color: #000000;">"</span><span style="color: #000000;">name</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">"</span><span style="color: #000000;">stone</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
memberDAO.update(map);</span></div>
<br />
没错,这种方法不错.需要更新哪些字段,只需要动态put到map中就可以.<br />
但是,对于这种方法,需要调用更新的地方,需要手工维护数据库的字段名,如果在put的时候,一不小心拼错字段名,那么更新操作肯定和你预计的会有差别.<br />
比如上面的代码:<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">Map</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">String,Object</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;map&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;HashMap</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">String,Object</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">();<br />
map.put(</span><span style="color: #000000;">"</span><span style="color: #000000;">nama</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">"</span><span style="color: #000000;">stone</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
memberDAO.update(map);</span></div>
不小心把name拼成了nama,那么新的name字段就无法保存到数据库中.试想一下,任何需要更新字段的地方,都存在拼写错误的风险.<br />
<br />
于是乎,人们又想到了参数类,比如就把MemberDO当成参数类:<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">MemberDO&nbsp;memberParam&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;MemberDO();<br />
memberParam.setName(</span><span style="color: #000000;">"</span><span style="color: #000000;">stone</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
memberDAO.update(memberParam);</span></div>
sqlmap.xml如下:<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">update&nbsp;member<br />
set&nbsp;gmt_modified&nbsp;=&nbsp;current_date<br />
</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">dynamic</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">isNotNull&nbsp;</span><span style="color: #ff0000;">property</span><span style="color: #0000ff;">="loginId"</span><span style="color: #ff0000;">,prepend</span><span style="color: #0000ff;">=","</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
login_id&nbsp;=&nbsp;#loginId#<br />
</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">isNotNull</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">isNotNull&nbsp;</span><span style="color: #ff0000;">property</span><span style="color: #0000ff;">="name"</span><span style="color: #ff0000;">,prepend</span><span style="color: #0000ff;">=","</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
name&nbsp;=&nbsp;#name#<br />
</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">isNotNull</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;<img src="http://www.blogjava.net/Images/dot.gif" alt="" /><br />
</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">dynamic</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
where&nbsp;id&nbsp;=&nbsp;#id#&nbsp; <br />
</span></div>
这方法貌似不错,不会存在字段名拼写错误的风险.并且需要更新哪些字段,动态set一下就可以.<br />
但是,如果要把某个字段设置为null,那怎么办?那没辙咯...(sqlmap中约定,只有不为null的时候,才更新).<br />
<br />
那...那...那怎么办呢?<br />
貌似只有Map才能满足需求嘛...因为sqlmap中有个<br />
"isPropertyAvailable"和"isNull"属性支持.只要配合这两个属性,就能区分需要更新为null,还是不更新保持原字段内容.<br />
sqlmap文件演示:<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">isPropertyAvailable&nbsp;</span><span style="color: #ff0000;">property</span><span style="color: #0000ff;">="loginId"</span><span style="color: #ff0000;">&nbsp;prepend</span><span style="color: #0000ff;">=","</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">isNotNull&nbsp;</span><span style="color: #ff0000;">property</span><span style="color: #0000ff;">="loginId"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;![CDATA[</span><span style="color: #808080;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;login_id&nbsp;=&nbsp;#loginId#<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">]]&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">isNotNull</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">isNull&nbsp;</span><span style="color: #ff0000;">property</span><span style="color: #0000ff;">="loginId"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;![CDATA[</span><span style="color: #808080;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;login_id&nbsp;=&nbsp;null<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">]]&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">isNull</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">isPropertyAvailable</span><span style="color: #0000ff;">&gt;</span></div>
只要map不put loginId,那么更新的时候,就不会更新这个字段,如果map.put("loginId",null),那么就会把loginId更新为null.<br />
看来只有map能胜任.<br />
<br />
不是说,使用map,维护字段内容很麻烦嘛.但是好像又只能使用它?<br />
于是乎,又想到了一种思路(也是本文要介绍的一个方法)<br />
通过方法拦截,在设置参数类的时候,把设置的属性值put到map中.(cglib是很胜任这样的场合的)<br />
<br />
首先,需要一个BaseDO.java DataObject的基类,仅仅用于维护一份Map对象.<br />
BaseDO.java:<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;BaseDO&nbsp;</span><span style="color: #0000ff;">implements</span><span style="color: #000000;">&nbsp;Serializable&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">long</span><span style="color: #000000;">&nbsp;serialVersionUID&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">315506079592557582L</span><span style="color: #000000;">;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;Map</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">String,&nbsp;Object</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;setterMap;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">synchronized</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;initSetterMap()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(setterMap&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setterMap&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;HashMap</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">String,&nbsp;Object</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">();<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;Map</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">String,&nbsp;Object</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;getSetterMap()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;setterMap;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
}</span></div>
<br />
采用Cglib,写一个对set方法的拦截器:<br />
SetterInterceptor.java 用于对截获set操作,把set的对象put到map中<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;SetterInterceptor&nbsp;</span><span style="color: #0000ff;">implements</span><span style="color: #000000;">&nbsp;MethodInterceptor&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;String&nbsp;SET_METHOD&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">set</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;Object&nbsp;intercept(Object&nbsp;obj,&nbsp;Method&nbsp;method,&nbsp;Object[]&nbsp;args,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MethodProxy&nbsp;proxy)&nbsp;</span><span style="color: #0000ff;">throws</span><span style="color: #000000;">&nbsp;Throwable&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;拦截DataObject中所有的set方法,把set的属性放入到map中</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(method.getName().startsWith(SET_METHOD))&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(obj&nbsp;</span><span style="color: #0000ff;">instanceof</span><span style="color: #000000;">&nbsp;BaseDO)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BaseDO&nbsp;baseDO&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(BaseDO)&nbsp;obj;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;baseDO.initSetterMap();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;attribute&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;StringUtils.substring(method.getName(),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SET_METHOD.length());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;attribute&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;StringUtils.uncapitalize(attribute);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(args&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;args.length&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;baseDO.getSetterMap().put(attribute,&nbsp;args[</span><span style="color: #000000;">0</span><span style="color: #000000;">]);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;proxy.invokeSuper(obj,&nbsp;args);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
}</span></div>
<br />
写一个创建Setter的工厂类,用于创建带方法拦截的DataObject对象<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;SetterFactory&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;SetterInterceptor&nbsp;setterInterceptor&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;SetterInterceptor();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;@SuppressWarnings(</span><span style="color: #000000;">"</span><span style="color: #000000;">unchecked</span><span style="color: #000000;">"</span><span style="color: #000000;">)<br />
&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: #000000;">&lt;</span><span style="color: #000000;">T&nbsp;</span><span style="color: #0000ff;">extends</span><span style="color: #000000;">&nbsp;BaseDO</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;T&nbsp;getSetterInstance(Class</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">T</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;clazz)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;Enhancer&nbsp;enhancer&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;Enhancer();<br />
&nbsp;&nbsp;&nbsp;&nbsp;enhancer.setSuperclass(clazz);<br />
&nbsp;&nbsp;&nbsp;&nbsp;enhancer.setCallback(setterInterceptor);<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;(T)&nbsp;enhancer.create();<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
}</span></div>
<br />
那么对于client调用,就非常简单了.<br />
如:<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Client&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;Log&nbsp;log&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;LogFactory.getLog(Client.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">final</span><span style="color: #000000;">&nbsp;String&nbsp;APP_CONFIG_FILE&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">cn/zeroall/javalab/ibatis/app.xml</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br />
<br />
&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;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;ApplicationContext&nbsp;ctx&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;ClassPathXmlApplicationContext(<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;APP_CONFIG_FILE);<br />
&nbsp;&nbsp;&nbsp;&nbsp;MemberDAO&nbsp;memberDAO&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(MemberDAO)&nbsp;ctx.getBean(</span><span style="color: #000000;">"</span><span style="color: #000000;">memberDAO</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;MemberDO&nbsp;setter&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;SetterFactory.getSetterInstance(MemberDO.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;setter.setId(</span><span style="color: #000000;">1</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;setter.setLoginId(</span><span style="color: #000000;">"</span><span style="color: #000000;">stone1</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;setter.setName(</span><span style="color: #000000;">"</span><span style="color: #000000;">stone1</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;memberDAO.updateById(setter);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;MemberDO&nbsp;member&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;memberDAO.findById(</span><span style="color: #000000;">1</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;log.info(member.getLoginId());<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}</span></div>
<br />
sqlmap文件如下:<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">update&nbsp;</span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="update-by-id"</span><span style="color: #ff0000;">&nbsp;parameterClass</span><span style="color: #0000ff;">="java.util.Map"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;![CDATA[</span><span style="color: #808080;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;update&nbsp;member<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set&nbsp;gmt_modified&nbsp;=&nbsp;current_date<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">]]&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">dynamic</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">isPropertyAvailable&nbsp;</span><span style="color: #ff0000;">property</span><span style="color: #0000ff;">="loginId"</span><span style="color: #ff0000;">&nbsp;prepend</span><span style="color: #0000ff;">=","</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">isNotNull&nbsp;</span><span style="color: #ff0000;">property</span><span style="color: #0000ff;">="loginId"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;![CDATA[</span><span style="color: #808080;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;login_id&nbsp;=&nbsp;#loginId#<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">]]&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">isNotNull</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">isNull&nbsp;</span><span style="color: #ff0000;">property</span><span style="color: #0000ff;">="loginId"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;![CDATA[</span><span style="color: #808080;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;login_id&nbsp;=&nbsp;null<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">]]&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">isNull</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">isPropertyAvailable</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">isPropertyAvailable&nbsp;</span><span style="color: #ff0000;">property</span><span style="color: #0000ff;">="password"</span><span style="color: #ff0000;">&nbsp;prepend</span><span style="color: #0000ff;">=","</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">isNotNull&nbsp;</span><span style="color: #ff0000;">property</span><span style="color: #0000ff;">="password"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;![CDATA[</span><span style="color: #808080;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;password&nbsp;=&nbsp;#password#<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">]]&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">isNotNull</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">isNull&nbsp;</span><span style="color: #ff0000;">property</span><span style="color: #0000ff;">="password"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;![CDATA[</span><span style="color: #808080;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;password&nbsp;=&nbsp;null<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">]]&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">isNull</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">isPropertyAvailable</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">isPropertyAvailable&nbsp;</span><span style="color: #ff0000;">property</span><span style="color: #0000ff;">="name"</span><span style="color: #ff0000;">&nbsp;prepend</span><span style="color: #0000ff;">=","</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">isNotNull&nbsp;</span><span style="color: #ff0000;">property</span><span style="color: #0000ff;">="name"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;![CDATA[</span><span style="color: #808080;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name&nbsp;=&nbsp;#name#<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">]]&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">isNotNull</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">isNull&nbsp;</span><span style="color: #ff0000;">property</span><span style="color: #0000ff;">="name"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;![CDATA[</span><span style="color: #808080;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name&nbsp;=&nbsp;null<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">]]&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">isNull</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">isPropertyAvailable</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">isPropertyAvailable&nbsp;</span><span style="color: #ff0000;">property</span><span style="color: #0000ff;">="profile"</span><span style="color: #ff0000;">&nbsp;prepend</span><span style="color: #0000ff;">=","</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">isNotNull&nbsp;</span><span style="color: #ff0000;">property</span><span style="color: #0000ff;">="profile"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;![CDATA[</span><span style="color: #808080;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;profile&nbsp;=&nbsp;#profile#<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">]]&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">isNotNull</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">isNull&nbsp;</span><span style="color: #ff0000;">property</span><span style="color: #0000ff;">="profile"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;![CDATA[</span><span style="color: #808080;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;profile&nbsp;=&nbsp;null<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">]]&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">isNull</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">isPropertyAvailable</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">dynamic</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;![CDATA[</span><span style="color: #808080;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;where&nbsp;id&nbsp;=&nbsp;#id#<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">]]&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">update</span><span style="color: #0000ff;">&gt;</span></div>
<br />
<br />
一旦采用了Setter对象,那么对于表记录的更新操作,仅仅需要一个sql,就能解决.比较方便.<br />
<br />
附件中,把整个演示代码附上,有兴趣的朋友,可以了解下:<br />
采用maven构建,workspace编码采用utf-8.数据库采用pgsql<br />
<br />
<a href="/Files/stone2083/java/ibatis-setter.zip">demo附件</a><br />
<br />
备注:<br />
member表创建sql如下:<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080;">--</span><span style="color: #008080;">&nbsp;Table:&nbsp;member</span><span style="color: #008080;"><br />
</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">--</span><span style="color: #008080;">&nbsp;DROP&nbsp;TABLE&nbsp;member;</span><span style="color: #008080;"><br />
</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">CREATE</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">TABLE</span><span style="color: #000000;">&nbsp;member<br />
(<br />
&nbsp;&nbsp;id&nbsp;serial&nbsp;</span><span style="color: #808080;">NOT</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">NULL</span><span style="color: #000000;">,<br />
&nbsp;&nbsp;login_id&nbsp;</span><span style="color: #000000; font-weight: bold;">character</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000; font-weight: bold;">varying</span><span style="color: #000000;">(</span><span style="color: #800000; font-weight: bold;">16</span><span style="color: #000000;">),<br />
&nbsp;&nbsp;"password"&nbsp;</span><span style="color: #000000; font-weight: bold;">character</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000; font-weight: bold;">varying</span><span style="color: #000000;">(</span><span style="color: #800000; font-weight: bold;">16</span><span style="color: #000000;">),<br />
&nbsp;&nbsp;"name"&nbsp;</span><span style="color: #000000; font-weight: bold;">character</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000; font-weight: bold;">varying</span><span style="color: #000000;">(</span><span style="color: #800000; font-weight: bold;">32</span><span style="color: #000000;">),<br />
&nbsp;&nbsp;profile&nbsp;</span><span style="color: #000000; font-weight: bold;">text</span><span style="color: #000000;">,<br />
&nbsp;&nbsp;gmt_created&nbsp;</span><span style="color: #000000; font-weight: bold;">timestamp</span><span style="color: #000000;">&nbsp;without&nbsp;time&nbsp;zone,<br />
&nbsp;&nbsp;gmt_modified&nbsp;</span><span style="color: #000000; font-weight: bold;">timestamp</span><span style="color: #000000;">&nbsp;without&nbsp;time&nbsp;zone,<br />
&nbsp;&nbsp;</span><span style="color: #0000ff;">CONSTRAINT</span><span style="color: #000000;">&nbsp;member_pkey&nbsp;</span><span style="color: #0000ff;">PRIMARY</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">KEY</span><span style="color: #000000;">&nbsp;(id)<br />
)<br />
</span><span style="color: #0000ff;">WITH</span><span style="color: #000000;">&nbsp;(OIDS</span><span style="color: #808080;">=</span><span style="color: #000000;">FALSE);<br />
</span><span style="color: #0000ff;">ALTER</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">TABLE</span><span style="color: #000000;">&nbsp;member&nbsp;OWNER&nbsp;</span><span style="color: #0000ff;">TO</span><span style="color: #000000;">&nbsp;javalab;</span></div>
<br />
<br />
特别说明:<br />
此方法原创作者为公司同事,本文只是盗用了他的创意.<br />
<br />
<br />
<img src ="http://www.blogjava.net/stone2083/aggbug/210969.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stone2083/" target="_blank">stone2083</a> 2008-06-26 22:46 <a href="http://www.blogjava.net/stone2083/archive/2008/06/26/210969.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>活用Srping AOP</title><link>http://www.blogjava.net/stone2083/archive/2008/06/01/205147.html</link><dc:creator>stone2083</dc:creator><author>stone2083</author><pubDate>Sun, 01 Jun 2008 07:21:00 GMT</pubDate><guid>http://www.blogjava.net/stone2083/archive/2008/06/01/205147.html</guid><wfw:comment>http://www.blogjava.net/stone2083/comments/205147.html</wfw:comment><comments>http://www.blogjava.net/stone2083/archive/2008/06/01/205147.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stone2083/comments/commentRss/205147.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stone2083/services/trackbacks/205147.html</trackback:ping><description><![CDATA[总有那么一些代码，在测试环境下，是不能轻易被调用的。<br />
比如:<br />
1)发送系统任务邮件到客户邮箱，可能一不小心，就把测试邮件发送给了真实客户的邮箱里;<br />
2)调用跨公司的系统接口，而对方系统没有测试环境，每调用一次接口，就会在对方系统产生垃圾数据；<br />
3)调用的代码可能需要大量的cpu运算，占用大量的内存空间，消耗大量的资源；<br />
等等。。。<br />
<br />
为了解决这样的需求，<br />
1)在代码中，到处充斥着这样的代码：<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080;">1</span>&nbsp;<span style="color: #0000ff;">if</span><span style="color: #000000;">(在测试环境下)&nbsp;{<br />
</span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;打印日志;<br />
</span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;">}&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;{<br />
</span><span style="color: #008080;">4</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;调用真实的业务逻辑;<br />
</span><span style="color: #008080;">5</span>&nbsp;<span style="color: #000000;">}</span></div>
于是乎，需要到处维护这样的代码，一旦增加此类需求，就需要编写同样的代码<br />
<br />
2)部分懒惰的程序员，连这样的if...else...也不愿意写，仅仅在注释中说明下在测试环境中调用方法的危害性。<br />
于是，在测试阶段，一旦和测试部门沟通不足，导致代码还是经常被调用到，如果是在作压力，性能测试，那么危害性可想而已。<br />
曾发生过，压力测试某个功能，结果把大量的测试邮件，发送给了客户，影响很差。<br />
<br />
<br />
那么，如何解决这样的需求场景呢？<br />
没错，采用proxy模式，可以搞定。考虑到现在很多企业都使用Spring作为IOC容器，本文就简单介绍，如何采用spring aop来解决问题。<br />
<br />
以发送邮件的需求作为虚拟场景。<br />
现在有个Service，专门负责邮件的发送。<br />
1. MyService.java<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080;">1</span>&nbsp;<span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;MyService&nbsp;{<br />
</span><span style="color: #008080;">2</span>&nbsp;<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;">void</span><span style="color: #000000;">&nbsp;sendMailSafely()&nbsp;{<br />
</span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000;">"</span><span style="color: #000000;">send&nbsp;mail&nbsp;successfully.</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
</span><span style="color: #008080;">4</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080;">5</span>&nbsp;<span style="color: #000000;">}</span></div>
<br />
如果这个sendMailSafely被客户端调用，那么毫无疑问，邮件不管任何环境下，都会被成功发送。<br />
需要有个方法拦截器，对这个方法做拦截。<br />
2. MyInterceptor.java<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;MyInterceptor&nbsp;</span><span style="color: #0000ff;">implements</span><span style="color: #000000;">&nbsp;MethodInterceptor&nbsp;{<br />
</span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">boolean</span><span style="color: #000000;">&nbsp;isProduction&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;">&nbsp;4</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />
</span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;Object&nbsp;invoke(MethodInvocation&nbsp;invocation)&nbsp;</span><span style="color: #0000ff;">throws</span><span style="color: #000000;">&nbsp;Throwable&nbsp;{<br />
</span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">!</span><span style="color: #000000;">isProduction)&nbsp;{<br />
</span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000;">"</span><span style="color: #000000;">is&nbsp;production&nbsp;environment.do&nbsp;nothing<img src="http://www.blogjava.net/Images/dot.gif" alt="" /></span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
</span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br />
</span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;invocation.proceed();<br />
</span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">14</span>&nbsp;<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;">void</span><span style="color: #000000;">&nbsp;setProduction(</span><span style="color: #0000ff;">boolean</span><span style="color: #000000;">&nbsp;isProduction)&nbsp;{<br />
</span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.isProduction&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;isProduction;<br />
</span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">18</span>&nbsp;<span style="color: #000000;">}</span></div>
这个拦截器，根据配置文件的参数isProduction判断是否在正式环境，如果是在测试环境，对方法做拦截，仅仅打印log，不真实调用业务逻辑。<br />
<br />
如何让sendMailSafely()方法被此拦截器做拦截，所以通过spring配置文件，配置一个advisor，通知对以Safely结尾的方法做拦截<br />
3.&nbsp; application.xml<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #0000ff;">&lt;</span><span style="color: #800000;">bean&nbsp;</span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="safetyAdvisor"</span><span style="color: #ff0000;">&nbsp;class</span><span style="color: #0000ff;">="org.springframework.aop.support.RegexpMethodPointcutAdvisor"</span><span style="color: #ff0000;">&nbsp;scope</span><span style="color: #0000ff;">="singleton"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">property&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="advice"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">ref&nbsp;</span><span style="color: #ff0000;">local</span><span style="color: #0000ff;">="myInterceptor"</span><span style="color: #ff0000;">&nbsp;</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">property</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">property&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="patterns"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">list</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">value</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">.*Safely</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">value</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">list</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">property</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">bean</span><span style="color: #0000ff;">&gt;</span></div>
<br />
附上application.xml的全部内容<br />
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008080;">&nbsp;1</span>&nbsp;<span style="color: #0000ff;">&lt;</span><span style="color: #800000;">beans&nbsp;</span><span style="color: #ff0000;">default-autowire</span><span style="color: #0000ff;">="byName"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;2</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;3</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #008000;">&lt;!--</span><span style="color: #008000;">&nbsp;service实例&nbsp;</span><span style="color: #008000;">--&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;4</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">bean&nbsp;</span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="myService"</span><span style="color: #ff0000;">&nbsp;class</span><span style="color: #0000ff;">="cn.zeroall.javalab.aop.MyService"</span><span style="color: #ff0000;">&nbsp;scope</span><span style="color: #0000ff;">="singleton"</span><span style="color: #ff0000;">&nbsp;</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;5</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #008000;">&lt;!--</span><span style="color: #008000;">&nbsp;方法拦截器&nbsp;</span><span style="color: #008000;">--&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;7</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">bean&nbsp;</span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="myInterceptor"</span><span style="color: #ff0000;">&nbsp;class</span><span style="color: #0000ff;">="cn.zeroall.javalab.aop.MyInterceptor"</span><span style="color: #ff0000;">&nbsp;scope</span><span style="color: #0000ff;">="singleton"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;8</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">property&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="production"</span><span style="color: #ff0000;">&nbsp;value</span><span style="color: #0000ff;">="false"</span><span style="color: #ff0000;">&nbsp;</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">&nbsp;9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">bean</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">10</span>&nbsp;<span style="color: #000000;"><br />
</span><span style="color: #008080;">11</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #008000;">&lt;!--</span><span style="color: #008000;">&nbsp;通知者&nbsp;</span><span style="color: #008000;">--&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">12</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">bean&nbsp;</span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="safetyAdvisor"</span><span style="color: #ff0000;">&nbsp;class</span><span style="color: #0000ff;">="org.springframework.aop.support.RegexpMethodPointcutAdvisor"</span><span style="color: #ff0000;">&nbsp;scope</span><span style="color: #0000ff;">="singleton"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">13</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">property&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="advice"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">14</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">ref&nbsp;</span><span style="color: #ff0000;">local</span><span style="color: #0000ff;">="myInterceptor"</span><span style="color: #ff0000;">&nbsp;</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">15</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">property</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">16</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">property&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="patterns"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">17</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">list</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #008080;">18</span>&nbsp;<span style="