﻿<?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-LifeNote -随笔分类-Spring</title><link>http://www.blogjava.net/lifenote/category/27921.html</link><description>&amp;nbsp;
Try to find something different in your life and then write it down&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&lt;strong&gt;Java乐园：&lt;a href='http://www.java-bj.cn' target='_blank'&gt;&lt;font color='red' size="+1"&gt;www.java-bj.cn&lt;/font&gt;&lt;/a&gt;  资料下载&lt;/strong&gt;
&lt;div style="float:left"&gt;
&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-4636496036365579";
/* 468x60, 创建于 08-4-23 */
google_ad_slot = "3356926921";
google_ad_width = 468;
google_ad_height = 60;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;
&lt;/div&gt;
&lt;div style="float:left"&gt;
&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-4636496036365579";
/* 468x60, 创建于 08-4-23 */
google_ad_slot = "5017273295";
google_ad_width = 468;
google_ad_height = 60;
//--&gt;
&lt;/script&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;
&lt;/div&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;</description><language>zh-cn</language><lastBuildDate>Thu, 24 Apr 2008 07:47:09 GMT</lastBuildDate><pubDate>Thu, 24 Apr 2008 07:47:09 GMT</pubDate><ttl>60</ttl><item><title>Eclipse下的Java反编译插件：Jode Decompiler</title><link>http://www.blogjava.net/lifenote/archive/2008/04/24/195588.html</link><dc:creator>LifeNote</dc:creator><author>LifeNote</author><pubDate>Thu, 24 Apr 2008 07:05:00 GMT</pubDate><guid>http://www.blogjava.net/lifenote/archive/2008/04/24/195588.html</guid><wfw:comment>http://www.blogjava.net/lifenote/comments/195588.html</wfw:comment><comments>http://www.blogjava.net/lifenote/archive/2008/04/24/195588.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/lifenote/comments/commentRss/195588.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lifenote/services/trackbacks/195588.html</trackback:ping><description><![CDATA[这个工具感觉非常方便 介绍给大家<br />
安装方法： <br />
&nbsp;&nbsp;&nbsp;&nbsp;help =&gt; Software Updates =&gt; Find and Install... =&gt; Search for new features to install,单击"New Remote Site..." 在URL栏输入 <a onclick="showLinkBubble(this);return false" href="http://www.technoetic.com/eclipse/update" target="_blank" link="http://www.technoetic.com/eclipse/update">http://www.technoetic.com/eclipse/update</a><wbr>.然后下一步，就可以看到&#8220;jode decompiler plugin *.*&#8221;，选上安装就可以了。 <br />
<br />
安装好后可以看到Window =&gt; Preferences... =&gt; Java =&gt; Jode Decompiler选项卡。 <br />
<br />
配置：Window =&gt; Preferences... =&gt; General =&gt; Editors =&gt; File Associations找到"*.class"在"Associated editors"里面可以看到"Jode class file viewer"选中它再单击Default按钮. <br />
<br />
在Eclipse中展开jar文件,双击class文件即可看到反编译之后的源代码.<br />
<img src ="http://www.blogjava.net/lifenote/aggbug/195588.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lifenote/" target="_blank">LifeNote</a> 2008-04-24 15:05 <a href="http://www.blogjava.net/lifenote/archive/2008/04/24/195588.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用动态代理实现用AOP对数据库进行操作</title><link>http://www.blogjava.net/lifenote/archive/2008/04/22/194687.html</link><dc:creator>LifeNote</dc:creator><author>LifeNote</author><pubDate>Tue, 22 Apr 2008 01:54:00 GMT</pubDate><guid>http://www.blogjava.net/lifenote/archive/2008/04/22/194687.html</guid><wfw:comment>http://www.blogjava.net/lifenote/comments/194687.html</wfw:comment><comments>http://www.blogjava.net/lifenote/archive/2008/04/22/194687.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lifenote/comments/commentRss/194687.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lifenote/services/trackbacks/194687.html</trackback:ping><description><![CDATA[<div class="NewsContent" id="NewsContentLabel"><span class="t18">要实现对数据库的操作，离不开数据源（DataSource）或者连接（Connection）,但是通常来说对数据库的操作都应该放在DAO中，而DAO又不应该与应用服务器相关联，所以一般都使用连接（Connection）。现在我们这里就有一个问题了，怎么在拦截器中获得连接。我想可以通过两种方式获得：<br />
在分别讨论这两种方法之前，我们需要先讨论一下在处理数据库的时候的异常的处理。我这里做了一个TransactionException继承至RuntimeException然后在拦截器里面抛出，再又应用框架处理这个异常。下面试这个类的代码：<br />
public&nbsp;class&nbsp;TransactionException&nbsp;extends&nbsp;RuntimeException&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;Throwable&nbsp;superException;<br />
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;String&nbsp;myMessage;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;TransactionException(Throwable&nbsp;throwable){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;super(throwable);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.superException&nbsp;=&nbsp;throwable;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;TransactionException(Throwable&nbsp;throwable,String&nbsp;message){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;super(message,throwable);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.superException&nbsp;=&nbsp;throwable;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.myMessage&nbsp;=&nbsp;message;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;/**<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;Returns&nbsp;the&nbsp;myMessage.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/<br />
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;String&nbsp;getMessage()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;myMessage;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;/**<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;Returns&nbsp;the&nbsp;superException.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/<br />
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;Throwable&nbsp;getSuperException()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;superException;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;/**<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;myMessage&nbsp;The&nbsp;myMessage&nbsp;to&nbsp;set.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/<br />
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;setMyMessage(String&nbsp;message)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.myMessage&nbsp;=&nbsp;message;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;/**<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;superException&nbsp;The&nbsp;superException&nbsp;to&nbsp;set.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/<br />
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;setSuperException(Throwable&nbsp;superException)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.superException&nbsp;=&nbsp;superException;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
}<br />
1）&nbsp;&nbsp;&nbsp;&nbsp;通过方法的第一个参数传进去<br />
l&nbsp;&nbsp;&nbsp;&nbsp;DAO<br />
import&nbsp;java.sql.Connection;<br />
<br />
public&nbsp;class&nbsp;TestDao&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;insertA(Connection&nbsp;con,String&nbsp;a,String&nbsp;b,&#8230;&#8230;){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;<br />
一系列操作<br />
&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;String&nbsp;queryA(Connection&nbsp;con,&#8230;&#8230;.){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;<br />
一系列操作<br />
&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;<br />
}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;updateA(Connection&nbsp;con,&#8230;&#8230;.){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;<br />
一系列操作<br />
&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;<br />
}<br />
}<br />
<br />
l&nbsp;&nbsp;&nbsp;&nbsp;拦截器<br />
import&nbsp;java.sql.Connection;<br />
import&nbsp;java.sql.SQLException;<br />
import&nbsp;java.util.ArrayList;<br />
import&nbsp;java.util.List;<br />
<br />
public&nbsp;class&nbsp;TransactionInterceptor&nbsp;implements&nbsp;Interceptor&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;before(InvokeJniInfo&nbsp;invInfo)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(isNeedTransactions(invInfo)){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Connection&nbsp;conn&nbsp;=&nbsp;(Connection)&nbsp;invInfo.getArgs()[0];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn.setAutoCommit(false);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(SQLException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;TransactionException(e);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;after(InvokeJniInfo&nbsp;invInfo)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(isNeedTransactions(invInfo)){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Connection&nbsp;conn&nbsp;=&nbsp;(Connection)&nbsp;invInfo.getArgs()[0];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn.commit();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(SQLException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;TransactionException(e);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}finally{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(conn&nbsp;!=&nbsp;null){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(SQLException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;TransactionException(e,"Close&nbsp;Connection&nbsp;is&nbsp;failure!");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;exceptionThrow(InvokeJniInfo&nbsp;invInfo)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(isNeedTransactions(invInfo)){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Connection&nbsp;conn&nbsp;=&nbsp;(Connection)&nbsp;invInfo.getArgs()[0];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn.rollback();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(SQLException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;TransactionException(e);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}finally{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(conn&nbsp;!=&nbsp;null){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(SQLException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;TransactionException(e,"Close&nbsp;Connection&nbsp;is&nbsp;failure!");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&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;<br />
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;List&nbsp;getNeedTransaction(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List&nbsp;needTransactions&nbsp;=&nbsp;new&nbsp;ArrayList();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;needTransactions.add("insert");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;needTransactions.add("update");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;needTransactions;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;boolean&nbsp;isNeedTransactions(InvokeJniInfo&nbsp;invInfo){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;needTransaction&nbsp;=&nbsp;"";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List&nbsp;needTransactions&nbsp;=&nbsp;getNeedTransaction();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(int&nbsp;i&nbsp;=&nbsp;0;i<needtransactions.size();i++){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;needTransaction&nbsp;=&nbsp;(String)needTransactions.get(i);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(invInfo.getMethod().getName().startsWith(needTransaction)){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;true;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;false;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
<br />
需要注意的是：getNeedTransaction就是需要进行事务处理的方法的开头，这个方法可以写成一个从配置文件里面去读，这里我就写死在里面了。只是对insert和update开头的方法进行事务控制。<br />
2）&nbsp;&nbsp;&nbsp;&nbsp;将Connection对象放在ThreadLocal中<br />
l&nbsp;&nbsp;&nbsp;&nbsp;ConnectionUtil类：<br />
import&nbsp;java.sql.Connection;<br />
<br />
public&nbsp;final&nbsp;class&nbsp;ConnectionUtil&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;static&nbsp;ThreadLocal&nbsp;connections&nbsp;=&nbsp;new&nbsp;ThreadLocal();<br />
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;Connection&nbsp;getConnection(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Connection&nbsp;conn&nbsp;=&nbsp;null;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn&nbsp;=&nbsp;(Connection)&nbsp;connections.get();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(conn&nbsp;==&nbsp;null){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn&nbsp;=&nbsp;getRealConnection();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;connections.set(conn);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;conn;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;realseConnection(Connection&nbsp;conn){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;connections.set(null);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;static&nbsp;Connection&nbsp;getRealConnection()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;实现自己获取连接的代码<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;null;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
l&nbsp;&nbsp;&nbsp;&nbsp;DAO类<br />
public&nbsp;class&nbsp;TestDao&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;insertA(String&nbsp;a,String&nbsp;b){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Connection&nbsp;conn&nbsp;=&nbsp;getConnection();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;<br />
一系列操作<br />
&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;String&nbsp;queryA(Connection&nbsp;con,&#8230;&#8230;.){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Connection&nbsp;conn&nbsp;=&nbsp;getConnection();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;<br />
一系列操作<br />
&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;<br />
}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;updateA(Connection&nbsp;con,&#8230;&#8230;.){<br />
Connection&nbsp;conn&nbsp;=&nbsp;getConnection();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;<br />
一系列操作<br />
&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;<br />
}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;Connection&nbsp;getConnection(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;ConnectionUtil.getConnection();<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
}<br />
l&nbsp;&nbsp;&nbsp;&nbsp;拦截器<br />
import&nbsp;java.sql.Connection;<br />
import&nbsp;java.sql.SQLException;<br />
import&nbsp;java.util.ArrayList;<br />
import&nbsp;java.util.List;<br />
<br />
public&nbsp;class&nbsp;TransactionInterceptor&nbsp;implements&nbsp;Interceptor&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;before(InvokeJniInfo&nbsp;invInfo)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(isNeedTransactions(invInfo)){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Connection&nbsp;conn&nbsp;=&nbsp;getConnection();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn.setAutoCommit(false);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(SQLException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;TransactionException(e);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;after(InvokeJniInfo&nbsp;invInfo)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(isNeedTransactions(invInfo)){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Connection&nbsp;conn&nbsp;=&nbsp;getConnection();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn.commit();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(SQLException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;TransactionException(e);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}finally{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(conn&nbsp;!=&nbsp;null){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;releaseConnection(conn);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(SQLException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;TransactionException(e,"Close&nbsp;Connection&nbsp;is&nbsp;failure!");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;exceptionThrow(InvokeJniInfo&nbsp;invInfo)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(isNeedTransactions(invInfo)){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Connection&nbsp;conn&nbsp;=&nbsp;getConnection();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn.rollback();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(SQLException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;TransactionException(e);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}finally{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(conn&nbsp;!=&nbsp;null){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;releaseConnection(conn);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(SQLException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;TransactionException(e,"Close&nbsp;Connection&nbsp;is&nbsp;failure!");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&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;<br />
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;Connection&nbsp;getConnection(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;ConnectionUtil.getConnection();<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;void&nbsp;releaseConnection(Connection&nbsp;conn){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ConnectionUtil.releaseConnection(conn);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;List&nbsp;getNeedTransaction(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List&nbsp;needTransactions&nbsp;=&nbsp;new&nbsp;ArrayList();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;needTransactions.add("insert");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;needTransactions.add("update");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;needTransactions;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;boolean&nbsp;isNeedTransactions(InvokeJniInfo&nbsp;invInfo){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;needTransaction&nbsp;=&nbsp;"";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List&nbsp;needTransactions&nbsp;=&nbsp;getNeedTransaction();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(int&nbsp;i&nbsp;=&nbsp;0;i<needtransactions.size();i++){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;needTransaction&nbsp;=&nbsp;(String)needTransactions.get(i);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(invInfo.getMethod().getName().startsWith(needTransaction)){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;true;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;false;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
&nbsp;&nbsp;&nbsp;&nbsp;最后将这个拦截器添加到AOP拦截框架中去，InterceptorHandler类中的getIntercetors方法中添加一个：<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;synchronized&nbsp;List&nbsp;getIntercetors(){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(null&nbsp;==&nbsp;interceptors){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;interceptors&nbsp;=&nbsp;new&nbsp;ArrayList();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;<br />
interceptors.add(new&nbsp;TransactionInterceptor&nbsp;());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;interceptors;<br />
}<br />
</span></div>
<img src ="http://www.blogjava.net/lifenote/aggbug/194687.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lifenote/" target="_blank">LifeNote</a> 2008-04-22 09:54 <a href="http://www.blogjava.net/lifenote/archive/2008/04/22/194687.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Hibernate中Criteria的完整用法 </title><link>http://www.blogjava.net/lifenote/archive/2008/03/12/185708.html</link><dc:creator>LifeNote</dc:creator><author>LifeNote</author><pubDate>Wed, 12 Mar 2008 07:24:00 GMT</pubDate><guid>http://www.blogjava.net/lifenote/archive/2008/03/12/185708.html</guid><wfw:comment>http://www.blogjava.net/lifenote/comments/185708.html</wfw:comment><comments>http://www.blogjava.net/lifenote/archive/2008/03/12/185708.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/lifenote/comments/commentRss/185708.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lifenote/services/trackbacks/185708.html</trackback:ping><description><![CDATA[最近在项目中使用 Spring 和 Hibernate 进行开发，有感于 Criteria 比较好用，在查询方法<br />
<br />
<font face="Times New Roman" size="4">设计上可以灵活的根据 Criteria 的特点来方便地进行查询条件的组装。现在对 Hibernate的Criteria 的用法进行总结：</font><br />
<font face="Times New Roman" size="4">&nbsp;&nbsp; Hibernate 设计了 CriteriaSpecification 作为 Criteria 的父接口，下面提供了 Criteria和DetachedCriteria </font>。 <br />
&nbsp;&nbsp; Criteria 和 DetachedCriteria 的主要区别在于创建的形式不一样， Criteria 是在线的，所</font><br />
<font face="Times New Roman" size="4">以它是由 Hibernate Session 进行创建的；而 DetachedCriteria 是离线的，创建时无需 </font><br />
<font face="Times New Roman" size="4">Session，DetachedCriteria 提供了 2 个静态方法 forClass(Class) 或 forEntityName(Name) </font><br />
<font face="Times New Roman" size="4">进行DetachedCriteria 实例的创建。 Spring 的框架提供了getHibernateTemplate</font><br />
<font face="Times New Roman" size="4">().findByCriteria(detachedCriteria) 方法可以很方便地根据DetachedCriteria 来返回查询结</font><br />
<font face="Times New Roman" size="4">果。 <br />
&nbsp;&nbsp; Criteria 和 DetachedCriteria 均可使用 Criterion 和 Projection 设置查询条件。可以设</font><br />
<font face="Times New Roman" size="4">置 FetchMode( 联合查询抓取的模式 ) ，设置排序方式。对于 Criteria 还可以设置 FlushModel </font><br />
<font face="Times New Roman" size="4">（冲刷 Session 的方式）和 LockMode （数据库锁模式）。 </font><br />
<font face="Times New Roman" size="4">下面对 Criterion 和 Projection 进行详细说明。</font><br />
<font face="Times New Roman" size="4">&nbsp;&nbsp;&nbsp;&nbsp; Criterion 是 Criteria 的查询条件。Criteria 提供了 add(Criterion criterion) 方法来</font><br />
<font face="Times New Roman" size="4">添加查询条件。<br />
&nbsp;&nbsp;&nbsp;&nbsp; Criterion 接口的主要实现包括： Example 、 Junction 和 SimpleExpression 。而 </font><br />
<font face="Times New Roman" size="4">Junction 的实际使用是它的两个子类 conjunction 和 disjunction ，分别是使用 AND 和 OR 操</font><br />
<font face="Times New Roman" size="4">作符进行来联结查询条件集合。<br />
&nbsp;&nbsp;&nbsp;&nbsp; Criterion 的实例可以通过 Restrictions 工具类来创建，Restrictions 提供了大量的静态</font><br />
<font face="Times New Roman" size="4">方法，如 eq （等于）、 ge （大于等于）、 between 等来方法的创建 Criterion 查询条件 </font><br />
<font face="Times New Roman" size="4">（SimpleExpression 实例）。除此之外， Restrictions 还提供了方法来创建 conjunction 和 </font><br />
<font face="Times New Roman" size="4">disjunction 实例，通过往该实例的 add(Criteria) 方法来增加查询条件形成一个查询条件集合</font><br />
<font face="Times New Roman" size="4">。<br />
&nbsp;&nbsp;&nbsp;&nbsp; 至于 Example 的创建有所不同， Example 本身提供了一个静态方法 create(Object </font><br />
<font face="Times New Roman" size="4">entity) ，即根据一个对象（实际使用中一般是映射到数据库的对象）来创建。然后可以设置一些</font><br />
<font face="Times New Roman" size="4">过滤条件： <br />
Example exampleUser =Example.create(u) <br />
.ignoreCase() // 忽略大小写 <br />
.enableLike(MatchMode.ANYWHERE); <br />
// 对 String 类型的属性，无论在那里值在那里都匹配。相当于 %value% </font><br />
<font face="Times New Roman" size="4">&nbsp; Project 主要是让 Criteria 能够进行报表查询，并可以实现分组。 Project 主要有 </font><br />
<font face="Times New Roman" size="4">SimpleProjection 、 ProjectionList 和 Property 三个实现。其中 SimpleProjection 和 </font><br />
<font face="Times New Roman" size="4">ProjectionList 的实例化是由内建的 Projections 来完成，如提供的 avg 、 count 、 max 、 </font><br />
<font face="Times New Roman" size="4">min 、 sum 可以让开发者很容易对某个字段进行统计查询。 <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property 是对某个字段进行查询条件的设置，如通过Porperty.forName(&#8220;color&#8221;).in</font><br />
<font face="Times New Roman" size="4">(new String[]{&#8220;black&#8221;,&#8221;red&#8221;,&#8221;write&#8221;}); 则可以创建一个 Project 实例。通过 </font><br />
<font face="Times New Roman" size="4">criteria 的 add(Project) 方法加入到查询条件中去。 </font><br />
<font face="Times New Roman" size="4">&nbsp;&nbsp;&nbsp; 使用 Criteria 进行查询，主要要清晰的是 Hibernate 提供了那些类和方法来满足开发中查</font><br />
<font face="Times New Roman" size="4">询条件的创建和组装，下面介绍几种用法：</font><br />
<font face="Times New Roman" size="4">1. 创建一个Criteria 实例<br />
org.hibernate.Criteria接口表示特定持久类的一个查询。Session是 Criteria实例的工厂。<br />
Criteria crit = sess.createCriteria(Cat.class);<br />
crit.setMaxResults(50);<br />
List cats = crit.list();<br />
&nbsp;<br />
2. 限制结果集内容<br />
一个单独的查询条件是org.hibernate.criterion.Criterion 接口的一个实例。</font><br />
<br />
<font face="Times New Roman" size="4">org.hibernate.criterion.Restrictions类 定义了获得某些内置Criterion类型的工厂方法。<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .add( Restrictions.like("name", "Fritz%") )<br />
&nbsp;&nbsp;&nbsp; .add( Restrictions.between("weight", minWeight, maxWeight) )<br />
&nbsp;&nbsp;&nbsp; .list();</font><br />
<br />
<font face="Times New Roman" size="4">约束可以按逻辑分组。 <br />
&nbsp;<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .add( Restrictions.like("name", "Fritz%") )<br />
&nbsp;&nbsp;&nbsp; .add( Restrictions.or(<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Restrictions.eq( "age", new Integer(0) ),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Restrictions.isNull("age")<br />
&nbsp;&nbsp;&nbsp; ) )<br />
&nbsp;&nbsp;&nbsp; .list();<br />
&nbsp;<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .add( Restrictions.in( "name", new String[] { "Fritz", "Izi", "Pk" } ) )<br />
&nbsp;&nbsp;&nbsp; .add( Restrictions.disjunction()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Restrictions.isNull("age") )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Restrictions.eq("age", new Integer(0) ) )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Restrictions.eq("age", new Integer(1) ) )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Restrictions.eq("age", new Integer(2) ) )<br />
&nbsp;&nbsp;&nbsp; ) )<br />
&nbsp;&nbsp;&nbsp; .list();<br />
&nbsp;<br />
Hibernate提供了相当多的内置criterion类型(Restrictions 子类), 但是尤其有用的是可以允许</font><br />
<br />
<font face="Times New Roman" size="4">你直接使用SQL。<br />
&nbsp;<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .add( Restrictions.sql("lower({alias}.name) like lower(?)", "Fritz%", </font><br />
<br />
<font face="Times New Roman" size="4">Hibernate.STRING) )<br />
&nbsp;&nbsp;&nbsp; .list();<br />
&nbsp;<br />
{alias}占位符应当被替换为被查询实体的列别名。 <br />
Property实例是获得一个条件的另外一种途径。你可以通过调用Property.forName() 创建一个</font><br />
<br />
<font face="Times New Roman" size="4">Property。 <br />
&nbsp;<br />
&nbsp; Property age = Property.forName("age");<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .add( Restrictions.disjunction()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( age.isNull() )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( age.eq( new Integer(0) ) )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( age.eq( new Integer(1) ) )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( age.eq( new Integer(2) ) )<br />
&nbsp;&nbsp;&nbsp; ) )<br />
&nbsp;&nbsp;&nbsp; .add( Property.forName("name").in( new String[] { "Fritz", "Izi", "Pk" } ) )<br />
&nbsp;&nbsp;&nbsp; .list();<br />
&nbsp;<br />
3. 结果集排序<br />
你可以使用org.hibernate.criterion.Order来为查询结果排序。 <br />
&nbsp;<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .add( Restrictions.like("name", "F%")<br />
&nbsp;&nbsp;&nbsp; .addOrder( Order.asc("name") )<br />
&nbsp;&nbsp;&nbsp; .addOrder( Order.desc("age") )<br />
&nbsp;&nbsp;&nbsp; .setMaxResults(50)<br />
&nbsp;&nbsp;&nbsp; .list();<br />
&nbsp;<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .add( Property.forName("name").like("F%") )<br />
&nbsp;&nbsp;&nbsp; .addOrder( Property.forName("name").asc() )<br />
&nbsp;&nbsp;&nbsp; .addOrder( Property.forName("age").desc() )<br />
&nbsp;&nbsp;&nbsp; .setMaxResults(50)<br />
&nbsp;&nbsp;&nbsp; .list();<br />
&nbsp;<br />
4. 关联<br />
你可以使用createCriteria()非常容易的在互相关联的实体间建立 约束。<br />
&nbsp;<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .add( Restrictions.like("name", "F%")<br />
&nbsp;&nbsp;&nbsp; .createCriteria("kittens")<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Restrictions.like("name", "F%")<br />
&nbsp;&nbsp;&nbsp; .list();</font><br />
<br />
<font face="Times New Roman" size="4"><br />
注意第二个 createCriteria()返回一个新的 Criteria实例，该实例引用kittens 集合中的元素。 <br />
接下来，替换形态在某些情况下也是很有用的。<br />
&nbsp;<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .createAlias("kittens", "kt")<br />
&nbsp;&nbsp;&nbsp; .createAlias("mate", "mt")<br />
&nbsp;&nbsp;&nbsp; .add( Restrictions.eqProperty("kt.name", "mt.name") )<br />
&nbsp;&nbsp;&nbsp; .list();</font><br />
<br />
<font face="Times New Roman" size="4"><br />
(createAlias()并不创建一个新的 Criteria实例。) <br />
Cat实例所保存的之前两次查询所返回的kittens集合是 没有被条件预过滤的。如果你希望只获得</font><br />
<br />
<font face="Times New Roman" size="4">符合条件的kittens， 你必须使用returnMaps()。 <br />
&nbsp;<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .createCriteria("kittens", "kt")<br />
&nbsp;&nbsp;&nbsp; .add( Restrictions.eq("name", "F%") )<br />
&nbsp;&nbsp;&nbsp; .returnMaps()<br />
&nbsp;&nbsp;&nbsp; .list();<br />
Iterator iter = cats.iterator();<br />
while ( iter.hasNext() ) {<br />
&nbsp;&nbsp;&nbsp; Map map = (Map) iter.next();<br />
&nbsp;&nbsp;&nbsp; Cat cat = (Cat) map.get(Criteria.ROOT_ALIAS);<br />
&nbsp;&nbsp;&nbsp; Cat kitten = (Cat) map.get("kt");<br />
}</font><br />
<br />
<font face="Times New Roman" size="4">5. 动态关联抓取<br />
你可以使用setFetchMode()在运行时定义动态关联抓取的语义。 <br />
&nbsp;<br />
List cats = sess.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .add( Restrictions.like("name", "Fritz%") )<br />
&nbsp;&nbsp;&nbsp; .setFetchMode("mate", FetchMode.EAGER)<br />
&nbsp;&nbsp;&nbsp; .setFetchMode("kittens", FetchMode.EAGER)<br />
&nbsp;&nbsp;&nbsp; .list();<br />
&nbsp;<br />
这个查询可以通过外连接抓取mate和kittens。<br />
&nbsp;<br />
6. 查询示例<br />
org.hibernate.criterion.Example类允许你通过一个给定实例 构建一个条件查询。<br />
&nbsp;<br />
Cat cat = new Cat();<br />
cat.setSex('F');<br />
cat.setColor(Color.BLACK);<br />
List results = session.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .add( Example.create(cat) )<br />
&nbsp;&nbsp;&nbsp; .list();</font><br />
<br />
<font face="Times New Roman" size="4"><br />
版本属性、标识符和关联被忽略。默认情况下值为null的属性将被排除。 <br />
可以自行调整Example使之更实用。 <br />
&nbsp;<br />
Example example = Example.create(cat)<br />
&nbsp;&nbsp;&nbsp; .excludeZeroes()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //exclude zero valued properties<br />
&nbsp;&nbsp;&nbsp; .excludeProperty("color")&nbsp; //exclude the property named "color"<br />
&nbsp;&nbsp;&nbsp; .ignoreCase()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //perform case insensitive string comparisons<br />
&nbsp;&nbsp;&nbsp; .enableLike();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //use like for string comparisons<br />
List results = session.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .add(example)<br />
&nbsp;&nbsp;&nbsp; .list();</font><br />
<br />
<font face="Times New Roman" size="4"><br />
甚至可以使用examples在关联对象上放置条件。<br />
&nbsp;<br />
List results = session.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .add( Example.create(cat) )<br />
&nbsp;&nbsp;&nbsp; .createCriteria("mate")<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Example.create( cat.getMate() ) )<br />
&nbsp;&nbsp;&nbsp; .list();</font><br />
<br />
<font face="Times New Roman" size="4"><br />
7. 投影(Projections)、聚合（aggregation）和分组（grouping）<br />
org.hibernate.criterion.Projections是 Projection 的实例工厂。我们通过调用 </font><br />
<br />
<font face="Times New Roman" size="4">setProjection()应用投影到一个查询。 <br />
&nbsp;<br />
List results = session.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .setProjection( Projections.rowCount() )<br />
&nbsp;&nbsp;&nbsp; .add( Restrictions.eq("color", Color.BLACK) )<br />
&nbsp;&nbsp;&nbsp; .list();<br />
&nbsp;<br />
List results = session.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .setProjection( Projections.projectionList()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Projections.rowCount() )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Projections.avg("weight") )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Projections.max("weight") )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Projections.groupProperty("color") )<br />
&nbsp;&nbsp;&nbsp; )<br />
&nbsp;&nbsp;&nbsp; .list();</font><br />

<p><font face="Times New Roman" size="4"><br />
在一个条件查询中没有必要显式的使用 "group by" 。某些投影类型就是被定义为 分组投影，他</font><br />
<br />
<font face="Times New Roman" size="4">们也出现在SQL的group by子句中。 </font><br />
<br />
<font face="Times New Roman" size="4">可以选择把一个别名指派给一个投影，这样可以使投影值被约束或排序所引用。下面是两种不同的</font><br />
<br />
<font face="Times New Roman" size="4">实现方式：<br />
&nbsp;<br />
List results = session.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .setProjection( Projections.alias( Projections.groupProperty("color"), "colr" ) )<br />
&nbsp;&nbsp;&nbsp; .addOrder( Order.asc("colr") )<br />
&nbsp;&nbsp;&nbsp; .list();</font></p>
<br />

<p><font face="Times New Roman" size="4">List results = session.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .setProjection( Projections.groupProperty("color").as("colr") )<br />
&nbsp;&nbsp;&nbsp; .addOrder( Order.asc("colr") )<br />
&nbsp;&nbsp;&nbsp; .list();<br />
&nbsp;<br />
alias()和as()方法简便的将一个投影实例包装到另外一个 别名的Projection实例中。简而言之，</font><br />
<br />
<font face="Times New Roman" size="4">当你添加一个投影到一个投影列表中时 你可以为它指定一个别名： <br />
&nbsp;<br />
List results = session.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .setProjection( Projections.projectionList()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Projections.rowCount(), "catCountByColor" )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Projections.avg("weight"), "avgWeight" )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Projections.max("weight"), "maxWeight" )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Projections.groupProperty("color"), "color" )<br />
&nbsp;&nbsp;&nbsp; )<br />
&nbsp;&nbsp;&nbsp; .addOrder( Order.desc("catCountByColor") )<br />
&nbsp;&nbsp;&nbsp; .addOrder( Order.desc("avgWeight") )<br />
&nbsp;&nbsp;&nbsp; .list();</font><br />
<br />
<font face="Times New Roman" size="4"><br />
List results = session.createCriteria(Domestic.class, "cat")<br />
&nbsp;&nbsp;&nbsp; .createAlias("kittens", "kit")<br />
&nbsp;&nbsp;&nbsp; .setProjection( Projections.projectionList()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Projections.property("cat.name"), "catName" )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Projections.property("kit.name"), "kitName" )<br />
&nbsp;&nbsp;&nbsp; )<br />
&nbsp;&nbsp;&nbsp; .addOrder( Order.asc("catName") )<br />
&nbsp;&nbsp;&nbsp; .addOrder( Order.asc("kitName") )<br />
&nbsp;&nbsp;&nbsp; .list();</font><br />
<br />
<font face="Times New Roman" size="4"><br />
也可以使用Property.forName()来表示投影：<br />
&nbsp;<br />
List results = session.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .setProjection( Property.forName("name") )<br />
&nbsp;&nbsp;&nbsp; .add( Property.forName("color").eq(Color.BLACK) )<br />
&nbsp;&nbsp;&nbsp; .list();</font><br />
<font face="Times New Roman" size="4">List results = session.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .setProjection( Projections.projectionList()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Projections.rowCount().as("catCountByColor") )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Property.forName("weight").avg().as("avgWeight") )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Property.forName("weight").max().as("maxWeight") )<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .add( Property.forName("color").group().as("color" )<br />
&nbsp;&nbsp;&nbsp; )<br />
&nbsp;&nbsp;&nbsp; .addOrder( Order.desc("catCountByColor") )<br />
&nbsp;&nbsp;&nbsp; .addOrder( Order.desc("avgWeight") )<br />
&nbsp;&nbsp;&nbsp; .list();</font><br />
<br />
<font face="Times New Roman" size="4"><br />
8. 离线(detached)查询和子查询<br />
DetachedCriteria类使你在一个session范围之外创建一个查询，并且可以使用任意的 Session来</font><br />
<br />
<font face="Times New Roman" size="4">执行它。<br />
&nbsp;<br />
DetachedCriteria query = DetachedCriteria.forClass(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .add( Property.forName("sex").eq('F') );<br />
//创建一个Session<br />
Session session = .;<br />
Transaction txn = session.beginTransaction();<br />
List results = query.getExecutableCriteria(session).setMaxResults(100).list();<br />
txn.commit();<br />
session.close();</font><br />
<br />
<font face="Times New Roman" size="4"><br />
DetachedCriteria也可以用以表示子查询。条件实例包含子查询可以通过 Subqueries或者</font><br />
<font face="Times New Roman" size="4">Property获得。<br />
&nbsp;<br />
DetachedCriteria avgWeight = DetachedCriteria.forClass(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .setProjection( Property.forName("weight").avg() );<br />
session.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .add( Property.forName("weight).gt(avgWeight) )<br />
&nbsp;&nbsp;&nbsp; .list();</font><br />
<font face="Times New Roman" size="4">DetachedCriteria weights = DetachedCriteria.forClass(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .setProjection( Property.forName("weight") );<br />
session.createCriteria(Cat.class)<br />
&nbsp;&nbsp;&nbsp; .add( Subqueries.geAll("weight", weights) )<br />
&nbsp;&nbsp;&nbsp; .list();</font><br />
<font face="Times New Roman" size="4"><br />
相互关联的子查询也是有可能的：<br />
&nbsp;<br />
DetachedCriteria avgWeightForSex = DetachedCriteria.forClass(Cat.class, "cat2")<br />
&nbsp;&nbsp;&nbsp; .setProjection( Property.forName("weight").avg() )<br />
&nbsp;&nbsp;&nbsp; .add( Property.forName("cat2.sex").eqProperty("cat.sex") );<br />
session.createCriteria(Cat.class, "cat")<br />
&nbsp;&nbsp;&nbsp; .add( Property.forName("weight).gt(avgWeightForSex) )<br />
&nbsp;&nbsp;&nbsp; .list();<br />
</font></p>
<img src ="http://www.blogjava.net/lifenote/aggbug/185708.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lifenote/" target="_blank">LifeNote</a> 2008-03-12 15:24 <a href="http://www.blogjava.net/lifenote/archive/2008/03/12/185708.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>深入理解Tapestry的Rewind</title><link>http://www.blogjava.net/lifenote/archive/2008/03/08/184695.html</link><dc:creator>LifeNote</dc:creator><author>LifeNote</author><pubDate>Sat, 08 Mar 2008 08:03:00 GMT</pubDate><guid>http://www.blogjava.net/lifenote/archive/2008/03/08/184695.html</guid><wfw:comment>http://www.blogjava.net/lifenote/comments/184695.html</wfw:comment><comments>http://www.blogjava.net/lifenote/archive/2008/03/08/184695.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lifenote/comments/commentRss/184695.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lifenote/services/trackbacks/184695.html</trackback:ping><description><![CDATA[Tapestry的rewind一直是学习和使用Tapestry的难点，rewind是用来处理表单提交的，表单默认使用的是DirectService来提交。在详细介绍之前，先说明下此文中需要用到的一些概念，首先是表单组件，我这里指的是指继承自AbstractFormComponent类的组件，例如：TextField、TextArea、Checkbox等，而不是具体的Form组件，表单组件使用时必须在Form组件中，这些组件在rewind时调用继承自AbstractFormComponent的rewindFormComponent来读取数据，并将数据赋值给容器或者页面。 <br />
我们来看一下最简单的TextField组件，组件定义如下 <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://www.javaeye.com/article/41724#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span>&lt;input&nbsp;&nbsp;jwcid=</span><span class="string">"price@TextField"</span><span>&nbsp;type=</span><span class="string">"text"</span><span>&nbsp;value=</span><span class="string">"ognl:picture.price"</span><span>&nbsp;&nbsp;translator=</span><span class="string">"translator:number,pattern=##.##"</span><span>&nbsp;&nbsp;validators=</span><span class="string">"validators:min=0"</span><span>&nbsp;displayName=</span><span class="string">"价格"</span><span>&nbsp;</span><span class="keyword">class</span><span>=</span><span class="string">"input_text"</span><span>/&gt;&nbsp;&nbsp;</span></span> </li>
</ol>
</div>
<pre class="java" style="display: none" name="code">&lt;input  jwcid="price@TextField" type="text" value="ognl:picture.price"  translator="translator:number,pattern=##.##"  validators="validators:min=0" displayName="价格" class="input_text"/&gt;</pre>
<br />
再看一下TextField中的rewindFormComponent组件方法 <br />
<div class="dp-highlighter">
<div class="bar">
<div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://www.javaeye.com/article/41724#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div>
</div>
<ol class="dp-j">
    <li><span><span class="keyword">protected</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;rewindFormComponent(IMarkupWriter&nbsp;writer,&nbsp;IRequestCycle&nbsp;cycle)&nbsp;{ &nbsp;&nbsp;</span></span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//从请求中得到参数值 </span><span>&nbsp;&nbsp;</span></span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;value&nbsp;=&nbsp;cycle.getParameter(getName()); &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">try</span><span>&nbsp;{ &nbsp;&nbsp;</span></span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//用translator来转换值 </span><span>&nbsp;&nbsp;</span></span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object&nbsp;object&nbsp;=&nbsp;getTranslatedFieldSupport().parse(</span><span class="keyword">this</span><span>,&nbsp;value); &nbsp;&nbsp;</span></span>
    <li><span class="comment">//用validators来验证值 </span><span>&nbsp;&nbsp;</span></span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getValidatableFieldSupport().validate(</span><span class="keyword">this</span><span>,&nbsp;writer,&nbsp;cycle,&nbsp;object); &nbsp;&nbsp;</span></span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//赋值给容器或者页面 </span><span>&nbsp;&nbsp;</span></span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setValue(object); &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span class="keyword">catch</span><span>&nbsp;(ValidatorException&nbsp;e)&nbsp;{ &nbsp;&nbsp;</span></span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getForm().getDelegate().record(e); &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span> </li>
</ol>
</div>
<pre class="java" style="display: none" name="code">protected void rewindFormComponent(IMarkupWriter writer, IRequestCycle cycle) {
//从请求中得到参数值
String value = cycle.getParameter(getName());
try {
//用translator来转换值
Object object = getTranslatedFieldSupport().parse(this, value);
//用validators来验证值
getValidatableFieldSupport().validate(this, writer, cycle, object);
//赋值给容器或者页面
setValue(object);
} catch (ValidatorException e) {
getForm().getDelegate().record(e);
}
}</pre>
<br />
可以看到在rewindFormComponent中，主要是从请求中取得用户输入的值，然后进行处理，最后赋值给容器或者页面，上面的例子中会调用页面类的getPicture().setPrice(&#8220;用户输入的值&#8221;)来进行赋值。这样整个表单的提交就可以理解为所有的表单组件读取用户输入的值并赋值给页面的过程。 <br />
整个表单提交的详细处理过程如下： <br />
<ul>* initialize():页面初始化 <br />
    * pageBeginRender() ("rewind"):getRequestCycle().<span class="hilite1"><span class="hilite1">isRewinding</span></span>()为true <br />
    * rewind of the form / setting of properties:所有表单组件调用rewindFormComponent来取值赋值 <br />
    * Deferred listeners (for Submit components):调用Submit组件的listener <br />
    * Form's listener：调用Form组件的listener <br />
    * pageEndRender() ("rewind"): getRequestCycle().<span class="hilite1"><span class="hilite1">isRewinding</span></span>()为true <br />
    * pageBeginRender() (normal): getRequestCycle().<span class="hilite1"><span class="hilite1">isRewinding</span></span>()为false <br />
    * pageEndRender() (normal): getRequestCycle().<span class="hilite1"><span class="hilite1">isRewinding</span></span>()为false</ul>
    我们可以看到pageBeginRender和pageEndRender被调用了两次，两次中的区别为RequestCycle().<span class="hilite1"><span class="hilite1">isRewinding</span></span>，因为我们在使用时经常利用pageBeginRender的初始化值，所以这里有很多使用上的误区，如果在pageBeginRender中从数据库读取数据来初始化跟表单提交无关的变量的话，就可能被调用两次，这个是应该避免的。什么叫跟表单提交无关的变量呢，就是表单组件中跟赋值无关的，例如上边提到的value="ognl:picture.price",这时picture就是与表单提交相关的变量，如果你没有初始化，那么在赋值时调用getPicture().setPrice()就会出现空指针异常，因为这是的picture为null。我们举个例子来看一下表单无关的变量，假如这个picture页面会显示一个创建picture的表单和所有picture的列表，那这个picture的列表就是与表单提交无关的变量，如果你在pageBeginRender中初始化的话，就需要区分是否rewind，否则表单提交时就会被初始化两次，让我们看一下代码： <br />
    <div class="dp-highlighter">
    <div class="bar">
    <div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://www.javaeye.com/article/41724#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div>
    </div>
    <ol class="dp-j">
        <li><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">abstract</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;setPictures(List&lt;Picture&gt;&nbsp;pictures); &nbsp;&nbsp;</span></span>
        <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">abstract</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;setPictureInList();</span><span class="comment">//用于For中的value </span><span>&nbsp;&nbsp;</span></span>
        <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">abstract</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;setPicture(Picture&nbsp;picture);</span><span class="comment">//用于表单创建 </span><span>&nbsp;&nbsp;</span></span>
        <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">abstract</span><span>&nbsp;Picture&nbsp;getPicture(); &nbsp;&nbsp;</span></span>
        <li><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;pageBeginRender(PageEvent&nbsp;event)&nbsp;{ &nbsp;&nbsp;</span></span>
        <li><span class="keyword">if</span><span>(getPicture()==</span><span class="keyword">null</span><span>){ &nbsp;&nbsp;</span></span>
        <li><span>setPicture(</span><span class="keyword">new</span><span>&nbsp;Picture()); &nbsp;&nbsp;</span></span>
        <li><span>} &nbsp;&nbsp;</span>
        <li><span>setPictures(getPictureService().findAll()); &nbsp;&nbsp;</span>
        <li><span>}&nbsp;&nbsp;</span> </li>
    </ol>
    </div>
    <pre class="java" style="display: none" name="code">public abstract void setPictures(List&lt;Picture&gt; pictures);
    public abstract void setPictureInList();//用于For中的value
    public abstract void setPicture(Picture picture);//用于表单创建
    public abstract Picture getPicture();
    public void pageBeginRender(PageEvent event) {
    if(getPicture()==null){
    setPicture(new Picture());
    }
    setPictures(getPictureService().findAll());
    }</pre>
    判断picture是否为null并赋值在页面显示和rewind中都是需要的，因为页面显示时，需要调用getPicture().getPrice(),页面rewind时，需要调用getPicture().setPrice(),这两个阶段中的picture都不能为null。但setPictures会在表单提交时被调用两次，在rewind阶段初始化它是没有用处的，所以这时就要对是否rewind进行判断。修改后的代码如下： <br />
    <div class="dp-highlighter">
    <div class="bar">
    <div class="tools">Java代码 <a title="复制代码" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;" href="http://www.javaeye.com/article/41724#"><img alt="复制代码" src="http://www.javaeye.com/images/icon_copy.gif" _counted="undefined" /></a></div>
    </div>
    <ol class="dp-j">
        <li><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;pageBeginRender(PageEvent&nbsp;event)&nbsp;{ &nbsp;&nbsp;</span></span>
        <li><span class="keyword">if</span><span>(getPicture()==</span><span class="keyword">null</span><span>){ &nbsp;&nbsp;</span></span>
        <li><span>setPicture(</span><span class="keyword">new</span><span>&nbsp;Picture()); &nbsp;&nbsp;</span></span>
        <li><span>} &nbsp;&nbsp;</span>
        <li><span class="keyword">if</span><span>&nbsp;(!event.getRequestCycle().<span class="hilite1"><span class="hilite1">isRewinding</span></span>())&nbsp;{ &nbsp;&nbsp;</span></span>
        <li><span>setPictures(getPictureService().findAll()); &nbsp;&nbsp;</span>
        <li><span>} &nbsp;&nbsp;</span>
        <li><span>}&nbsp;&nbsp;</span> </li>
    </ol>
    </div>
    <pre class="java" style="display: none" name="code">public void pageBeginRender(PageEvent event) {
    if(getPicture()==null){
    setPicture(new Picture());
    }
    if (!event.getRequestCycle().<span class="hilite1"><span class="hilite1">isRewinding</span></span>()) {
    setPictures(getPictureService().findAll());
    }
    }</pre>
    这样就可以避免在rewind时对pictures进行不必要的赋值。这里还要提到的一点是页面显示和提交后的页面很可能不是同一个页面类的实例，大家都知道页面类的实例是从实例池取到的，用户打开页面显示表单完后的页面类实例和用户提交表单时的用来rewind的页面类实例不一定是同一个，即使是一个实例，也是被重新初始化过的，不要想当然的认为显示表单后再提交那个实例应该保存原来显示的东西，这个应该理清楚。 <br />
    <br />
    原文地址：http://www.javaeye.com/article/41724
<img src ="http://www.blogjava.net/lifenote/aggbug/184695.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lifenote/" target="_blank">LifeNote</a> 2008-03-08 16:03 <a href="http://www.blogjava.net/lifenote/archive/2008/03/08/184695.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《J2EE核心模式》(DAO模式)</title><link>http://www.blogjava.net/lifenote/archive/2008/02/15/180110.html</link><dc:creator>LifeNote</dc:creator><author>LifeNote</author><pubDate>Fri, 15 Feb 2008 09:09:00 GMT</pubDate><guid>http://www.blogjava.net/lifenote/archive/2008/02/15/180110.html</guid><wfw:comment>http://www.blogjava.net/lifenote/comments/180110.html</wfw:comment><comments>http://www.blogjava.net/lifenote/archive/2008/02/15/180110.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/lifenote/comments/commentRss/180110.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lifenote/services/trackbacks/180110.html</trackback:ping><description><![CDATA[<p>很多的J2EE应用程序需要使用持久性数据(数据库、文件等)。不同的程序，持久性存储是各不相同的，并且用来访问这些不同的持久性存储机制的API也有很大的不同。如果应用程序要在不同的持久性存储间迁移，这些访问特定持久存储层的代码将面临重写。<br />
如何解决这个问题?且看"DAO模式"</p>
<p>数据访问对象(Data&nbsp;Acess&nbsp;Object)&nbsp;模式<br />
一.环境<br />
根据数据源不同，数据访问也不同。根据存储的类型(关系数据库、面向对象数据库、文件等等)和供应商实现不同，持久性存储(比如数据库)的访问差别也很大</p>
<p>二.问题<br />
许多真是的J2EE应用程序需要在一定程度上使用持久性数据。对于许多应用程序，持久性存储是使用不同的机制实现的,并且用来访问这些不同的持久性存储机制的API也有很大的不同。<br />
比如，应用程序使用实体bean(这里应该是指BMP的bean，CMP的bean已大大降低了与RDBMS的耦合)的分布式组件来表示持久性数据，或者使用JDBC&nbsp;API来访问驻留在某关系数据库管理系统(RDBMS)中的数据，这些组件中包含连接性性和数据访问代码会引入这些组件与数据源实现之间的紧密耦合。组件中这类代码依赖性使应用程序从某种数据源迁移到其他种类的数据源将变得非常麻烦和困难。当数据源变化时，组件也需要改变，以便于能够处理新类型的数据源</p>
<p>(举个例子来说，我们UPTEL系统是使用JDBC&nbsp;API对&nbsp;ORACLE数据库进行连接和数据访问的，这些JDBC&nbsp;API与SQL语句散布在系统中，当我们需要将UPTEL迁移到其他RDBMS时，比如曾经迁移到INFORMIX，就面临重写数据库连接和访问数据的模块。)</p>
<p>三.作用力<br />
1.诸如bean管理的实体bean、会话bean、servlet等组件往往需要从持久性存储数据源中检索数据，以及进行数据存储等操作。<br />
2.根据产品供应商的不同，持久性存储API差别也很大，这些API和其能力同样根据存储的类型不同也有差别，这样存在以下缺点，即访问这些独立系统的API很不统一。<br />
3.组件需要透明于实际的持久性存储或者数据源实现，以便于提供到不同供应商产品、不同存储类型和不同数据源类型的更容易的移植性。</p>
<p>四.解决方案<br />
使用数据访问对象(DAO)模式来抽象和封装所有对数据源的访问。DAO管理着与数据源的连接以便检索和存储数据。<br />
DAO实现了用来操作数据源的访问机制。数据源可以时RDBMS,LDAP,File等。依赖于DAO的业务组件为其客户端使用DAO提供更简单的接口。DAO完全向客户端隐藏了数据源实现细节。由于当低层数据源实现变化时，DAO向客户端提供的接口不会变化，所有该模式允许DAO调整到不同的存储模式，而不会影响其客户端或者业务组件。重要的是,DAO充当组件和数据源之间的适配器。</p>
<p>(按照这个理论，如果我们UPTEL系统使用了DAO模式,就可以无缝的从ORACLE迁移到任何一个RDBMS了。梦想总是很完美的，且看看DAO模式如何实现)</p>
 <img src ="http://www.blogjava.net/lifenote/aggbug/180110.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lifenote/" target="_blank">LifeNote</a> 2008-02-15 17:09 <a href="http://www.blogjava.net/lifenote/archive/2008/02/15/180110.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JSF中文输入乱码问题解决方法</title><link>http://www.blogjava.net/lifenote/archive/2008/01/31/178680.html</link><dc:creator>LifeNote</dc:creator><author>LifeNote</author><pubDate>Thu, 31 Jan 2008 07:05:00 GMT</pubDate><guid>http://www.blogjava.net/lifenote/archive/2008/01/31/178680.html</guid><wfw:comment>http://www.blogjava.net/lifenote/comments/178680.html</wfw:comment><comments>http://www.blogjava.net/lifenote/archive/2008/01/31/178680.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/lifenote/comments/commentRss/178680.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lifenote/services/trackbacks/178680.html</trackback:ping><description><![CDATA[<p class="content">该方法已知适用的版本tomact5.0.18,tomcat5.0.9。<br />
已知不适用的版本为tomcat5.0.28。<br />
问题描述：<br />
在inputtext中输入中文，然后在输出，显示为乱码。<br />
解决方法：<br />
1、自定义转器<br />
package util;<br />
import java.util.Map;<br />
import javax.faces.component.UIComponent;<br />
import javax.faces.convert.Converter;<br />
import javax.faces.context.FacesContext;<br />
import javax.faces.convert.ConverterException; </p>
<p class="content">public class StringConverter implements Converter {<br />
&nbsp;public Object getAsObject(FacesContext context, UIComponent component,<br />
&nbsp;&nbsp;&nbsp;String newValues) throws ConverterException {<br />
&nbsp;&nbsp;String newstr = "";<br />
&nbsp;&nbsp;if (newValues == null) {<br />
&nbsp;&nbsp;&nbsp;newValues = "";<br />
&nbsp;&nbsp;}<br />
&nbsp;&nbsp;byte[] byte1 = null;<br />
&nbsp;&nbsp;try {<br />
&nbsp;&nbsp;&nbsp;byte1 = newValues.getBytes("ISO-8859-1");<br />
&nbsp;&nbsp;&nbsp;newstr = new String(byte1, "GB2312");<br />
&nbsp;&nbsp;&nbsp;UIInput input=(UIInput)component;//<br />
&nbsp;&nbsp;&nbsp;input.setSubmittedValue(newstr);<br />
&nbsp;&nbsp;} catch (UnsupportedEncodingException e) {<br />
&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
&nbsp;&nbsp;}</p>
<p class="content">&nbsp;&nbsp;return newstr;</p>
<p class="content">&nbsp;}</p>
<p class="content">&nbsp;public String getAsString(FacesContext context, UIComponent component,<br />
&nbsp;&nbsp;&nbsp;Object Values) throws ConverterException {&nbsp;<br />
&nbsp;&nbsp;return (String) Values;<br />
&nbsp;}<br />
}</p>
<p class="content">2、注册转换器<br />
faces-config.xml片段<br />
&lt;converter&gt;<br />
&nbsp; &lt;converter-id&gt;util.stringconverter&lt;/converter-id&gt;<br />
&nbsp; &lt;converter-class&gt;util.StringConverter&lt;/converter-class&gt;<br />
&lt;/converter&gt;</p>
<p class="content">3、在页面使用转换器<br />
&lt;h:inputText id="account" value="#{util.account}" required="true" styleClass="input" &gt;&nbsp;<br />
&nbsp;&lt;f:converter converterId="utilstringconverter"/&gt;</p>
<img src ="http://www.blogjava.net/lifenote/aggbug/178680.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lifenote/" target="_blank">LifeNote</a> 2008-01-31 15:05 <a href="http://www.blogjava.net/lifenote/archive/2008/01/31/178680.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Tomcat,Weblogic 等服务器  SSL 安全登陆的例子---附证书文件生成器</title><link>http://www.blogjava.net/lifenote/archive/2008/01/15/175432.html</link><dc:creator>LifeNote</dc:creator><author>LifeNote</author><pubDate>Tue, 15 Jan 2008 04:32:00 GMT</pubDate><guid>http://www.blogjava.net/lifenote/archive/2008/01/15/175432.html</guid><wfw:comment>http://www.blogjava.net/lifenote/comments/175432.html</wfw:comment><comments>http://www.blogjava.net/lifenote/archive/2008/01/15/175432.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/lifenote/comments/commentRss/175432.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lifenote/services/trackbacks/175432.html</trackback:ping><description><![CDATA[<p>公司今天一个登陆的地方要修改，需要加一个SSL安全登陆,于是查些资料并总结如下，希望对有用的着的朋友有帮助<br />
文件打包地址：http://www.blogjava.net/Files/lifenote/tomcat配置ssl.rar<br />
一下为帮助说明：<br />
<br />
1.1.&nbsp;安全登录 SSL<br />
1.1.1&nbsp;&nbsp;WebLogic下面SSL配置：<br />
1．生成 keystoreFile：<br />
&nbsp;* keystoreFile 文件的生成：<br />
%Java_Home%\bin\keytool -genkey -alias localhost-weblogic -keyalg RSA -validity 365 -keystore ./testKey.jks</p>
<p>&nbsp;* csr 文件的生成：<br />
%Java_Home%\bin\keytool -certreq -alias localhost-weblogic -sigalg MD5withRSA -file ./testServer.csr -keystore ./testKey.jks</p>
<p>&nbsp;* 注意： http 的默认端口是80，https 的默认端口是433，ftp 的默认端口是21。<br />
2．部署keystore 文件<br />
在 &lt;http://hostname:7001/console&gt;&nbsp; 中配置刚才生成的 testKey.jks 文件。</p>
<p>1.1.2&nbsp;Tomcat 下面SSL配置</p>
<p><br />
1．生成 keystoreFile：<br />
&nbsp;* keystoreFile 文件的生成：<br />
%Java_Home%\bin\keytool -genkey -alias localhost-weblogic -keyalg RSA -validity 365 -keystore ./testKey.jks</p>
<p>Example for inner test：<br />
[root@localhost ~]# <br />
/home/tomcat/jdk1.5.0_12/bin/keytool -genkey -alias localhost-tomcat -keyalg RSA -validity 365 -keystore /home/tomcat/apache-tomcat-5.5.23/conf/VCMarketKey.jks<br />
Enter keystore password:&nbsp; someday2007<br />
What is your first and last name?<br />
&nbsp; [Unknown]:&nbsp; lifenote<br />
What is the name of your organizational unit?<br />
&nbsp; [Unknown]:&nbsp; Java<br />
What is the name of your organization?<br />
&nbsp; [Unknown]:&nbsp; Sunxc<br />
What is the name of your City or Locality?<br />
&nbsp; [Unknown]:&nbsp; Beijing<br />
What is the name of your State or Province?<br />
&nbsp; [Unknown]:&nbsp; Beijing<br />
What is the two-letter country code for this unit?<br />
&nbsp; [Unknown]:&nbsp; ZH<br />
Is CN=lifenote, OU=Java, O=Sunxc, L=Beijing, ST=Beijing, C=ZH correct?<br />
&nbsp; [no]:&nbsp; y</p>
<p>Enter key password for &lt;localhost-tomcat&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (RETURN if same as keystore password):&nbsp; someday2007<br />
[root@localhost ~]#</p>
<p>&nbsp;</p>
<p>&nbsp;* csr 文件的生成：<br />
%Java_Home%\bin\keytool -certreq -alias localhost-weblogic -sigalg MD5withRSA -file ./testServer.csr -keystore ./testKey.jks</p>
<p>&nbsp;* 注意： http 的默认端口是80，https 的默认端口是433，ftp 的默认端口是21。</p>
<p><br />
2．部署keystore 文件<br />
&nbsp; 打开 server.xml 文件，修改内容如下：<br />
&nbsp;<br />
&nbsp;* 只需去掉 server.xml 中对SSL定义的注释，在加上 keystoreFile、keystorePass 这两个属性即可。<br />
&nbsp; &lt;Service<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name="Catalina"&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;Connector<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; port="8080"<br />
&nbsp;&nbsp;...<br />
&nbsp;&nbsp;&nbsp; &lt;/Connector&gt;<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&lt;!-- Define a SSL HTTP/1.1 Connector on port 8443 --------------------- 要加入的内容在这里 --&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;Connector port="8443" maxHttpHeaderSize="8192"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; maxThreads="150" minSpareThreads="25" maxSpareThreads="75"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enableLookups="false" disableUploadTimeout="true"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; acceptCount="100" scheme="https" secure="true"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; clientAuth="false" sslProtocol="TLS" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; keystoreFile="e:/temp_E/ssl/testKey.jks" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; keystorePass="aaaaaa"/&gt;</p>
<p>&nbsp;&nbsp;&nbsp; &lt;Connector<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; port="8009"<br />
&nbsp;&nbsp;...<br />
&nbsp;&nbsp;&nbsp; &lt;/Connector&gt;<br />
&nbsp;...<br />
Example for inner test：<br />
&nbsp;&nbsp;&nbsp; &lt;Connector port="443" maxHttpHeaderSize="8192"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; maxThreads="150" minSpareThreads="25" maxSpareThreads="75"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enableLookups="false" disableUploadTimeout="true"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; acceptCount="100" scheme="https" secure="true"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; clientAuth="false" sslProtocol="TLS" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; keystoreFile="/home/tomcat/apache-tomcat-5.5.23/conf/VCMarketKey.jks"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; keystorePass="password"/&gt;</p>
<p><br />
&nbsp;注意需默认要使用 443 而不是 8443，要使用8443要在apache中配置，保证从apache请求tomcat 采用 &lt;https://ip:8443/&gt;... 的格式。</p>
<p><br />
1.1.3&nbsp;使用http访问WebService s的客户端配置<br />
Servlet服务器配置好SSL之后，客户端可以使用https访问了。<br />
对于用户使用浏览器访问https的方式，浏览器会弹出安装证书的对话框，确认之后可以正常使用https访问。<br />
&nbsp;对于WebService 通过https方式访问，按照一下步骤：<br />
1．&nbsp;WebService客户端要先取得keyStore文件；<br />
2．&nbsp;虚拟机系统使用 System.setProperties(&#8230;) 设置keyStore信息；<br />
3．&nbsp;使用 url=&lt;https://ip:port/...&gt; 访问WebService服务</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<img src ="http://www.blogjava.net/lifenote/aggbug/175432.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lifenote/" target="_blank">LifeNote</a> 2008-01-15 12:32 <a href="http://www.blogjava.net/lifenote/archive/2008/01/15/175432.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个Struts的上传下载文件的程序</title><link>http://www.blogjava.net/lifenote/archive/2008/01/14/175299.html</link><dc:creator>LifeNote</dc:creator><author>LifeNote</author><pubDate>Mon, 14 Jan 2008 13:24:00 GMT</pubDate><guid>http://www.blogjava.net/lifenote/archive/2008/01/14/175299.html</guid><wfw:comment>http://www.blogjava.net/lifenote/comments/175299.html</wfw:comment><comments>http://www.blogjava.net/lifenote/archive/2008/01/14/175299.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/lifenote/comments/commentRss/175299.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lifenote/services/trackbacks/175299.html</trackback:ping><description><![CDATA[&nbsp;&nbsp; 参看了一些资料实现了一个Struts的上传下载文件的程序，提供下载学习，有什么不好的地方请留言多多指教<br />
为了节省空间，文件中没有导入java包，导入eclipse后请自行加入java包<br />
<a href="http://www.blogjava.net/Files/lifenote/"><br />
http://www.blogjava.net/Files/lifenote/</a>使用struts实现文件上传下载.rar<br />
<br />
要把上面的地址都复制哦
<img src ="http://www.blogjava.net/lifenote/aggbug/175299.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lifenote/" target="_blank">LifeNote</a> 2008-01-14 21:24 <a href="http://www.blogjava.net/lifenote/archive/2008/01/14/175299.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java.lang.OutOfMemoryError 的解决办法</title><link>http://www.blogjava.net/lifenote/archive/2008/01/09/173982.html</link><dc:creator>LifeNote</dc:creator><author>LifeNote</author><pubDate>Wed, 09 Jan 2008 05:27:00 GMT</pubDate><guid>http://www.blogjava.net/lifenote/archive/2008/01/09/173982.html</guid><wfw:comment>http://www.blogjava.net/lifenote/comments/173982.html</wfw:comment><comments>http://www.blogjava.net/lifenote/archive/2008/01/09/173982.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/lifenote/comments/commentRss/173982.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lifenote/services/trackbacks/173982.html</trackback:ping><description><![CDATA[最近在使用Tomcat +Tapestry的时候遇见一个问题，由于Tapestry修改些内容后要重新启动（即使配置了一下那参数有时候也要重启）当我修改了页面的内容 需要调试不断刷新，发现页面显示的速度越来越慢 最后就出现了 500错误java.lang.OutOfMemoryError&nbsp; 内存溢出，在网上查了一下资料<br />
最后总结如下希望可以帮你解决同样的问题<br />
解决java.lang.OutOfMemoryError的方法有如下几种：<br />
1。增加jvm的内存大小。方法有：&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1）在执行某个class文件时候，可以使用java&nbsp;-Xmx256M&nbsp;aa.class来设置运行aa.class时jvm所允许占用的最大内存为256M。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2）对tomcat容器，可以在启动时对jvm设置内存限度。对tomcat，可以在catalina.bat中添加：<br />
&nbsp;&nbsp;set&nbsp;CATALINA_OPTS=-Xms128M&nbsp;-Xmx256M<br />
&nbsp;&nbsp;&nbsp;set&nbsp;JAVA_OPTS=-Xms128M&nbsp;-Xmx256M<br />
或者把%CATALINA_OPTS%和%JAVA_OPTS%代替为-Xms128M&nbsp;-Xmx256M
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3）对resin容器，同样可以在启动时对jvm设置内存限度。在bin文件夹下创建一个startup.bat文件，内容如下：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@echo&nbsp;off<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;call&nbsp;"httpd.exe"&nbsp;&nbsp;"-Xms128M"&nbsp;"-Xmx256M"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:end&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;其中"-Xms128M"为最小内存，"-Xmx256M"为最大内存。</p>
<p>&nbsp;2.&nbsp;&nbsp;&nbsp;&nbsp;优化程序，释放垃圾。</p>
<img src ="http://www.blogjava.net/lifenote/aggbug/173982.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lifenote/" target="_blank">LifeNote</a> 2008-01-09 13:27 <a href="http://www.blogjava.net/lifenote/archive/2008/01/09/173982.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>多模块Struts应用程序的几个问题（及部分解决方法）</title><link>http://www.blogjava.net/lifenote/archive/2008/01/04/172726.html</link><dc:creator>LifeNote</dc:creator><author>LifeNote</author><pubDate>Fri, 04 Jan 2008 05:35:00 GMT</pubDate><guid>http://www.blogjava.net/lifenote/archive/2008/01/04/172726.html</guid><wfw:comment>http://www.blogjava.net/lifenote/comments/172726.html</wfw:comment><comments>http://www.blogjava.net/lifenote/archive/2008/01/04/172726.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lifenote/comments/commentRss/172726.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lifenote/services/trackbacks/172726.html</trackback:ping><description><![CDATA[<a class="UBBWordLink" href="http://www.java-bj.cn/article/sort022/www.java-bj.cn" target="_blank">Struts</a>从1.1版本开始支持把应用程序分为多个模块，每个模块可以看作独立的应用程序，在带来方便的同时，我也发现了一些问题。比如有一个<a class="UBBWordLink" href="http://www.java-bj.cn/article/sort022/www.java-bj.cn" target="_blank">struts</a>应用程序分了大约十个模块，现在有以下问题不知道大家一般是怎么解决的：<br />
<div&nbsp;class=posttext><br />
<p>1、因为要进行验证，所以在每个模块对应的资源文件里都要有&#8220;errors.required={0}&nbsp;is&nbsp;required.&#8221;等资源，有没有只用在一个文件里定义的方法？</p>
<br />
<p>2、用tiles的时候，要在每个模块对应的tiles-defs.xml里定义几乎相同的definition，有没有只用在一个文件里定义的方法？（我试过在缺省模块里定义一个definition，然后在模块里extends它，但不行，extends似乎只找当前模块）</p>
<br />
<p>3、使用ExceptionHandler的时候，为什么在exception标签里指定了bundle属性还是只在当前模块里找资源？我希望把一些重复使用的异常处理声明在一个文件里，例如NotLoginException、NoSuchObjectException等等，并且它们对应的key也指向同一个资源文件里的资源（利用bundle属性），怎么实现？</p>
<br />
<p>经过一段时间的摸索，第一个和第三个问题基本上解决了，其实它们可以看作同一类问题，就是资源的问题。在<a class="UBBWordLink" href="http://www.java-bj.cn/article/sort022/www.java-bj.cn" target="_blank">struts</a>-config-xxx.xml里定义资源文件时，可以指定一个factory属性，不指定时使用缺省的&#8220;org.apache.<a class="UBBWordLink" href="http://www.java-bj.cn/article/sort022/www.java-bj.cn" target="_blank">struts</a>.util.PropertyMessageResourcesFactory&#8221;类。我的解决方法是自定义一个CustomMessageResourcesFactory类，将多个资源文件以逗号分隔的形式作为参数（即message-resources的parameter属性）传给它，在需要资源的地方会遍历它们进行查找。同时还要自定义一个CustomMessageResources类，它的getMessage()方法里是查找资源的关键代码，而factory只是解析逗号分隔的参数构造并返回CustomMessageResources实例。</p>
<br />
<p>CustomMessageResourcesFactory的代码比较简单，如下所示：</p>
<br />
<DIV&NBSP;STYLE="BACKGROUND:&NBSP;#E6E6E6;&NBSP;BORDER-BOTTOM:&NBSP;WINDOWTEXT&NBSP;0.5PT&NBSP;SOLID;&NBSP;BORDER-LEFT:&NBSP;WINDOWTEXT&NBSP;0.5PT&NBSP;SOLID;&NBSP;BORDER-RIGHT:&NBSP;WINDOWTEXT&NBSP;0.5PT&NBSP;SOLID;&NBSP;BORDER-TOP:&NBSP;WINDOWTEXT&NBSP;0.5PT&NBSP;SOLID;&NBSP;PADDING-BOTTOM:&NBSP;4PX;&NBSP;PADDING-LEFT:&NBSP;5.4PT;&NBSP;PADDING-RIGHT:&NBSP;5.4PT;&NBSP;PADDING-TOP:&NBSP;4PX;&NBSP;WIDTH:&NBSP;98%;&NBSP;WORD-BREAK:&NBSP;BREAK-ALL"><br />
<div><IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; /><SPAN&NBSP;STYLE="COLOR:&NBSP;#000000">package&nbsp;eg;<br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; /><br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; />import&nbsp;java.util.Arrays;<br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; /><br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; />import&nbsp;org.apache.<a class="UBBWordLink" href="http://www.java-bj.cn/article/sort022/www.java-bj.cn" target="_blank">struts</a>.util.MessageResources;<br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; />import&nbsp;org.apache.<a class="UBBWordLink" href="http://www.java-bj.cn/article/sort022/www.java-bj.cn" target="_blank">struts</a>.util.MessageResourcesFactory;<br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; /><br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; />public&nbsp;class&nbsp;CustomMessageResourcesFactory&nbsp;extends&nbsp;MessageResourcesFactory{<br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; /><br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;MessageResources&nbsp;createResources(String&nbsp;config)&nbsp;{<br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><SPAN&NBSP;STYLE="COLOR:&NBSP;#0000FF">return</span><SPAN&NBSP;STYLE="COLOR:&NBSP;#000000">&nbsp;</span><SPAN&NBSP;STYLE="COLOR:&NBSP;#0000FF">new</span><SPAN&NBSP;STYLE="COLOR:&NBSP;#000000">&nbsp;CustomMessageResources(Arrays.asList(config.split(</span><SPAN&NBSP;STYLE="COLOR:&NBSP;#000000">"</span><SPAN&NBSP;STYLE="COLOR:&NBSP;#000000">,</span><SPAN&NBSP;STYLE="COLOR:&NBSP;#000000">"</span><SPAN&NBSP;STYLE="COLOR:&NBSP;#000000">)));<br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; />&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; /><br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; />}<br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; /></span>&nbsp;</div>
<br />
<p>&nbsp;</p>
<br />
<p>CustomMessageResources就稍微复杂一些，不过很幸运，我在网上找到了一个完全符合自己要求的类，下载地址在<A&NBSP;HREF="HTTP: javaboutique.internet.com tutorials Dynaform source.zip?><br />
<div><IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; /><SPAN&NBSP;STYLE="COLOR:&NBSP;#0000FF">&lt;</span><SPAN&NBSP;STYLE="COLOR:&NBSP;#800000">message-resources&nbsp;</span><SPAN&NBSP;STYLE="COLOR:&NBSP;#FF0000">factory</span><SPAN&NBSP;STYLE="COLOR:&NBSP;#0000FF">="eg.CustomMessageResourcesFactory"</span><SPAN&NBSP;STYLE="COLOR:&NBSP;#FF0000">&nbsp;<br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; />&nbsp;&nbsp;&nbsp;&nbsp;parameter</span><SPAN&NBSP;STYLE="COLOR:&NBSP;#0000FF">="eg.ApplicationResources,eg.ErrorResources"</span><SPAN&NBSP;STYLE="COLOR:&NBSP;#FF0000">&nbsp;</span><SPAN&NBSP;STYLE="COLOR:&NBSP;#0000FF">/&gt;</span><SPAN&NBSP;STYLE="COLOR:&NBSP;#000000"><br />
<IMG&NBSP;ALIGN=TOP&NBSP;HEIGHT=16&NBSP;SRC="HTTP: style="cursor: pointer" onclick="javascript:window.open(this.src);" www.cnblogs.com Images OutliningIndicators onload="return imgzoom(this,550);" width="11"  None.gif?&nbsp; /></span>&nbsp;</div>
<br />
<p>&nbsp;</p>
<br />
<p>上面参考了这篇文章</SPAN&NBSP;STYLE="COLOR:&NBSP;#000000"></SPAN&NBSP;STYLE="COLOR:&NBSP;#0000FF"></SPAN&NBSP;STYLE="COLOR:&NBSP;#FF0000"></SPAN&NBSP;STYLE="COLOR:&NBSP;#0000FF"></SPAN&NBSP;STYLE="COLOR:&NBSP;#FF0000"></SPAN&NBSP;STYLE="COLOR:&NBSP;#0000FF"></SPAN&NBSP;STYLE="COLOR:&NBSP;#FF0000"></SPAN&NBSP;STYLE="COLOR:&NBSP;#800000"></SPAN&NBSP;STYLE="COLOR:&NBSP;#0000FF"></DIV&NBSP;STYLE="BACKGROUND:&NBSP;#E6E6E6;&NBSP;BORDER-BOTTOM:&NBSP;WINDOWTEXT&NBSP;0.5PT&NBSP;SOLID;&NBSP;BORDER-LEFT:&NBSP;WINDOWTEXT&NBSP;0.5PT&NBSP;SOLID;&NBSP;BORDER-RIGHT:&NBSP;WINDOWTEXT&NBSP;0.5PT&NBSP;SOLID;&NBSP;BORDER-TOP:&NBSP;WINDOWTEXT&NBSP;0.5PT&NBSP;SOLID;&NBSP;PADDING-BOTTOM:&NBSP;4PX;&NBSP;PADDING-LEFT:&NBSP;5.4PT;&NBSP;PADDING-RIGHT:&NBSP;5.4PT;&NBSP;PADDING-TOP:&NBSP;4PX;&NBSP;WIDTH:&NBSP;98%;&NBSP;WORD-BREAK:&NBSP;BREAK-ALL">
</SPAN&NBSP;STYLE="COLOR:&NBSP;#000000"></SPAN&NBSP;STYLE="COLOR:&NBSP;#000000"></SPAN&NBSP;STYLE="COLOR:&NBSP;#000000"></SPAN&NBSP;STYLE="COLOR:&NBSP;#000000"></SPAN&NBSP;STYLE="COLOR:&NBSP;#000000"></SPAN&NBSP;STYLE="COLOR:&NBSP;#0000FF"></SPAN&NBSP;STYLE="COLOR:&NBSP;#000000"></SPAN&NBSP;STYLE="COLOR:&NBSP;#0000FF"></SPAN&NBSP;STYLE="COLOR:&NBSP;#000000"></p>
<img src ="http://www.blogjava.net/lifenote/aggbug/172726.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lifenote/" target="_blank">LifeNote</a> 2008-01-04 13:35 <a href="http://www.blogjava.net/lifenote/archive/2008/01/04/172726.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JSF和Spring集成</title><link>http://www.blogjava.net/lifenote/archive/2008/01/03/172506.html</link><dc:creator>LifeNote</dc:creator><author>LifeNote</author><pubDate>Thu, 03 Jan 2008 08:31:00 GMT</pubDate><guid>http://www.blogjava.net/lifenote/archive/2008/01/03/172506.html</guid><wfw:comment>http://www.blogjava.net/lifenote/comments/172506.html</wfw:comment><comments>http://www.blogjava.net/lifenote/archive/2008/01/03/172506.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lifenote/comments/commentRss/172506.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lifenote/services/trackbacks/172506.html</trackback:ping><description><![CDATA[<p>JSF和Spring集成原理是获得彼此的上下文引用,以此进一步获得各自管理的bean,这是可能的,因为两者是web应用框架都遵循servlet规范,为二者整合提供了可能和基础.<br />
&nbsp;<br />
在Spring中ApplicationContext是相当重要的类,对于web应用,它还包装了javax.servlet.ServletContext,为web应用提供了所有可以利用的数据,包括可管理bean,Faces中通过FacesContext类可以获得所有可以利用的资源,同样包括JSF的可管理支持bean,它们都围绕着ServletContext提供了自己的门面,通过各自的门面在Servlet容器的世界里彼此相通.<br />
本文介绍两种方式,实现二者集成:<br />
1.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 通过写自己的类来完成二者的连通,实际上只是获得彼此世界里存活的bean,对于JSF中事件处理可能需要更进一步的构思和编码,为了这点,第二个方法介绍了一种框架.<br />
2.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 使用框架完成二者集成.<br />
&nbsp;<br />
一&nbsp; 自己动手,下面的代码以示例为主,其它涉及的类和接口略去.<br />
这个工具类提供在JSF世界里查找Spring管理的bean.也实现在Spring中查找JSF组件的方法.<br />
package com.skysoft.rbac.dao;<br />
&nbsp;<br />
import org.springframework.context.ApplicationContext;<br />
import org.springframework.web.context.support.WebApplicationContextUtils;<br />
import javax.faces.context.FacesContext;<br />
import javax.servlet.ServletContext;<br />
import javax.faces.el.ValueBinding;<br />
import javax.faces.FactoryFinder;<br />
import javax.faces.application.Application;<br />
import javax.faces.application.ApplicationFactory;<br />
&nbsp;<br />
public final class SpringFacesUtil {<br />
&nbsp; public SpringFacesUtil() {<br />
&nbsp; }<br />
&nbsp; /**<br />
&nbsp;&nbsp; * 从Spring中查找bean.<br />
&nbsp;&nbsp; * @param beanname String<br />
&nbsp;&nbsp; * @return Object<br />
&nbsp;&nbsp; */<br />
&nbsp; public static Object findBean(String beanname) {<br />
&nbsp;&nbsp;&nbsp; ServletContext context = (ServletContext) FacesContext.getCurrentInstance().<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getExternalContext().getContext();<br />
&nbsp;&nbsp;&nbsp; ApplicationContext appctx = WebApplicationContextUtils.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getRequiredWebApplicationContext(context);<br />
&nbsp;&nbsp;&nbsp; return appctx.getBean(beanname);<br />
&nbsp; }<br />
&nbsp; /**<br />
&nbsp;&nbsp; * 从JSF中查找bean.<br />
&nbsp;&nbsp; * @param beanname String<br />
&nbsp;&nbsp; * @return Object<br />
&nbsp;&nbsp; */<br />
&nbsp; public static Object lookupBean(String beanname) {<br />
&nbsp;&nbsp;&nbsp; Object obj = getValueBinding(getJsfEl(beanname)).getValue(FacesContext.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getCurrentInstance());<br />
&nbsp;&nbsp;&nbsp; return obj;<br />
&nbsp; }<br />
&nbsp;<br />
&nbsp; private static ValueBinding getValueBinding(String el) {<br />
&nbsp;&nbsp;&nbsp; return getApplication().createValueBinding(el);<br />
&nbsp; }<br />
&nbsp;<br />
&nbsp; private static Application getApplication() {<br />
&nbsp;&nbsp;&nbsp; ApplicationFactory appFactory = (ApplicationFactory) FactoryFinder.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getFactory(FactoryFinder.APPLICATION_FACTORY);<br />
&nbsp;&nbsp;&nbsp; //FactoryFinder.FACES_CONTEXT_FACTORY<br />
&nbsp;&nbsp;&nbsp; //FactoryFinder.RENDER_KIT_FACTORY<br />
&nbsp;&nbsp;&nbsp; return appFactory.getApplication();<br />
&nbsp; }<br />
&nbsp;<br />
&nbsp; private static String getJsfEl(String value) {<br />
&nbsp;&nbsp;&nbsp; return "#{" + value + "}";<br />
&nbsp; }<br />
}<br />
下面定义一个由JSF管理的bean:<br />
package com.skysoft.rbac.dao;<br />
&nbsp;<br />
import javax.servlet.ServletContext;<br />
&nbsp;<br />
import org.springframework.context.ApplicationContext;<br />
import org.springframework.web.context.support.WebApplicationContextUtils;<br />
import org.skysoft.struts.jsf.util.FacesUtils;<br />
&nbsp;<br />
public class ServiceLocatorBean<br />
&nbsp;&nbsp;&nbsp; implements ServiceLocator {<br />
&nbsp; private static final String DAO_SERVICE_BEAN_NAME = "userDAO";<br />
&nbsp; //这个dao就是由Spring提供的管理bean,这个dao可以使用Hibernate实现.<br />
&nbsp; private UserDAO dao;<br />
&nbsp;<br />
&nbsp; public ServiceLocatorBean() {<br />
&nbsp;&nbsp;&nbsp; this.dao = (UserDAO)SpringFacesUtil.findBean(DAO_SERVICE_BEAN_NAME);<br />
&nbsp; }<br />
&nbsp;<br />
&nbsp; public UserDAO getDao() {<br />
&nbsp;&nbsp;&nbsp; return dao;<br />
&nbsp; }<br />
}<br />
下面是一个使用ServiceLocatorBean的类.<br />
public class UserDAOImp<br />
&nbsp;&nbsp;&nbsp; extends HibernateDaoSupport implements UserDAO {<br />
&nbsp; private UserDAO dao;<br />
&nbsp; private List list;<br />
&nbsp;<br />
&nbsp; public UserDAOImp() {}<br />
&nbsp;<br />
&nbsp; public List getList() {<br />
&nbsp;&nbsp;&nbsp; if (list == null) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; list = dao.getList();<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; return list;<br />
&nbsp; }<br />
&nbsp;<br />
&nbsp; public UserDAO getDao() {<br />
&nbsp;&nbsp;&nbsp; return dao;<br />
&nbsp; }<br />
&nbsp;<br />
&nbsp; public void setDao(UserDAO dao) {<br />
&nbsp;&nbsp;&nbsp; this.dao = dao;<br />
&nbsp; }<br />
}<br />
&nbsp;<br />
在faces-config.xml中的配置:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;managed-bean&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;managed-bean-name&gt;serviceLocatorBean&lt;/managed-bean-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;managed-bean-class&gt;com.skysoft.rbac.dao.ServiceLocatorBean&lt;/managed-bean-class&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;managed-bean-scope&gt;session&lt;/managed-bean-scope&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/managed-bean&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;managed-bean&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;managed-bean-name&gt;User&lt;/managed-bean-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;managed-bean-class&gt;com.skysoft.rbac.User&lt;/managed-bean-class&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;managed-bean-scope&gt;request&lt;/managed-bean-scope&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;managed-property&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property-name&gt;serviceLocator&lt;/property-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property-class&gt;com.skysoft.rbac.dao.ServiceLocatorBean&lt;/property-class&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;#{serviceLocatorBean}&lt;/value&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/managed-property&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/managed-bean&gt;<br />
在applicationContext.xml中的配置:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;bean id="userDAO" class="com.skysoft.rbac.dao.UserDAOImp"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name="sessionFactory"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ref local="sessionFactory" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/property&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/bean&gt;<br />
二 使用框架<br />
1 介绍<br />
这个框架是Spring相关项目,提供一个包de.mindmatters.faces.spring,这个包包含JSF和Spring框架综合集成的粘合代码,这些代码以独立于一个实现的方式完成,这样它能和任何JSF实现一起使用.<br />
本包的提供的代码主要目的是尽可能透明的集成两个框架,主要特征:<br />
l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JSF/JSP开发者应该能访问Spring管理的Beans,就好象它们是由JSF管理的.<br />
l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JSF可管理beans应能集成入Spring.<br />
l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RequestHandledEvent事件也应该能被发布到Spring.<br />
2&nbsp; JSF配置集成<br />
本包构造了一个基于faces配置文件(e.g. /WEB-INF/faces-config.xml)的WebApplicationContext类, 让它成为遵循"spring-beans" DTD配置文件(e.g. defined in /WEB-INF/applicationContext.xml)来配置的ApplicationContext的孩子,这样依从"faces-config" DTD的WebApplicationContext就是全特征的,即自动拥有如下功能: <br />
l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JSF可管理beans实现了Spring的*Aware interfaces:<br />
ApplicationContextAware <br />
BeanFactoryAware <br />
BeanNameAware <br />
ResourceLoaderAware <br />
ServletContextAware <br />
l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JSF可管理beans实现Spring的lifecycle interfaces:<br />
InitializingBean <br />
DisposableBean <br />
l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 实现Spring的FactoryBean interface<br />
l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 实现Spring的ApplicationListener interface <br />
l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 发布ApplicationEvent事件.<br />
l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 从资源中读取消息.<br />
等等,更多可看Spring.<br />
3 访问方式<br />
1) 从JSF中程序化的访问Spring管理的beans.<br />
因为在FacesWebApplicationContext和ApplicationContext之间有层次关系,所以你的JSF可管理支持beans能容易的实现ApplicationContextAware接口,并能通过getBean方法访问它而不管它是否定义在FacesWebApplicationContext中还是定义在父ApplicationContext类对象中.<br />
2) 通过JSF EL从JSF中访问Spring管理的beans.<br />
能够使用JSF EL访问beans无论你引用的bean由JSF管理还是由Spring管理.两个bean上下文在存取时间合并.<br />
a) 直接访问:<br />
如果一个带有请求名字的bean只存在于Spring上下文内的话,这个bean被使用,bean的singleton属性设置被完全保持.<br />
b) 区域化访问(scoped access):<br />
如果你要从JSF定义bean的作用域的能力上得益还想让那个bean由Spring管理,那么就要在两个上下文中定义,只是对于JSF上下文中的定义的类类型要使用de.mindmatters.faces.spring.SpringBeanFactory类,你还应该设置那个bean的singleton属性到false,因这能覆盖你的作用域设置.在你使用JSF EL访问bean时,你总能获得一个遵从你在JSF上下文中定义的作用域设置的由Spring管理的bean的实例.<br />
&nbsp;<br />
三 用法<br />
通常,就象设置任何其它JSF web应用一样设置你的web应用,下面的样例配置展示怎样使能上面提到的特征。<br />
在web.xml配置中必须加入下列配置条目,同时注意把该库的jsf-spring.jar放在适当的位置.<br />
&lt;web-app&gt;<br />
&nbsp;&nbsp;&nbsp; .........<br />
&nbsp;&nbsp;&nbsp; &lt;!--<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 过滤器用于向Spring发布RequestHandledEvent,它应该影射到和FacesServlet url相同的模式.<br />
&nbsp;&nbsp;&nbsp; --&gt;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &lt;filter&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-name&gt;RequestHandled&lt;/filter-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-class&gt;de.mindmatters.faces.spring.support.RequestHandledFilter&lt;/filter-class&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/filter&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &lt;filter-mapping&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-name&gt;RequestHandled&lt;/filter-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;*.faces&lt;/url-pattern&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/filter-mapping&gt;<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp; &lt;!--<br />
&nbsp;&nbsp;&nbsp; 这个侦听器用于装入Spring beans的父应用上下文.<br />
&nbsp;&nbsp;&nbsp; --&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;listener&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/listener&gt;<br />
&nbsp;&nbsp;&nbsp; .........<br />
&lt;/web-app&gt;<br />
下面的一些说明,都可以通过下载这个Spring相关项目得到,列在这里只为演示上面的说明的功能.<br />
WEB-INF/faces-config.xml <br />
&lt;!-- 一个纯JSF管理的bean --&gt;<br />
&lt;managed-bean&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;managed-bean-name&gt;jsfBean&lt;/managed-bean-name&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;managed-bean-class&gt;example.NameBean&lt;/managed-bean-class&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;managed-bean-scope&gt;session&lt;/managed-bean-scope&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;managed-property&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property-name&gt;name&lt;/property-name&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/managed-property&gt;<br />
&lt;/managed-bean&gt;<br />
&lt;!--一个SpringBeanScope用来定义Spring可管理bean的作用域.--&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;managed-bean&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;managed-bean-name&gt;scopedAccessSpringBean&lt;/managed-bean-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;managed-bean-class&gt;de.mindmatters.faces.spring.SpringBeanScope&lt;/managed-bean-class&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;managed-bean-scope&gt;session&lt;/managed-bean-scope&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/managed-bean&gt;<br />
&lt;!-- 这是一个纯JSF可管理bean,它持有一个到Spring可管理bean的一个引用. --&gt;<br />
&lt;managed-bean&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;managed-bean-name&gt;referencingBean&lt;/managed-bean-name&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;managed-bean-class&gt;example.ReferencingBean&lt;/managed-bean-class&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;managed-bean-scope&gt;session&lt;/managed-bean-scope&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;managed-property&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property-name&gt;referencedBean&lt;/property-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;#{managedPropertyAccessSpringBean}&lt;/value&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/managed-property&gt;<br />
&lt;/managed-bean&gt;<br />
WEB-INF/applicationContext.xml (partial)<br />
&lt;!-- 一个纯Spring的可管理bean --&gt;<br />
&lt;bean id="directAccessSpringBean" class="example.NameBean"/&gt;<br />
&lt;!-- 一个向JSF作用域提供的可管理bean.&nbsp; --&gt;<br />
&lt;bean id="scopedAccessSpringBean" class="example.NameBean" singleton="false"/&gt;<br />
&lt;!-- 一个纯Spring的可管理bean,它由一个JSF可管理bean引用.(当然了,它也能被直接访问啦.) --&gt;<br />
&lt;bean id="managedPropertyAccessSpringBean" class="example.NameBean" singleton="false"/&gt;<br />
参考:<br />
http://jsf-spring.sourceforge.net/&nbsp;&nbsp; JSF-Spring,Spring相关项目官方站点,提供本文介绍的框架下载以及实例下载.<br />
javaworld.com/javaworld/jw-07-2004/jw-0719-jsf.html"&gt;http://www.javaworld.com/javaworld/jw-07-2004/jw-0719-jsf.html 一篇关于JSF和Spring的文章.<br />
bean的singleton属性设置被完全保持. </p>
<p>b) 区域化访问(scoped access):<br />
如果你要从JSF定义bean的作用域的能力上得益还想让那个bean由Spring管理,那么就要在两个上下文中定义,只是对于JSF上下文中的定义的类类型要使用de.mindmatters.faces.spring.SpringBeanFactory类,你还应该设置那个bean的singleton属性到false,因这能覆盖你的作用域设置.在你使用JSF EL访问bean时,你总能获得一个遵从你在JSF上下文中定义的作用域设置的由Spring管理的bean的实例.<br />
&nbsp;<br />
三 用法<br />
通常,就象设置任何其它JSF web应用一样设置你的web应用,下面的样例配置展示怎样使能上面提到的特征。<br />
在web.xml配置中必须加入下列配置条目,同时注意把该库的jsf-spring.jar放在适当的位置.<br />
&lt;web-app&gt;<br />
&nbsp;&nbsp;&nbsp; .........<br />
&nbsp;&nbsp;&nbsp; &lt;!--<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 过滤器用于向Spring发布RequestHandledEvent,它应该影射到和FacesServlet url相同的模式.<br />
&nbsp;&nbsp;&nbsp; --&gt;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &lt;filter&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-name&gt;RequestHandled&lt;/filter-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-class&gt;de.mindmatters.faces.spring.support.RequestHandledFilter&lt;/filter-class&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/filter&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; &lt;filter-mapping&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;filter-name&gt;RequestHandled&lt;/filter-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;*.faces&lt;/url-pattern&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/filter-mapping&gt;<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp; &lt;!--<br />
&nbsp;&nbsp;&nbsp; 这个侦听器用于装入Spring beans的父应用上下文.<br />
&nbsp;&nbsp;&nbsp; --&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;listener&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/listener&gt;<br />
&nbsp;&nbsp;&nbsp; .........<br />
&lt;/web-app&gt;<br />
下面的一些说明,都可以通过下载这个Spring相关项目得到,列在这里只为演示上面的说明的功能.<br />
WEB-INF/faces-config.xml <br />
&lt;!-- 一个纯JSF管理的bean --&gt;<br />
&lt;managed-bean&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;managed-bean-name&gt;jsfBean&lt;/managed-bean-name&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;managed-bean-class&gt;example.NameBean&lt;/managed-bean-class&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;managed-bean-scope&gt;session&lt;/managed-bean-scope&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;managed-property&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property-name&gt;name&lt;/property-name&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/managed-property&gt;<br />
&lt;/managed-bean&gt;<br />
&lt;!--一个SpringBeanScope用来定义Spring可管理bean的作用域.--&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;managed-bean&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;managed-bean-name&gt;scopedAccessSpringBean&lt;/managed-bean-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;managed-bean-class&gt;de.mindmatters.faces.spring.SpringBeanScope&lt;/managed-bean-class&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;managed-bean-scope&gt;session&lt;/managed-bean-scope&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/managed-bean&gt;<br />
&lt;!-- 这是一个纯JSF可管理bean,它持有一个到Spring可管理bean的一个引用. --&gt;<br />
&lt;managed-bean&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;managed-bean-name&gt;referencingBean&lt;/managed-bean-name&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;managed-bean-class&gt;example.ReferencingBean&lt;/managed-bean-class&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;managed-bean-scope&gt;session&lt;/managed-bean-scope&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;managed-property&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property-name&gt;referencedBean&lt;/property-name&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;value&gt;#{managedPropertyAccessSpringBean}&lt;/value&gt;<br />
&nbsp;&nbsp;&nbsp; &lt;/managed-property&gt;<br />
&lt;/managed-bean&gt;<br />
WEB-INF/applicationContext.xml (partial)<br />
&lt;!-- 一个纯Spring的可管理bean --&gt;<br />
&lt;bean id="directAccessSpringBean" class="example.NameBean"/&gt;<br />
&lt;!-- 一个向JSF作用域提供的可管理bean.&nbsp; --&gt;<br />
&lt;bean id="scopedAccessSpringBean" class="example.NameBean" singleton="false"/&gt;<br />
&lt;!-- 一个纯Spring的可管理bean,它由一个JSF可管理bean引用.(当然了,它也能被直接访问啦.) --&gt;<br />
&lt;bean id="managedPropertyAccessSpringBean" class="example.NameBean" singleton="false"/&gt;<br />
参考:<br />
http://jsf-spring.sourceforge.net/&nbsp;&nbsp; JSF-Spring,Spring相关项目官方站点,提供本文介绍的框架下载以及实例下载.<br />
http://www.javaworld.com/javaworld/jw-07-2004/jw-0719-jsf.html 一篇关于JSF和Spring的文章.<br />
</p>
<img src ="http://www.blogjava.net/lifenote/aggbug/172506.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lifenote/" target="_blank">LifeNote</a> 2008-01-03 16:31 <a href="http://www.blogjava.net/lifenote/archive/2008/01/03/172506.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>博客搬家程序是如何实现的</title><link>http://www.blogjava.net/lifenote/archive/2007/12/27/170914.html</link><dc:creator>LifeNote</dc:creator><author>LifeNote</author><pubDate>Thu, 27 Dec 2007 08:28:00 GMT</pubDate><guid>http://www.blogjava.net/lifenote/archive/2007/12/27/170914.html</guid><wfw:comment>http://www.blogjava.net/lifenote/comments/170914.html</wfw:comment><comments>http://www.blogjava.net/lifenote/archive/2007/12/27/170914.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lifenote/comments/commentRss/170914.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lifenote/services/trackbacks/170914.html</trackback:ping><description><![CDATA[如题，找有开发过这样功能的朋友介绍一下，是分析html代码么&nbsp; 那比如sina 的和163的 代码肯定不一样的 那不是要写很多这样的程序 疑惑中。。。
<img src ="http://www.blogjava.net/lifenote/aggbug/170914.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lifenote/" target="_blank">LifeNote</a> 2007-12-27 16:28 <a href="http://www.blogjava.net/lifenote/archive/2007/12/27/170914.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>★★oracle易忘函数用法★★</title><link>http://www.blogjava.net/lifenote/archive/2007/12/14/167677.html</link><dc:creator>LifeNote</dc:creator><author>LifeNote</author><pubDate>Fri, 14 Dec 2007 02:02:00 GMT</pubDate><guid>http://www.blogjava.net/lifenote/archive/2007/12/14/167677.html</guid><wfw:comment>http://www.blogjava.net/lifenote/comments/167677.html</wfw:comment><comments>http://www.blogjava.net/lifenote/archive/2007/12/14/167677.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lifenote/comments/commentRss/167677.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lifenote/services/trackbacks/167677.html</trackback:ping><description><![CDATA[<p>===================★★oracle易忘函数用法★★=====================================<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;开发积累资料<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Author:SunXianchao<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2006年于湖南长沙<br />
==============================================================================<br />
一般的to_char是这样用的to_char(sysdate,'YYYY-MM-DD hh:mi:ss AM') ，也有几个突出点的用法：</p>
<p>to_char(sysdate, 'dd') 查看今天是几号to_char(sysdate, 'ww') 查看这是这个月第几个星期</p>
<p>to_char(sysdate, 'mm')&nbsp; 查看这是一年中第几个月</p>
<p>to_char(sysdate, 'yyyy') 查看年份last_day(to_date('2007-02-01','YYYY-MM-DD'))查看一个月的最后一天，add_months(sysdate,10)查看若干个月后的今天，next_day(sysdate,'星期五')给个日期查看后面的最近的星期几的日期，不过这个星期五要是换成英文居然有问题，第2个参数可以是数字1-7，分别表示周日到周六。</p>
<p>下面贴个全的，需要的时候顺便查一下。</p>
<p>一、PL/SQL单行函数和组函数详解</p>
<p>函数是一种有零个或多个参数并且有一个返回值的程序。在SQL中Oracle内建了一系列函数，这些函数都可被称为SQL或PL/SQL语句，函数主要分为两大类：单行函数和组函数。</p>
<p>本文将讨论如何利用单行函数以及使用规则。<br />
1、SQL中的单行函数</p>
<p>SQL和PL/SQL中自带很多类型的函数，有字符、数字、日期、转换、和混合型等多种函数用于处理单行数据，因此这些都可被统称为单行函数。这些函数均可用于SELECT,WHERE、ORDER BY等子句中，例如下面的例子中就包含了TO_CHAR,UPPER,SOUNDEX等单行函数。</p>
<p>SELECT ename,TO_CHAR(hiredate,'day,DD-Mon-YYYY')FROM empWhere UPPER(ename) Like 'AL%'ORDER BY SOUNDEX(ename) </p>
<p><br />
单行函数也可以在其他语句中使用，如update的SET子句，INSERT的VALUES子句，DELET的WHERE子句,认证考试特别注意在SELECT语句中使用这些函数，所以我们的注意力也集中在SELECT语句中。</p>
<p>2、NULL和单行函数</p>
<p>在如何理解NULL上开始是很困难的，就算是一个很有经验的人依然对此感到困惑。NULL值表示一个未知数据或者一个空值，算术操作符的任何一个操作数为NULL值，结果均为提个NULL值,这个规则也适合很多函数，只有CONCAT,DECODE,DUMP,NVL,REPLACE在调用了NULL参数时能够返回非NULL值。在这些中NVL函数时最重要的，因为他能直接处理NULL值，NVL有两个参数:NVL(x1,x2),x1和x2都式表达式，当x1为null时返回X2,否则返回x1。</p>
<p>下面我们看看emp数据表它包含了薪水、奖金两项，需要计算总的补偿。</p>
<p>column name emp_id salary bonuskey type pk nulls/unique nn,u nnfk table datatype number number numberlength 11.2 11.2 </p>
<p><br />
不是简单的将薪水和奖金加起来就可以了，如果某一行是null值那么结果就将是null，比如下面的例子：</p>
<p>update empset salary=(salary+bonus)*1.1 </p>
<p><br />
这个语句中，雇员的工资和奖金都将更新为一个新的值，但是如果没有奖金，即 salary + null,那么就会得出错误的结论，这个时候就要使用nvl函数来排除null值的影响。</p>
<p>所以正确的语句是：</p>
<p>update empset salary=(salary+nvl(bonus,0)*1.1 </p>
<p><br />
3、单行字符串函数</p>
<p>单行字符串函数用于操作字符串数据，他们大多数有一个或多个参数，其中绝大多数返回字符串。</p>
<p>ASCII()</p>
<p>c1是一字符串，返回c1第一个字母的ASCII码，他的逆函数是CHR()</p>
<p>SELECT ASCII('A') BIG_A,ASCII('z') BIG_z FROM empBIG_A BIG_z65 122 </p>
<p><br />
CHR()[NCHAR_CS]</p>
<p>i是一个数字，函数返回十进制表示的字符。</p>
<p>select CHR(65),CHR(122),CHR(223) FROM empCHR65 CHR122 CHR223A z B </p>
<p><br />
CONCAT(,)</p>
<p>c1,c2均为字符串，函数将c2连接到c1的后面，如果c1为null,将返回c2.如果c2为null,则返回c1，如果c1、c2都为null，则返回null。他和操作符||返回的结果相同</p>
<p>select concat('slobo ','Svoboda') username from dualusernameslobo Syoboda <br />
INITCAP()</p>
<p>c1为一字符串。函数将每个单词的第一个字母大写其它字母小写返回。单词由空格，控制字符，标点符号限制。</p>
<p>select INITCAP('veni,vedi,vici') Ceasar from dualCeasarVeni,Vedi,Vici </p>
<p><br />
INSTR(,[,[,]])</p>
<p>c1,c2均为字符串，i,j为整数。函数返回c2在c1中第j次出现的位置，搜索从c1的第i个字符开始。当没有发现需要的字符时返回0,如果i为负数，那么搜索将从右到左进行，但是位置的计算还是从左到右，i和j的缺省值为1。</p>
<p>select INSTR('Mississippi','i',3,3) from dualINSTR('MISSISSIPPI','I',3,3)11select INSTR('Mississippi','i',-2,3) from dualINSTR('MISSISSIPPI','I',3,3)2 </p>
<p><br />
INSTRB(,[,i[,j])</p>
<p>与INSTR()函数一样，只是他返回的是字节，对于单字节INSTRB()等于INSTR()。</p>
<p>LENGTH()</p>
<p>c1为字符串，返回c1的长度，如果c1为null，那么将返回null值。</p>
<p>select LENGTH('Ipso Facto') ergo from dualergo10 </p>
<p><br />
LENGTHb()</p>
<p>与LENGTH()一样，返回字节。</p>
<p>lower()</p>
<p>返回c的小写字符，经常出现在where子串中。</p>
<p>select LOWER(colorname) from itemdetail WHERE LOWER(colorname) LIKE '%white%'COLORNAMEWinterwhite </p>
<p><br />
LPAD(,[,])</p>
<p>c1,c2均为字符串，i为整数。在c1的左侧用c2字符串补足致长度i,可多次重复，如果i小于c1的长度，那么只返回i那么长的c1字符，其他的将被截去。c2的缺省值为单空格，参见RPAD。</p>
<p>select LPAD(answer,7,'') padded,answer unpadded from question;PADDED UNPADDED Yes YesNO NOMaybe maybe </p>
<p><br />
LTRIM(,)</p>
<p>把c1中最左边的字符去掉，使其第一个字符不在c2中，如果没有c2，那么c1就不会改变。</p>
<p>select LTRIM('Mississippi','Mis') from dualLTRppi </p>
<p><br />
RPAD(,[,])</p>
<p>在c1的右侧用c2字符串补足致长度i,可多次重复，如果i小于c1的长度，那么只返回i那么长的c1字符，其他的将被截去。c2的缺省值为单空格,其他与LPAD相似。</p>
<p>RTRIM(,)</p>
<p>把c1中最右边的字符去掉，使其第后一个字符不在c2中，如果没有c2，那么c1就不会改变。</p>
<p>REPLACE(,[,])</p>
<p>c1,c2,c3都是字符串，函数用c3代替出现在c1中的c2后返回。</p>
<p>select REPLACE('uptown','up','down') from dualREPLACEdowntown </p>
<p><br />
STBSTR(,[,])</p>
<p>c1为一字符串，i,j为整数，从c1的第i位开始返回长度为j的子字符串，如果j为空，则直到串的尾部。</p>
<p>select SUBSTR('Message',1,4) from dualSUBSMess </p>
<p><br />
SUBSTRB(,[,])</p>
<p>与SUBSTR大致相同，只是I,J是以字节计算。</p>
<p>SOUNDEX()</p>
<p>返回与c1发音相似的词。</p>
<p>select SOUNDEX('dawes') Dawes SOUNDEX('daws') Daws, SOUNDEX('dawson') from dualDawes Daws DawsonD200 D200 D250 </p>
<p><br />
TRANSLATE(,,)</p>
<p>将c1