﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-银色幻想</title><link>http://www.blogjava.net/xzhoujun/</link><description /><language>zh-cn</language><lastBuildDate>Fri, 01 May 2026 17:31:00 GMT</lastBuildDate><pubDate>Fri, 01 May 2026 17:31:00 GMT</pubDate><ttl>60</ttl><item><title>Jakarta简介</title><link>http://www.blogjava.net/xzhoujun/archive/2007/05/18/118264.html</link><dc:creator>银色幻想</dc:creator><author>银色幻想</author><pubDate>Fri, 18 May 2007 02:16:00 GMT</pubDate><guid>http://www.blogjava.net/xzhoujun/archive/2007/05/18/118264.html</guid><wfw:comment>http://www.blogjava.net/xzhoujun/comments/118264.html</wfw:comment><comments>http://www.blogjava.net/xzhoujun/archive/2007/05/18/118264.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xzhoujun/comments/commentRss/118264.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xzhoujun/services/trackbacks/118264.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 项目																																																																																																																		子项目																																																				...&nbsp;&nbsp;<a href='http://www.blogjava.net/xzhoujun/archive/2007/05/18/118264.html'>阅读全文</a><img src ="http://www.blogjava.net/xzhoujun/aggbug/118264.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xzhoujun/" target="_blank">银色幻想</a> 2007-05-18 10:16 <a href="http://www.blogjava.net/xzhoujun/archive/2007/05/18/118264.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts+Spring+Hibernate内存泄漏</title><link>http://www.blogjava.net/xzhoujun/archive/2007/05/18/118251.html</link><dc:creator>银色幻想</dc:creator><author>银色幻想</author><pubDate>Fri, 18 May 2007 01:54:00 GMT</pubDate><guid>http://www.blogjava.net/xzhoujun/archive/2007/05/18/118251.html</guid><wfw:comment>http://www.blogjava.net/xzhoujun/comments/118251.html</wfw:comment><comments>http://www.blogjava.net/xzhoujun/archive/2007/05/18/118251.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xzhoujun/comments/commentRss/118251.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xzhoujun/services/trackbacks/118251.html</trackback:ping><description><![CDATA[在服务器运行过程中，Spring不停的运行的计划任务和OpenSessionInViewFilter，使得Tomcat反复加载对象而产生框架并用时可能产生的内存泄漏，则使用IntrospectorCleanupListener作为相应的解决办法。"
<p>对于这一句话,引用关于IntrospectorCleanupListener一段解释:</p><p></p><div class="quote_title">引用</div><div class="quote_div">spring中的提供了一个名为org.springframework.web.util.IntrospectorCleanupListener的监听器。它主要负责处理由　JavaBeans Introspector的使用而引起的缓冲泄露。spring中对它的描述如下：它是一个在web应用关闭的时候,清除JavaBeans Introspector的监听器.web.xml中注册这个listener.可以保证在web 应用关闭的时候释放与掉这个web 应用相关的class loader 和由它管理的类如果你使用了JavaBeans Introspector来分析应用中的类,Introspector 缓冲中会保留这些类的引用.结果在你的应用关闭的时候,这些类以及web 应用相关的class loader没有被垃圾回收.不幸的是,清除Introspector的唯一方式是刷新整个缓冲.这是因为我们没法判断哪些是属于你的应用的引用.所以删除被缓冲的introspection会导致把这台电脑上的所有应用的introspection都删掉.需要注意的是,spring 托管的bean不需要使用这个监听器.因为spring它自己的introspection所使用的缓冲在分析完一个类之后会被马上从javaBeans Introspector缓冲中清除掉.应用程序中的类从来不直接使用JavaBeans Introspector.所以他们一般不会导致内部查看资源泄露.但是一些类库和框架往往会产生这个问题.例如:Struts 和Quartz.单个的内部查看泄漏会导致整个的web应用的类加载器不能进行垃圾回收.在web应用关闭之后,你会看到此应用的所有静态类资源(例如单例).这个错误当然不是由这个类自 身引起的. 
<p></p><p>用法很简单，就是在web.xml中加入: <br />&lt;listener&gt; <br />&lt;listener-class&gt;org.springframework.web.util.IntrospectorCleanupListener&lt;/listener-class&gt; <br />&lt;/listener&gt;</p></div><p><u><font color="#0000ff"></font></u> </p><img src ="http://www.blogjava.net/xzhoujun/aggbug/118251.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xzhoujun/" target="_blank">银色幻想</a> 2007-05-18 09:54 <a href="http://www.blogjava.net/xzhoujun/archive/2007/05/18/118251.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>rmi的实现</title><link>http://www.blogjava.net/xzhoujun/archive/2006/11/04/79033.html</link><dc:creator>银色幻想</dc:creator><author>银色幻想</author><pubDate>Sat, 04 Nov 2006 02:26:00 GMT</pubDate><guid>http://www.blogjava.net/xzhoujun/archive/2006/11/04/79033.html</guid><wfw:comment>http://www.blogjava.net/xzhoujun/comments/79033.html</wfw:comment><comments>http://www.blogjava.net/xzhoujun/archive/2006/11/04/79033.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xzhoujun/comments/commentRss/79033.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xzhoujun/services/trackbacks/79033.html</trackback:ping><description><![CDATA[RMI，远程方法调用（Remote Method Invocation）是Enterprise JavaBeans的支柱，是建立分布式Java应用程序的方便途径。RMI是非常容易使用的，但是它非常的强大。<br />　　RMI的基础是接口，RMI构架基于一个重要的原理：定义接口和定义接口的具体实现是分开的。下面我们通过具体的例子，建立一个简单的远程计算服务和使用它的客户程序<br /><br />　　一个正常工作的RMI系统由下面几个部分组成： 
<ul><li>远程服务的接口定义 
</li><li>远程服务接口的具体实现 
</li><li>桩（Stub）和框架（Skeleton）文件 
</li><li>一个运行远程服务的服务器 
</li><li>一个RMI命名服务，它允许客户端去发现这个远程服务 
</li><li>类文件的提供者（一个HTTP或者FTP服务器） 
</li><li>一个需要这个远程服务的客户端程序 </li></ul><p>相关代码如下：<br />接口类<br />public interface RMI_Add extends java.rmi.Remote {<br /> public long add(long a, long b, long c) throws java.rmi.RemoteException;<br />}<br /><br /><br />实现类<br />import java.rmi.Naming;</p><p>public class RMI_AddImpl extends java.rmi.server.UnicastRemoteObject implements RMI_Add {<br /> public RMI_AddImpl() throws java.rmi.RemoteException {<br />  super();<br /> }</p><p> public long add(long a, long b, long c) throws java.rmi.RemoteException {<br />  return a + b + c;<br /> }</p><p> public static void main(String[] args) {<br />  try {<br />   RMI_Add d = new RMI_AddImpl();<br />   Naming.rebind("rmi://127.0.0.1:1099/RMI_AddService", d);<br />  } catch (Exception e) {<br />   e.printStackTrace();<br />  }<br /> }</p><p>}<br /><br />客户端<br />import java.net.MalformedURLException;<br />import java.rmi.Naming;<br />import java.rmi.NotBoundException;<br />import java.rmi.RMISecurityManager;<br />import java.rmi.RemoteException;</p><p>public class Client {<br /> public static void main(String[] args) {<br />  System.setSecurityManager(new RMISecurityManager());</p><p>  try {<br />   RMI_Add t = (RMI_Add) Naming.lookup("rmi://127.0.0.1:1099/RMI_AddService");<br />   for (int i = 0; i &lt; 10; i++)<br />    System.out.println("Perfect time =" + t.add(1, 2, 3));<br />  } catch (MalformedURLException e) {<br />   e.printStackTrace();<br />  } catch (RemoteException e) {<br />   e.printStackTrace();<br />  } catch (NotBoundException e) {<br />   e.printStackTrace();<br />  }<br /> }</p><p>}<br /><br /><br />一条最简单的安全策略,它允许任何人做任何事,对于你的更加关键性的应用,你必须指定更加详细安全策略。<br />grant {<br />  permission java.security.AllPermission "", "";<br />};<br /><br />相关命令<br />rmic -classpath . -d . RMI_AddImpl<br />start rmiregistry 1099<br />java -Djava.rmi.server.codebase=file:///E:/workspace/rmi/ RMI_AddImpl<br />java -Djava.security.policy=policy.txt Client</p><img src ="http://www.blogjava.net/xzhoujun/aggbug/79033.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xzhoujun/" target="_blank">银色幻想</a> 2006-11-04 10:26 <a href="http://www.blogjava.net/xzhoujun/archive/2006/11/04/79033.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SQL查询优化</title><link>http://www.blogjava.net/xzhoujun/archive/2006/10/29/77912.html</link><dc:creator>银色幻想</dc:creator><author>银色幻想</author><pubDate>Sun, 29 Oct 2006 08:54:00 GMT</pubDate><guid>http://www.blogjava.net/xzhoujun/archive/2006/10/29/77912.html</guid><wfw:comment>http://www.blogjava.net/xzhoujun/comments/77912.html</wfw:comment><comments>http://www.blogjava.net/xzhoujun/archive/2006/10/29/77912.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/xzhoujun/comments/commentRss/77912.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xzhoujun/services/trackbacks/77912.html</trackback:ping><description><![CDATA[
		<p>这个帖子主要总结提高查询速度的方法，涉及到减少连接数据库次数、建立索引、优化语句等方面。</p>
		<p>关于索引，推荐转载的这篇文章<br /><a href="http://blog.csdn.net/dutguoyi/archive/2006/01/10/575617.aspx">http://blog.csdn.net/dutguoyi/archive/2006/01/10/575617.aspx</a></p>
		<p>改善SQL语句的效率<br /><a href="http://community.csdn.net/Expert/topic/5087/5087396.xml?temp=.345669">http://community.csdn.net/Expert/topic/5087/5087396.xml?temp=.345669</a><br />数据量很大怎样加快索检速度<br /><a href="http://community.csdn.net/Expert/topic/5058/5058320.xml?temp=.1229517">http://community.csdn.net/Expert/topic/5058/5058320.xml?temp=.1229517</a><br />索引建立方法的区别<br /><a href="http://community.csdn.net/Expert/topic/5068/5068154.xml?temp=.3010218">http://community.csdn.net/Expert/topic/5068/5068154.xml?temp=.3010218</a><br />频繁插入删除数据需要更新索引<br /><a href="http://community.csdn.net/Expert/topic/4937/4937910.xml?temp=.8428614">http://community.csdn.net/Expert/topic/4937/4937910.xml?temp=.8428614</a><br />测试了一下sql server 2005 全文检索<br /><a href="http://community.csdn.net/Expert/topic/4878/4878430.xml?temp=.6049311">http://community.csdn.net/Expert/topic/4878/4878430.xml?temp=.6049311</a></p>
		<p>其他关于效率的高频问题</p>
		<p>判断一个表的数据不在另一个表中最优秀方法？<br /><a href="http://community.csdn.net/Expert/topic/5038/5038742.xml?temp=.4704553">http://community.csdn.net/Expert/topic/5038/5038742.xml?temp=.4704553</a><br />删除千万级表中重复记录的办法<br /><a href="http://community.csdn.net/Expert/topic/5089/5089261.xml?temp=.7907068">http://community.csdn.net/Expert/topic/5089/5089261.xml?temp=.7907068</a></p>
		<p>数据库数据查询变得不正常类型问题</p>
		<p>大数据量，稳定运行一段时候以后无法得到查询结果。<br /><a href="http://community.csdn.net/Expert/topic/4810/4810464.xml?temp=9.014529E-02">http://community.csdn.net/Expert/topic/4810/4810464.xml?temp=9.014529E-02</a><br /></p>
<img src ="http://www.blogjava.net/xzhoujun/aggbug/77912.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xzhoujun/" target="_blank">银色幻想</a> 2006-10-29 16:54 <a href="http://www.blogjava.net/xzhoujun/archive/2006/10/29/77912.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>EJB笔记</title><link>http://www.blogjava.net/xzhoujun/archive/2006/07/28/60486.html</link><dc:creator>银色幻想</dc:creator><author>银色幻想</author><pubDate>Fri, 28 Jul 2006 02:06:00 GMT</pubDate><guid>http://www.blogjava.net/xzhoujun/archive/2006/07/28/60486.html</guid><wfw:comment>http://www.blogjava.net/xzhoujun/comments/60486.html</wfw:comment><comments>http://www.blogjava.net/xzhoujun/archive/2006/07/28/60486.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xzhoujun/comments/commentRss/60486.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xzhoujun/services/trackbacks/60486.html</trackback:ping><description><![CDATA[1、ejb 基础知识 <br />（1） 无状态会话bean <br />不保存客户机的会话状态 <br />优点：使用小量的实例即可满足大量的客户。每个实例都没有标识，相互之间是等价的。 <br />等?的无状态会话bean： 多次和一次调用的结果和效应相同。 <br />在集群中可以负载均衡 a 机器失败，可以在b机器上重试 <br />非等?的无状态会话bean： 如：计数器 <br />不能自动因故障而进行切换。 <br />（2） 有状态会话bean <br />保存客户机的会话状态 <br />特点： 在有会话状态会话的bean例子中，出纳员的数量等于活动的顾客的数量，这可以简化编程模式 <br />weblogic 通过内存复制技术 在集群中进行负载均衡 <br />内存复制技术： 每个有会话状态的bean实例都将存储在两个服务器的内存中，一个服务器作为主服务器，另一个作为辅助服务器。 <br />如果主失败，辅助变为主，然后自动选择别的可用的服务器作为辅助。 <br />遗憾： 很难在Servlet 和JSP中用好有状态会话bean。可能会发生并发现象，产生RemoteException <br /><br />weblogic 的&lt;allow-concurrent-calls&gt; 可以封锁任何并发的调用。 <br />同步： 可以有选择地实现 Javax.ejb.SessionSynchronization接口 <br />afeterBegin() //进入事务时 <br />beforeCompletion() //提交事务前,用于提交前把缓存的数据写到数据库中. <br />afterCompletion() //提交事务后,用于释放共享资源或者更新事务提交和终止方面的统计信息. <br />会话bean通过其 SessionContext 对象中的 getUserTransaction() 方法,取得对UserTransaction的应用 <br />通常 SessionContext 被存放在成员变量中 <br />** 记住是在调用ejb.create()方法前调用 setUserTransaction() 方法 <br />利用对 UserTransaction 的引用会话可以使用 begin() 、commit()、rollback() 方法界定一个事务. <br /><br /><br />（3） 实体 bean： <br />它有一个主健作为唯一的标识符 <br />组成部分: 由本地接口、远程接口、bean类、主健类和配置描述器组成。 <br />本地接口： <br />扩展了javax.ejb.EJBHome接口，包括create（）、remove（）、finder 和home等方法 <br />1)create（）方法调用bean类中的ejbCreate（）方法。相当于数据的insert 方法。 <br />2)remove（）方法相当于数据库的delete操作。 <br />3)finder（）方法，使客户能够查询和接收满足查询条件的实体bean的引用。每个实体bean的本地接口中都必须 <br />有一个findByPrimaryKey() 方法 <br />4)home 方法，类似于无状态会话bean。 <br />主健类： <br />实体bean必须包括一个主健类，主健类用于标识实体bean实例，而且实体bean数据类型必须是唯一的。 <br />主健类可以是java的基本类型String Integer 也可以是用户自定义的。 <br />也可以是多个字段的主健的复合主健。 <br />bean 类和bean的上下文环境： <br />实现javax.ejb.EJBObject 接口,其中包含业务方法的语法格式定义. <br />bean 类实现了javax.ejb.EntityBean接口,同javax.ejb.SessionBean接口一样,EntityBean 接口包含了EJB <br />容器调用bean实例的语法格式. <br />在bean的构造器执行之后,立即调用setEntityContext() 方法,同时把bean实例的EntityContext 传递给它. <br />bean类实现了home方法和远程接口中的业务方法,home方法是针对匿名实例的方法不应使用有关的主健值. <br /><br />分为： <br />容器管理持久性（Container－Managerd Persistence）CMP <br />特点： EJB 容器自动生成，用于把实体bean的数据写入到数据库中。 <br />优点： bean作者可以避免编写实体bean与关系数据库数据访问方面的代码。cmp将自动处理这一过程。 <br />个性: 每一个cmp 实体bean 都有一组容器管理的字段,这些字段存储在数据库,并可从中加载.通常,每个容器管理的字段都对应于 <br />关系数据库中的一个列. <br />容器管理的每个字段必须在ejb-jar.XML中定义,这使容器能够把容器管理的字段与bean类中的set和get方法进行匹配比较. <br />另外,bean作者可以增加另外一个cmp配置描述文件 weblogic-cmp-rdbms.xml,其中包含数据库表名和每个容器管理的字 <br />段和相应的数据列的映射. <br /><br />bean管理持久性（Bean－Managerd Persistence ） BMP <br />特点： 在bmp实体中，bean作者需要自己编写数据库访问代码，也就是编写JDBC代码，插入、删除和查询数据库中的实体bean数据。 <br />优点： 可以让bean的作者完全灵活的处理实体bean的持久性数据，因为作者需要写数据访问的代码，他几乎可以使用任何持久性存 <br />储方式ejb2.0 cmp提供实体bean之间的标准关系映射，使容器能自动管理业务对象之间的交互。 <br />cmp拥有更多的访问控制，因此cmp比bmp有较好的性能。 <br /><br />（4） 消息 bean <br />把JMS 和EJB 成功结合在一起，集成的结果 <br />特点：客户机不需要调用消息bean 相反： 客户机只需要发一个消息给jMS目的。 <br />在消息到达以后，消息bean的onmessage（）方法将被调用，以处理这个消息。 <br />消息bean用于在服务器中执行异步操作。 <br /><br />2。EJB 组成 <br />（1）远程接口 <br />public interface HelloWord extents EJBObject <br />｛ <br />//EJBObject 接口方法 <br />EJBHome getEJBHome() throws RemoteException; <br /><br />Object getPrimaryKey() throws RemoteException; <br /><br />void remove() throws RemoteException, RemoveException; <br /><br />Handle getHandle() throws RemoteException; <br /><br />boolean isIdentical(EJBObject ejbObject) throws RemoteException; <br />｝ <br />（2）本地接口 <br />本地接口是ejb工厂，客户机可以使用本地接口创建、找出和删除ejb实例。只需写本地接口中的方法的语法调用格式 <br />public class HelloWorldHome extends EJBHome <br />｛ <br />//EJBHome 接口方法 <br />void remove(Handle handle) throws RemoteException, RemoveException; <br /><br />void remove(Object o) throws RemoteException, RemoveException; <br /><br />EJBMetaData getEJBMetaData() throws RemoteException; <br /><br />HomeHandle getHomeHandle() throws RemoteException; <br />// Home <br />public HelloWorld create() throws CreateException, RemoteException; <br />｝ <br /><br />（3）bean 类 <br /><br />public class HelloWorldBean implements SessionBean <br />｛ <br />// SessionBean 中的方法 <br />public void setSessionContext(SessionContext sessionContext) <br />/**调用次方法会话结束*/ <br />public void ejbRemove() <br />//ejb通过待命和活动的机制，管理一组正在工作的有状态会话bean实例 <br />/**活动*/ <br />public void ejbActivate() <br />/**待命*/ <br />public void ejbPassivate() <br />// bean类 <br />// 每个home 的create 方法对应一个ejbCreate（）方法 <br />// 有会话状态有很多不同版本的create（）方法。而create 方法必须有ejbCreate（）方法与之一一对应 <br />public void ejbCreate() <br /><br /><br />｝ <br /><br />不要在ejb类中类中实现远程接口 <br />3. EJB 配置描述器 <br />（1）ejb－jar.xml <br />&lt;ejb-jar&gt; (注释) <br />&lt;entERPrise-beans&gt; <br />&lt;session&gt; <br />&lt;ejb-name&gt;HelloWorld（ejbname）&lt;/ejb-name&gt; <br />&lt;home&gt;com.dhc.helloworld.HelloWorldHome（本地接口类）&lt;/home&gt; <br />&lt;remote&gt;com.dhc.helloworld.HelloWorld（远程接口类）&lt;/remote&gt; <br />&lt;ejb-class&gt;com.dhc.helloworld.HelloWorldBean（bean类）&lt;/ejb-class&gt; <br />&lt;session-type&gt;Stateless（无状态会话）&lt;/session-type&gt; <br />&lt;transaction-type&gt;Bean（bean管理的事务）&lt;/transaction-type&gt; <br />&lt;/session&gt; <br />&lt;/enterprise-beans&gt; <br />&lt;container-transaction&gt; <br />&lt;method&gt; <br />&lt;ejb-name&gt;ShoppingCartEjb&lt;/ejb-name&gt; <br />&lt;method-name&gt;*（说明ShoppingCartEjb的默认事务属性指定为Required）&lt;/method-name&gt; <br />&lt;/method&gt; <br />&lt;trans-attribute&gt;Required（容器管理的事务使用的属性 Nerver、NotSupported <br />、Supports、Mandatory、Required、RequiredNew）&lt;/trans-attribute&gt; <br />&lt;/container-transaction&gt; <br />&lt;/ejb-jar&gt; <br />（2）weblogic-ejb-jar.xml (注释) <br />&lt;weblogic-ejb-jar&gt; <br />&lt;weblogic-enterprise-bean&gt; <br />&lt;ejb-name&gt;HelloWorld（ejb名称）&lt;/ejb-name&gt; <br />&lt;jndi-name&gt;HelloWorldEJB（jndi名称）&lt;/jndi-name&gt; <br />&lt;max-bean-in-freepool&gt;10（限制不会有超过10个无状态会话bean并发运行）&lt;/max-bean-in-freepool&gt; <br />&lt;max-bean-in-cache&gt;10（放到内存缓存中的有状态会话bean的最大数量）&lt;/max-bean-in-cache&gt; <br />&lt;/weblogic-enterprise-bean&gt; <br />&lt;/weblogic-ejb-jar&gt; <br /><br />4 . 建立ejb 档案文件 <br />com/dhc/helloworld/（package） <br />com/dhc/helloworld/HelloWorld（远程接口） <br />com/dhc/helloworld/HelloWorldHome（本地接口） <br />com/dhc/helloworld/HelloWorldBean（bean类） <br />META-INF <br />META-INF/ejb－jar.xml（配置描述器） <br />META-INF/weblogic-ejb-jar.xml（weblogic服务器配置描述器） <br /><br />说明： META-INF 必须为大写 <br /><br />5 . 容器管理的事务 <br />Nerver : 不参与事务,如果参与产生RemoteException <br />NotSupported: 不能参与 <br />Supports: 如果调用者正在参与事务,相应的EJB调用也可以参与事务,否则不能 <br />Mandatory 如果调用者有一个事务,相应的EJB可以参与事务,否则,TransactionRequiredException <br />Required 如果调用者有一个事务,相应的EJB可以参与事务,否则,容器将在调用相应的EJB之前,开始一个事务. <br />当方法调用完成以后,即提交该事务. <br />RequiresNew 在调用相应的EJB之前,开始一个新的事务,当方法调用返回时,即提交这个事务. <br /><br /><br />6、ejb 引用 <br /><br />在ejb－jar.xml <br />&lt;ejb-ref&gt; <br />&lt;description&gt; an EJB reference to the Widget EJB(描述)&lt;/description&gt; <br />&lt;ejb-ref-name&gt;ejb/WidgetEJB&lt;/ejb-ref-name&gt; <br />&lt;ejb-ref-type&gt;session&lt;/ejb-ref-type&gt; <br />&lt;home&gt;com.dhc.WidgetHome&lt;/home&gt; <br />&lt;remote&gt;com.dhc.Widget&lt;/remote&gt; <br />&lt;/ejb-ref&gt; <br /><br />在 weblogic-ejb-jar.xml <br />&lt;ejb-reference-description&gt; <br />&lt;ejb-ref-name&gt;ejb/WidgeEJB&lt;/ejb-ref-name&gt; <br />&lt;jndi-name&gt;DeployedWidge&lt;/jndi-name&gt; <br />&lt;/ejb-reference-description&gt; <br /><br />程序 <br />Content ctx = new InitialContent(); <br />Object h = ctx.lookup("java:/comp/env/ejb"); //环境变量是只读的,而且是当前ejb的本地变量. <br />WidgetHome home = (WidgetHome)PortableRemoteObject.narrow(h,WidgeHome.class); <br /><br />7. 资源管理器的引用 <br />定义资源管理的引用 <br />例子： 建立 jdbc、DBPool与JDBC数据源的映射 <br />在ejb－jar.xml <br />&lt;resource-ref&gt; <br />&lt;description&gt;(描述)&lt;/description&gt; <br />&lt;res-ref-name&gt;jdbc/BDPool&lt;/res-ref-name&gt; <br />&lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt; <br />&lt;res-auth&gt;Container&lt;/res-auth&gt; <br />&lt;/resource-ref&gt; <br /><br />在 weblogic-ejb-jar.xml <br />&lt;resource-description&gt; <br />&lt;res-ref-name&gt;jdbc/DBPool&lt;/res-ref-name&gt; <br />&lt;jndi-name&gt;DBPool&lt;/jndi-name&gt; <br />&lt;/resource-description&gt; <br /><br />config.xml <br /><br />&lt;JDBCTxDataSource <br />name="DBPool" <br />Targets="myserver" <br />JDDIName="DBPool" (jndi名称) <br />PoolName ="DevelopmentPool" <br />/&gt; <br /><br />引用的优点 <br />我们用大量的映射和配置，才建立了资源管理器的引用，但是还是很值得的。 <br />以为便于部署人员重新配置应用而不需要修改实际的bean类代码。甚至也不需要修改ejb的配置描述器 <br />java bean 代码 <br /><br />Content ctx = new InitialContent(); <br />DataSource dataSource = (DataSource)ctx.lookup("java:/comp/env/jdbc/DBPool"); <br /><br />8 . 句柄： 作为一个串行化的对象，句柄中封装了足够的信息，以便重建对EJBObject的引用。 <br />句柄可用于在两个相互合作的进程中传递EJBObject的引用。接受进程即可从句柄中取得EJBObject的引用。 <br /><br />为了取得句柄，可以调用EJBObject接口的getHandle（）方法，返回一个Handle实例 <br />为了重建EJBObject 引用。可以使用Handle 接口的getEJBObject（）方法。 <br /><br />例子： <br />HelloWorld hw = home.create(); <br />javax.ejb.Handle handle = hw.getHandle(); <br />HelloWorld helloworld = (HelloWorld)PortableRemoteObject.narrow(handle.getEJBObject(),HelloWorld.class); <br /><br /><br />HomeHandle: <br />类似handle ，但不能用于引用EJBObject <br />HomeHandle 包含足够的信息，可以重建EJBHome（）的引用。 <br />差异： <br />是调用 getHomeHandle（）方法 和getEJBHome（）方法 <br />例子片断： <br />Content ctx ＝ new InitialContext(); <br />Object h = ctx.lookup("HelloWorldEJB"); <br />HelloWorldHome home = (HelloWorldHome)PortableRemoteObject.narrow(h,HelloWorldHome.class); <br />HomeHandle homehandle = home.getHomeHandle(); <br />Object nh = homehandle.getEJBHome(); <br />HelloWorldHome newHomeReference = (HelloWorldHome)PortableRemoteObject.narrow(nh,HelloWorldHome.class); <br /><br />优点: <br />他们可以自动的存储重建引用所需的信息 <br /><br />9.使用事务的技巧: <br />(1) 一个事务不要涉及太多的操作. <br />(2) 容器管理和bean管理的事务 <br />事务既耗费应用服务器中的资源,又耗费数据库资源,所以事务越短越好. <br />尽量使用容器管理事务而不要采用bean管理事务的方式. <br />(3) ejb遇到错误,需要强制事务回滚. 使用EJBObject.setRollbackOnly(); <br />(4) 不能让事务涉及web层和表示逻辑 <br />(5) 企业应用中不应当选用supports 事务属性,因为只有调用者开始一个事务后,ejb才能在事务中运行.<br /><img src ="http://www.blogjava.net/xzhoujun/aggbug/60486.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xzhoujun/" target="_blank">银色幻想</a> 2006-07-28 10:06 <a href="http://www.blogjava.net/xzhoujun/archive/2006/07/28/60486.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>J2EE工程实现中常见安全问题解决对策</title><link>http://www.blogjava.net/xzhoujun/archive/2006/06/20/54030.html</link><dc:creator>银色幻想</dc:creator><author>银色幻想</author><pubDate>Tue, 20 Jun 2006 09:35:00 GMT</pubDate><guid>http://www.blogjava.net/xzhoujun/archive/2006/06/20/54030.html</guid><wfw:comment>http://www.blogjava.net/xzhoujun/comments/54030.html</wfw:comment><comments>http://www.blogjava.net/xzhoujun/archive/2006/06/20/54030.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xzhoujun/comments/commentRss/54030.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xzhoujun/services/trackbacks/54030.html</trackback:ping><description><![CDATA[by fleshwound (<a href="http://www.smatrix.org/" target="_blank">http://www.smatrix.org</a>)<br />(注：这是我们的完整设计中的一部分，其它有些部分尚要求保密，希望这个拙文能给做J2EE项目的兄弟们带来点帮助,有任何关于JAVA安全和密码学理论和应用的问题可以来我们的论坛:<a href="http://bbs.smatrix.org/" target="_blank">http://bbs.smatrix.org</a>)<br />&nbsp;&nbsp; 近年来，随着互连网和计算机的普及，电子商务和电子政务成为当今社会生活的重要组成部分，以网上订购和网上在线支付的为主要功能的网店系统(Web Shop System)是目前电子商务的热门技术。<br />&nbsp;&nbsp; JAVA以它&ldquo;一次编译，处处运行&rdquo;的神奇魅力和强大的安全技术支持，很快成为WEB信息系统开发的首选语言，而J2EE就是为了WEB应用开发而诞生的。目前J2EE的应用大部份都是多层结构的, 良好的分层可以带来很多好处，例如可以使得代码结构清晰，方便组件复用，可以快速适应应用的新需求。同时，JAVA还提供了强大的安全技术(例如:JCA,HTTPS,JSSA等)。对于电子商务系统而言,系统平台的安全性和效率是其中的核心问题,而这些正好是J2EE及其相关技术的强项。<br /><br />0 系统中所要使用的API及其特点介绍<br />该系统中主要使用的技术和特点如下:<br />(1)EJB :主要是作为J2EE中间层，完成商业逻辑。目前主要有三种类型的EJB: 会话 Bean (Session Bean)、实体Bean (Entity Bean)、消息驱动的Bean（MDB）； <br />(2)JAAS:在J2EE 中用于处理认证和授权服务，进行资源控制；<br />(3)JSP和Java Servlets:用于J2EE的表示层，生成用户界面；<br />(4)JDBC:用于数据库（资源层）的连接和与数据库进行交互； <br />(5)JNDI:Java命名和目录接口,该API实际上是用来访问J2EE的所有资源；<br />(6)JMS:Java消息传输服务，配合MDB使用。<br /><br />1 Session的安全问题与解决方案<br />在项目中,保存Session一般有两种方法，一是分别放在客户端，一是集中放在服务器端。在客户端保存Session是指将Session的状态串行化，然后嵌入到返回给客户的HTML页面中。当Session中的信息很少时，这样实现比较容易，另外这种方法还消除了跨越多个服务器复制状态的问题。<br />　　但是在客户端保存Session状态时，必须考虑到由此带来的安全问题，因为黑客可能通过嗅探攻击（Sniffer）获取敏感信息。为了不让敏感信息数据暴露，解决的方法是对数据进行加密或者使用HTTPS，采用SSL技术。<br />　　如果是要保存大量Session状态的应用，最好的方法是将Session状态统一放在服务器端。当状态被保存在服务器上时，不会有客户端Session管理的大小和类型限制。此外，还避免了由此带来的安全问题，而且也不会遇到由于在每个请求间传送Session状态带来的性能影响，但是对服务器的性能要求比较高。网店系统的安全性要求较高，因此Session还是集中放在中间层服务器端,同时对客户端到服务器端采用SSL连接。<br />2客户端的缓存安全设计<br />大部分顾客使用的WEB浏览器将浏览过的页面缓存在磁盘上，这样我们浏览网页的时候不需要重新向服务器发出HTTP请求，对于普通的网页不存在安全问题。但是对于需要保密的WEB应用，会带来安全隐患和泄漏隐私，因此对于客户端缓存，也必须做适当的处理。最好的方法就是禁止使用缓存，但是对于大部分顾客而言，要求在客户端不用缓存是不现实的，因此我们必须在中间层解决该问题，方法是采用Servlet过滤器技术。该技术是Servlet2.3以后才出现的，在J2EE中的应用很广泛。要使用该技术，需要执行以下步骤：<br />（1）&nbsp;&nbsp;&nbsp;&nbsp;编写一个Servlet过滤器，实现javax.servlet.Filter接口；<br />（2）&nbsp;&nbsp;&nbsp;&nbsp;修改Web.xml文件，使容器知道过滤器在什么时候被调用。<br />Javax.servlet.Filter主要有3个方法：<br />(1)init(FilterConfig cfg) :当开始使用 servlet 过滤器服务时，容器调用此方法一次。传送给此方法的 FilterConfig 参数包含 servlet 过滤器的初始化参数；<br />(2)destroy() :当不再使用 servlet 过滤器服务时，容器调用此方法；<br />(3)doFilter(ServletRequest req, ServletResponse res, FilterChain chain): 容器为每个映射至此过滤器的 servlet 请求调用此方法，然后才调用该 servlet 本身。传送至此方法的 FilterChain 参数可用来调用过滤器链中的下一个过滤器。当链中的最后一个过滤器调用 chain.doFilter() 方法时，将运行最初请求的 servlet。因此，所有过滤器都应该调用 chain.doFilter() 方法。如果过滤器代码中的附加认证检查导致故障，则不需要将原始 servlet 实例化。在这种情况下，不需要调用 chain.doFilter() 方法，相反，可将其重定向至其它一些错误页面。<br />如果 servlet 映射至许多 servlet 过滤器，则按照应用程序的部署描述符（web.xml）中的先后出现的次序来调用 servlet 过滤器。这一部分的主要代码如下：<br />//要引入的类库<br />import javax.servlet.*;<br />import javax.servlet.http.HttpServletResponse;<br />import java.io.*;<br />import java.security.*;<br />//设置servlet过滤代码段<br />public class CacheFilter implements Filter {<br />protected FilterConfig filterConfig;<br />private String cachetp;<br />//初始化<br />public void init(FilterConfig filterConfig) throws ServletException <br />{<br />&nbsp;&nbsp;this.filterConfig = filterConfig;<br />&nbsp;&nbsp;cachetp=config.getInitParameter(&quot;CacheControlType&quot;);<br />&nbsp;&nbsp;if (cachetp==null)<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;throw new&nbsp;&nbsp;ServletException(&quot;没有定义Cache控制类型&quot;);<br />&nbsp;&nbsp;}<br />}<br />//<br />public void destroy() <br />{<br />&nbsp;&nbsp;this.filterConfig = null;<br />}<br />//执行过滤器部分<br />public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)<br />throws IOException, ServletException {<br />&nbsp;&nbsp;if (response instanceof HttpServletResponse )<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpServletResponse resp=(HttpServletResponse) response;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resp.addHeader(&quot;Cache-Control&quot;,cachetp);<br />&nbsp;&nbsp;} <br />&nbsp;&nbsp;else<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;throw new&nbsp;&nbsp;ServletException(&quot;非法相应!&quot;);<br />&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;chain.doFilter(request, response);<br />&nbsp;&nbsp;}<br /><br /><br />}<br />以下是在Web.xml中添加的对应的内容<br /><br />&lt;filter id=&quot;Filter_cache&quot;&gt;<br />&nbsp;&nbsp;&lt;filter-name&gt;CacheFilter&lt;/filter-name&gt;<br />&nbsp;&nbsp;&lt;filter-class&gt;CacheFilter&lt;/filter-class&gt;<br />&nbsp;&nbsp;&lt;description&gt;Cache filter&lt;/description&gt;<br />&nbsp;&nbsp;&lt;init-param&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&lt;param-name&gt;CacheControlType&lt;/param-name&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&lt;param-value&gt;no-store&lt;/param-value&gt;<br />&nbsp;&nbsp;&lt;/init-param&gt;<br />&nbsp;&nbsp;&lt;/filter-id&gt;<br />&lt;filter-mapping&gt;<br />&nbsp;&nbsp;&lt;filter-name&gt;CacheFilter&lt;/filter-name&gt;<br />&nbsp;&nbsp;&lt;url-pattern&gt;/cachecontrol&lt;/url-pattern&gt;<br />&lt;/filter-mapping&gt;<br />3视图访问的安全设置<br />　　所有用户都必须登陆，只有登陆才可以看到用户的角色和权限相对应的视图。因此一个重要的问题就是如何防止一个视图或者部分的视图被一个未被授权的客户直接访问。<br />　　在一些情况下，资源被限制为完全不允许某些用户访问,例如：管理后台就不应该让普通顾客会员访问。有几个方法可以做到这一点。一个方法是加入应用逻辑到处理控制器或者视图的程序中，禁止某些用户访问。另一个方案是设置运行时的系统，对于一些资源，仅允许经由另一个应用资源内部调用。在这种情形，对于这些资源的访问必须被通过另一个表现层的应用资源进行，例如一个servlet控制器。对于这些受限制的资源不允许通过浏览器直接调用。<br />　　在J2EE中，可以利用Web容器中内置的安全技术来进行角色访问资源的控制。根据最新版本的servlet和EJB规范，安全限制在web.xml的配置描述文件中描述，我们可以通过配置web.xml来控制角色访问，修改配置描述文件web.xml就可以达到快速修改安全策略的目的。<br />　　安全限制允许使用编程的方法根据用户的角色来控制访问。资源可以被某些角色的用户访问，同时禁止其它的角色访问。另外，某个视图的一部分也可以根据用户的角色来限制其访问。如果某些资源完全不允许来自于浏览器的直接访问，那么这些资源可以配置只允许一些特殊的安全角色访问，而这些安全角色不分配给任何一个用户。这样只要不分配这个安全角色，那么以这种方式配置的资源将禁止所有的浏览器直接访问。下面一个例子就是web.xml配置文件的一部分，它定义了一个安全的角色以限制直接的浏览器访问。角色的名字是&ldquo;vip&rdquo;，受限制资源的名字是specialgood1.jsp、specialgood2.jsp、specialgood3.jsp和bookinfo.jsp。除非一个用户或者组被分配到&ldquo;vip&rdquo;角色，否则这些客户都不可以直接访问这些JSP页面。不过，由于内部的请求并不受这些安全的限制，一个初始时由某servlet控制器处理的请求将会导向到这些受限制的页面，这样它们就可以间接访问这些JSP页面。 <br />&nbsp;&nbsp;&nbsp;&nbsp;＜security-constraint＞<br />&nbsp;&nbsp;&nbsp;&nbsp;＜web-resource-collection＞<br />&nbsp;&nbsp;&nbsp;&nbsp;＜web-resource-name＞specialgood ＜/web-resource-name＞<br />&nbsp;&nbsp;&nbsp;&nbsp;＜description＞special good infomation＜/description＞<br />&nbsp;&nbsp;&nbsp;&nbsp;＜url-pattern＞/shop/jsp/a1/specialgood1.jsp＜/url-pattern＞<br />&nbsp;&nbsp;&nbsp;&nbsp;＜url-pattern＞/shop/jsp/a1/specialgood2.jsp＜/url-pattern＞<br />&nbsp;&nbsp;&nbsp;&nbsp;＜url-pattern＞/shop/jsp/a1/specialgood3.jsp＜/url-pattern＞<br />＜url-pattern＞/shop/jsp/a1/bookinfo.jsp＜/url-pattern＞<br />&nbsp;&nbsp;&nbsp;&nbsp;＜http-method＞GET＜/http-method＞<br />&nbsp;&nbsp;&nbsp;&nbsp;＜http-method＞POST＜/http-method＞<br />&nbsp;&nbsp;&nbsp;&nbsp;＜/web-resource-collection＞<br />&nbsp;&nbsp;&nbsp;&nbsp;＜auth-constraint＞<br />&nbsp;&nbsp;&nbsp;&nbsp;＜role-name＞vip＜/role-name＞<br />&nbsp;&nbsp;&nbsp;&nbsp;＜/auth-constraint＞<br />&nbsp;&nbsp;&nbsp;&nbsp;＜/security-constraint＞<br />3 各层次间的耦合问题与解决策略<br />　　表现层的数据结构，例如HttpServletRequest，应该被限制在表现层上。如果将这些细节放到其它层(主要是业务逻辑层)中，将大大降低了代码的的重用性，令代码变得复杂，并且增加了层间的耦合。解决方法一个常用方法是不让表现层的数据结构和商业层共享，而是拷贝相关的状态到一个更常见的数据结构中再共享。你也可以选择由表现层数据结构中将相关的状态分离出来，作为独立的参数共享。另外在域对象暴露表现层的数据结构，如果将诸如HttpServletRequest的请求处理数据结构和域对象共享，这样做也会增加了应用中两个不同方面的耦合。域对象应该是可重用的组件，如果它们的实现依赖协议或者层相关的细节，它们可重用性就很差，同时维护和调试高耦合的应用更加困难。成熟的解决方案是不通过传送一个HttpServletRequest对象作为一个参数，而是拷贝request对象的状态到一个更为常用的数据结构中，并且将这个对象共享给域对象。你也可以选择由HttpServletRequest对象中将相关的状态分离出来，并且将每一个的状态作为一个独立的参数提供给域对象。<br />4 EJB的安全设计与控制<br />EJB的执行过程一般是这样的：(1)客户端通过JNDI检索Home对象的引用；(2)JNDI返回Home对象的引用；(3)请求创建一个新的EJB对象；(4)创建EJB对象；(5)返回EJB对象；(6)调用商务方法；(7)调用Enterprise Bean.引起EJB的安全问题原因主要存在三个方面:<br />(1)用包嗅探器(Packet Sniffer)获取用户凭证信息并直接调用会话Bean；（2）对实体Bean进行未授权访问；（3）对消息驱动的Bean的无效访问(发布恶意或者虚假的消息).<br />以上安全问题可导致客户端或者服务端欺骗攻击和DDOS攻击。解决问题(1)的方法是使用JAVA中SSL技术来保护通讯，解决(2)的方法是对于实体Bean全部采用本地接口或者采用JAAS(文献[1])，对于(1)和(2)，我们可以同时采取以下措施：让容器完成认证并传输用户凭证信息,另外使用声明性或者程序设计的安全验证角色。对于问题(3),J2EE并没有提供一个很好的方案，我们的解决方案是采用数字签名技术来保证信息来自可信任的源。该方法的结合代码简要说明如下,消息采用JMS传递：<br />//客户端，要用到消息发送者的私钥进行签名<br />...<br />message.setString(&quot;userid&quot;,userid);<br />message.setString(&quot;useritem&quot;,useritem);<br />message.setInt(&quot;usersn&quot;,serialnum);//包含一个序列号<br />message.setString(&quot;usercertid&quot;,certid);<br />String signature=getSignature(userid+&quot;:&quot;+useritem+&quot;:&quot;+serialnum+&quot;:&quot;+certid);<br />//进行签名,其中getSignature为签名函数，要用到消息发送者的私钥进行签名，具体密码学技术可参考文献[2]；<br />message.setString(&quot;signature&quot;,signature);<br />sendmessage(message);//发送信息<br />...<br />//服务器端<br />String checkstr=userid+&quot;:&quot;+message.getString(&quot;useritem&quot;)+&quot;:&quot;+<br />message.getInt(&quot;usersn&quot;)+&quot;:&quot;+usercertid;<br />boolean b_check=checkSignature(checkstr,msg.getString(&quot;signature&quot;),<br />usercertid,userid);<br />//进行验证,其中checkSignature为验证函数，要用到消息发送者的公钥进行验证，具体密码学技术可参考文献[2]；<br />5 CA中心与证书的生成<br />前面我们已经提出在客户端要使用HTTPS和SSL,因此要建立一个自己的CA中心来管理分发证书,加强客户端到中间层服务器端通讯的安全性.建立CA中心的第一步是利用JAVA工具包中的Keytool生成一个X509证书,然后将该证书交由权威CA中心Vertsign签名,再将该证书设置为根证书,建立自己的CA.每次有新用户注册交易的时候，都必须签发一个用户独一无二的证书，关键的过程是如何签发证书.签发证书的过程如下：<br />(1)从中间层CA服务器的密钥库中读取CA的证书：<br />FileInputStream in=new FileInputStream(ShopCAstorename);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;KeyStore ks=KeyStore.getInstance(&quot;JKS&quot;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ks.load(in,storepass);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;java.security.cert.Certificate c1=ks.getCertificate(alias);<br />(2)获得CA的私钥：<br />PrivateKey caprk=(PrivateKey)ks.getKey(alias,cakeypass);<br />(3)从CA的证书中提取签发者信息：<br />byte[] encod1=c1.getEncoded();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;X509CertImpl shopcimp1=new X509CertImpl(encod1); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;X509CertInfo shopcinfo1=(X509CertInfo)shopcimp1.get(X509CertImpl.NAME+<br />&quot;.&quot;+X509CertImpl.INFO);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;X500Name issuer=(X500Name)shopcinfo1.get(X509CertInfo.SUBJECT+<br />&quot;.&quot;+CertificateIssuerName.DN_NAME);<br />(4)获取待签发的证书相关信息，与（3）类似；<br />(5)设置新证书的有效期、序列号、签发者和签名算法：<br />//设置新证书有效期为1年<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Date begindate =new Date();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Date enddate =new Date(begindate.getTime()+3000*24*360*60*1000L);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CertificateValidity cv=new CertificateValidity(begindate,enddate);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cinfo2.set(X509CertInfo.VALIDITY,cv);<br />&nbsp;&nbsp;&nbsp;&nbsp; //设置新证书序列号<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int sn=(int)(begindate.getTime()/1000);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CertificateSerialNumber csn=new CertificateSerialNumber(sn);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cinfo2.set(X509CertInfo.SERIAL_NUMBER,csn);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //设置新证书签发者<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cinfo2.set(X509CertInfo.ISSUER+&quot;.&quot;+<br />CertificateIssuerName.DN_NAME,issuer);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//设置新证书算法<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AlgorithmId algorithm = <br />new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cinfo2.set(CertificateAlgorithmId.NAME+<br />&quot;.&quot;+CertificateAlgorithmId.ALGORITHM, algorithm);<br />(6)创建证书并签发：<br />// 创建证书<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;X509CertImpl newcert=new X509CertImpl(cinfo2);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 签名<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;newcert.sign(caprk,&quot;MD5WithRSA&quot;);<br />(7)将新证书提供给注册用户，并提示安装,一般的做法是在用户注册成功后系统立即返回一个证书对象给中间层某个Servlet，由其返回给用户。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;参考文献<br />[1]沈耀,陈昊鹏,李新颜.EJB容器中基于JAAS 的安全机制的实现.[J]:计算机应用与软件 2004.9 16~18 <br />[2](美)Jess Garms著，庞南等译. Java安全性编程指南[M].北京:电子工业出版社 2002<br />[3] <a href="http://java.sun.com/j2ee/" target="_blank">http://java.sun.com/j2ee/</a><br />[4] 蔡剑,景楠. Java 网络程序设计：J2EE（含1.4最新功能）[M].北京: 清华大学出版社 2003<br />[5](美)John Bell Tony Loton. Java Servlets 2.3编程指南[M].北京: 电子工业出版社 2002<br />[6](美)Joseph J.Bambara等著,刘堃等译. J2EE技术内幕[M].北京:机械工业出版社 2002<br />[7](美)Li Gong著.JAVA 2平台安全技术&mdash;&mdash;结构、API设计和实现[M].北京: 机械工业出版社 2000<br />[8](英)Danny Ayers等著,曾国平等译. Java服务器高级编程[M].北京：机械工业出版社 2005<br />[9]http://www.smatrix.org/bbs<br />[10]http://www.smatrix.cn/bbs<br />(欢迎转载，但需保留作者信息！－by felshwound)<img src ="http://www.blogjava.net/xzhoujun/aggbug/54030.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xzhoujun/" target="_blank">银色幻想</a> 2006-06-20 17:35 <a href="http://www.blogjava.net/xzhoujun/archive/2006/06/20/54030.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>正则表达式</title><link>http://www.blogjava.net/xzhoujun/archive/2006/05/05/44663.html</link><dc:creator>银色幻想</dc:creator><author>银色幻想</author><pubDate>Fri, 05 May 2006 10:11:00 GMT</pubDate><guid>http://www.blogjava.net/xzhoujun/archive/2006/05/05/44663.html</guid><wfw:comment>http://www.blogjava.net/xzhoujun/comments/44663.html</wfw:comment><comments>http://www.blogjava.net/xzhoujun/archive/2006/05/05/44663.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xzhoujun/comments/commentRss/44663.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xzhoujun/services/trackbacks/44663.html</trackback:ping><description><![CDATA[
		<p>
				<strong>前言</strong>
		</p>
		<p>正则表达式是烦琐的，但是强大的，学会之后的应用会让你除了提高效率外，会给你带来绝对的成就感。只要认真去阅读这些资料，加上应用的时候进行一定的参考，掌握正则表达式不是问题。</p>
		<p>
				<strong>索引</strong>
		</p>
		<p>
				<a href="file://D:\LinkToneCodes\Tone\ToneRobot\正则表达式(regular expression).htm#1._引子" target="_blank" rel="nofollow">
						<font size="2">1._引子</font>
				</a>
				<font size="2">
						<br />
						<a href="file://D:\LinkToneCodes\Tone\ToneRobot\正则表达式(regular expression).htm#2._正则表达式的历史" target="_blank" rel="nofollow">2._正则表达式的历史</a>
						<br />
				</font>
				<a href="file://D:\LinkToneCodes\Tone\ToneRobot\正则表达式(regular expression).htm#3._正则表达式定义" target="_blank" rel="nofollow">
						<font size="2">3._正则表达式定义</font>
				</a>
		</p>
		<blockquote>
				<p>
						<a href="file://D:\LinkToneCodes\Tone\ToneRobot\正则表达式(regular expression).htm#3.1_普通字符" target="_blank" rel="nofollow">
								<font size="2">3.1_普通字符</font>
						</a>
						<font size="2">
								<br />
								<a href="file://D:\LinkToneCodes\Tone\ToneRobot\正则表达式(regular expression).htm#3.2_非打印字符" target="_blank" rel="nofollow">3.2_非打印字符</a>
								<br />
								<a href="file://D:\LinkToneCodes\Tone\ToneRobot\正则表达式(regular expression).htm#3.3_特殊字符" target="_blank" rel="nofollow">3.3_特殊字符</a>
								<br />
								<a href="file://D:\LinkToneCodes\Tone\ToneRobot\正则表达式(regular expression).htm#3.4_限定符" target="_blank" rel="nofollow">3.4_限定符</a>
								<br />
								<a href="file://D:\LinkToneCodes\Tone\ToneRobot\正则表达式(regular expression).htm#3.5_定位符" target="_blank" rel="nofollow">3.5_定位符</a>
								<br />
								<a href="file://D:\LinkToneCodes\Tone\ToneRobot\正则表达式(regular expression).htm#3.6_选择" target="_blank" rel="nofollow">3.6_选择</a>
								<br />
						</font>
						<a href="file://D:\LinkToneCodes\Tone\ToneRobot\正则表达式(regular expression).htm#3.7_后向引用" target="_blank" rel="nofollow">
								<font size="2">3.7_后向引用</font>
						</a>
				</p>
		</blockquote>
		<p>
				<a href="file://D:\LinkToneCodes\Tone\ToneRobot\正则表达式(regular expression).htm#4._各种操作符的运算优先级" target="_blank" rel="nofollow">
						<font size="2">4._各种操作符的运算优先级</font>
				</a>
				<font size="2">
						<br />
						<a href="file://D:\LinkToneCodes\Tone\ToneRobot\正则表达式(regular expression).htm#5._全部符号解释" target="_blank" rel="nofollow">5._全部符号解释</a>
						<br />
						<a href="file://D:\LinkToneCodes\Tone\ToneRobot\正则表达式(regular expression).htm#6._部分例子" target="_blank" rel="nofollow">6._部分例子</a>
						<br />
				</font>
				<a href="file://D:\LinkToneCodes\Tone\ToneRobot\正则表达式(regular expression).htm#7._正则表达式匹配规则" target="_blank" rel="nofollow">
						<font size="2">7._正则表达式匹配规则</font>
				</a>
		</p>
		<blockquote>
				<p>
						<a href="file://D:\LinkToneCodes\Tone\ToneRobot\正则表达式(regular expression).htm#7.1_基本模式匹配" target="_blank" rel="nofollow">
								<font size="2">7.1_基本模式匹配</font>
						</a>
						<font size="2">
								<br />
								<a href="file://D:\LinkToneCodes\Tone\ToneRobot\正则表达式(regular expression).htm#7.2_字符簇" target="_blank" rel="nofollow">7.2_字符簇</a>
								<br />
						</font>
						<a href="file://D:\LinkToneCodes\Tone\ToneRobot\正则表达式(regular expression).htm#7.3_确定重复出现" target="_blank" rel="nofollow">
								<font size="2">7.3_确定重复出现</font>
						</a>
				</p>
		</blockquote>
		<hr />
		<h2>
				<a target="_blank" rel="nofollow" name="1._引子">1. 引子</a>
		</h2>
		<p>　　目前，正则表达式已经在很多软件中得到广泛的应用，包括*nix（Linux, Unix等），HP等操作系统，PHP，C#，Java等开发环境，以及很多的应用软件中，都可以看到正则表达式的影子。</p>
		<p>　　正则表达式的使用，可以通过简单的办法来实现强大的功能。为了简单有效而又不失强大，造成了正则表达式代码的难度较大，学习起来也不是很容易，所以需要付出一些努力才行，入门之后参照一定的参考，使用起来还是比较简单有效的。</p>
		<blockquote>
				<p>例子：<span style="BACKGROUND-COLOR: #00ffff"> ^.+@.+\\..+$ </span></p>
		</blockquote>
		<p>　　这样的代码曾经多次把我自己给吓退过。可能很多人也是被这样的代码给吓跑的吧。继续阅读本文将让你也可以自由应用这样的代码。</p>
		<p>　　注意：这里的第7部分跟前面的内容看起来似乎有些重复，目的是把前面表格里的部分重新描述了一次，目的是让这些内容更容易理解。</p>
		<h2>
				<strong>
						<a target="_blank" rel="nofollow" name="2._正则表达式的历史">2. 正则表达式的历史</a>
				</strong>
		</h2>
		<div id="nstext" valign="bottom">　　正则表达式的“祖先”可以一直上溯至对人类神经系统如何工作的早期研究。Warren McCulloch 和 Walter Pitts 这两位神经生理学家研究出一种数学方式来描述这些神经网络。 
<p>　　1956 年, 一位叫 Stephen Kleene 的数学家在 McCulloch 和 Pitts 早期工作的基础上，发表了一篇标题为“神经网事件的表示法”的论文，引入了正则表达式的概念。正则表达式就是用来描述他称为“正则集的代数”的表达式，因此采用“正则表达式”这个术语。</p><p>　　随后，发现可以将这一工作应用于使用 Ken Thompson 的计算搜索算法的一些早期研究，Ken Thompson 是 Unix 的主要发明人。正则表达式的第一个实用应用程序就是 Unix 中的 <em>qed </em>编辑器。</p><p>　　如他们所说，剩下的就是众所周知的历史了。从那时起直至现在正则表达式都是基于文本的编辑器和搜索工具中的一个重要部分。</p></div>
		<p>　</p>
		<h2>
				<strong>
						<a target="_blank" rel="nofollow" name="3._正则表达式定义">3. 正则表达式定义</a>
				</strong>
		</h2>
		<p>　　正则表达式(regular expression)描述了一种字符串匹配的模式，可以用来检查一个串是否含有某种子串、将匹配的子串做替换或者从某个串中取出符合某个条件的子串等。</p>
		<blockquote>
				<ul>
						<li>
								<span style="BACKGROUND-COLOR: #ffff00">列目录时，　dir *.txt或ls *.txt中的*.txt就</span>
								<font color="#ff0000">
										<span style="BACKGROUND-COLOR: #ffff00">不</span>
								</font>
								<span style="BACKGROUND-COLOR: #ffff00">是一个正则表达式,因为这里*与正则式的*的含义是不同的。</span>
						</li>
				</ul>
		</blockquote>
		<p>　　正则表达式是由普通字符（例如字符 a 到 z）以及特殊字符（称为元字符）组成的文字模式。正则表达式作为一个模板，将某个字符模式与所搜索的字符串进行匹配。</p>
		<h3>
				<strong>
						<a target="_blank" rel="nofollow" name="3.1_普通字符">3.1 普通字符</a>
				</strong>
		</h3>
		<p>　　由所有那些未显式指定为元字符的打印和非打印字符组成。这包括所有的大写和小写字母字符，所有数字，所有标点符号以及一些符号。 </p>
		<h3>
				<a target="_blank" rel="nofollow" name="3.2_非打印字符">3.2 非打印字符</a>
		</h3>
		<table cellspacing="1" cellpadding="3" border="0">
				<tbody>
						<tr>
								<th style="FONT-SIZE: 12px" align="left">字符 </th>
								<th style="FONT-SIZE: 12px" align="left">含义</th>
						</tr>
						<tr>
								<td style="FONT-SIZE: 12px">\cx </td>
								<td style="FONT-SIZE: 12px">匹配由x指明的控制字符。例如， \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则，将 c 视为一个原义的 'c' 字符。</td>
						</tr>
						<tr>
								<td style="FONT-SIZE: 12px">\f </td>
								<td style="FONT-SIZE: 12px">匹配一个换页符。等价于 \x0c 和 \cL。</td>
						</tr>
						<tr>
								<td style="FONT-SIZE: 12px">\n </td>
								<td style="FONT-SIZE: 12px">匹配一个换行符。等价于 \x0a 和 \cJ。</td>
						</tr>
						<tr>
								<td style="FONT-SIZE: 12px">\r </td>
								<td style="FONT-SIZE: 12px">匹配一个回车符。等价于 \x0d 和 \cM。</td>
						</tr>
						<tr>
								<td style="FONT-SIZE: 12px">\s </td>
								<td style="FONT-SIZE: 12px">匹配任何空白字符，包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。</td>
						</tr>
						<tr>
								<td style="FONT-SIZE: 12px">\S </td>
								<td style="FONT-SIZE: 12px">匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。</td>
						</tr>
						<tr>
								<td style="FONT-SIZE: 12px">\t </td>
								<td style="FONT-SIZE: 12px">匹配一个制表符。等价于 \x09 和 \cI。</td>
						</tr>
						<tr>
								<td style="FONT-SIZE: 12px">\v </td>
								<td style="FONT-SIZE: 12px">匹配一个垂直制表符。等价于 \x0b 和 \cK。</td>
						</tr>
				</tbody>
		</table>
		<br />　 
<h3><a target="_blank" rel="nofollow" name="3.3_特殊字符">3.3 特殊字符</a></h3>　　所谓特殊字符，就是一些有特殊含义的字符，如上面说的"*.txt"中的*，简单的说就是表示任何字符串的意思。如果要查找文件名中有＊的文件，则需要对＊进行转义，即在其前加一个\。ls \*.txt。正则表达式有以下特殊字符。 
<p>　</p><table cellspacing="1" cellpadding="3" border="0"><tbody><tr><th style="FONT-SIZE: 12px" align="left">特别字符</th><th style="FONT-SIZE: 12px" align="left">说明</th></tr><tr><td style="FONT-SIZE: 12px">$</td><td style="FONT-SIZE: 12px">匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性，则 $ 也匹配 '\n' 或 '\r'。要匹配 $ 字符本身，请使用 \$。</td></tr><tr><td style="FONT-SIZE: 12px">( )</td><td style="FONT-SIZE: 12px">标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符，请使用 \( 和 \)。</td></tr><tr><td style="FONT-SIZE: 12px">*</td><td style="FONT-SIZE: 12px">匹配前面的子表达式零次或多次。要匹配 * 字符，请使用 \*。</td></tr><tr><td style="FONT-SIZE: 12px">+</td><td style="FONT-SIZE: 12px">匹配前面的子表达式一次或多次。要匹配 + 字符，请使用 \+。</td></tr><tr><td style="FONT-SIZE: 12px">.</td><td style="FONT-SIZE: 12px">匹配除换行符 \n之外的任何单字符。要匹配 .，请使用 \。</td></tr><tr><td style="FONT-SIZE: 12px">[ </td><td style="FONT-SIZE: 12px">标记一个中括号表达式的开始。要匹配 [，请使用 \[。</td></tr><tr><td style="FONT-SIZE: 12px">?</td><td style="FONT-SIZE: 12px">匹配前面的子表达式零次或一次，或指明一个非贪婪限定符。要匹配 ? 字符，请使用 \?。</td></tr><tr><td style="FONT-SIZE: 12px">\</td><td style="FONT-SIZE: 12px">将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如， 'n' 匹配字符 'n'。'\n' 匹配换行符。序列 '\\' 匹配 "\"，而 '\(' 则匹配 "("。</td></tr><tr><td style="FONT-SIZE: 12px">^</td><td style="FONT-SIZE: 12px">匹配输入字符串的开始位置，除非在方括号表达式中使用，此时它表示不接受该字符集合。要匹配 ^ 字符本身，请使用 \^。</td></tr><tr><td style="FONT-SIZE: 12px">{</td><td style="FONT-SIZE: 12px">标记限定符表达式的开始。要匹配 {，请使用 \{。</td></tr><tr><td style="FONT-SIZE: 12px">|</td><td style="FONT-SIZE: 12px">指明两项之间的一个选择。要匹配 |，请使用 \|。</td></tr></tbody></table><blockquote><ul><li><strong style="FONT-WEIGHT: 400; BACKGROUND-COLOR: #ffff00">　　构造正则表达式的方法和创建数学表达式的方法一样。也就是用多种元字符与操作符将小的表达式结合在一起来创建更大的表达式。正则表达式的组件可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。</strong></li></ul></blockquote><p>　</p><h3><a target="_blank" rel="nofollow" name="3.4_限定符">3.4 限定符</a></h3>　　限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有*或+或?或{n}或{n,}或{n,m}共6种。<br />*、+和?限定符都是贪婪的，因为它们会尽可能多的匹配文字，只有在它们的后面加上一个?就可以实现非贪婪或最小匹配。<br />　　正则表达式的限定符有：<br />　 
<table cellspacing="1" cellpadding="3" border="0"><tbody><tr><th style="FONT-SIZE: 12px" align="left">字符 </th><th style="FONT-SIZE: 12px" align="left">描述</th></tr><tr><td style="FONT-SIZE: 12px">* </td><td style="FONT-SIZE: 12px">匹配前面的子表达式零次或多次。例如，zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。</td></tr><tr><td style="FONT-SIZE: 12px">+ </td><td style="FONT-SIZE: 12px">匹配前面的子表达式一次或多次。例如，'zo+' 能匹配 "zo" 以及 "zoo"，但不能匹配 "z"。+ 等价于 {1,}。</td></tr><tr><td style="FONT-SIZE: 12px">? </td><td style="FONT-SIZE: 12px">匹配前面的子表达式零次或一次。例如，"do(es)?" 可以匹配 "do" 或 "does" 中的"do" 。? 等价于 {0,1}。</td></tr><tr><td style="FONT-SIZE: 12px">{n} </td><td style="FONT-SIZE: 12px">n 是一个非负整数。匹配确定的 n 次。例如，'o{2}' 不能匹配 "Bob" 中的 'o'，但是能匹配 "food" 中的两个 o。</td></tr><tr><td style="FONT-SIZE: 12px">{n,} </td><td style="FONT-SIZE: 12px">n 是一个非负整数。至少匹配n 次。例如，'o{2,}' 不能匹配 "Bob" 中的 'o'，但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。</td></tr><tr><td style="FONT-SIZE: 12px">{n,m} </td><td style="FONT-SIZE: 12px">m 和 n 均为非负整数，其中n &lt;= m。最少匹配 n 次且最多匹配 m 次。例如，"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。</td></tr></tbody></table><h3><a target="_blank" rel="nofollow" name="3.5_定位符">3.5 定位符</a></h3>　　用来描述字符串或单词的边界，^和$分别指字符串的开始与结束，\b描述单词的前或后边界，\B表示非单词边界。<font color="#ff0000">不能对定位符使用限定符。</font><h3><a target="_blank" rel="nofollow" name="3.6_选择">3.6 选择</a></h3>　　用圆括号将所有选择项括起来，相邻的选择项之间用|分隔。但用圆括号会有一个副作用，是相关的匹配会被缓存，此时可用?:放在第一个选项前来消除这种副作用。<br />　　其中?:是非捕获元之一，还有两个非捕获元是?=和?!，这两个还有更多的含义，前者为正向预查，在任何开始匹配圆括号内的正则表达式模式的位置来匹配搜索字符串，后者为负向预查，在任何开始不匹配该正则表达式模式的位置来匹配搜索字符串。 
<h3><a target="_blank" rel="nofollow" name="3.7_后向引用">3.7 后向引用</a></h3>　　对一个正则表达式模式或部分模式两边添加圆括号将导致相关匹配存储到一个临时缓冲区中，所捕获的每个子匹配都按照在正则表达式模式中从左至右所遇到的内容存储。存储子匹配的缓冲区编号从 1 开始，连续编号直至最大 99 个子表达式。每个缓冲区都可以使用 '\n' 访问，其中 n 为一个标识特定缓冲区的一位或两位十进制数。<br />　　可以使用非捕获元字符 '?:', '?=', or '?!' 来忽略对相关匹配的保存。 
<h2><a target="_blank" rel="nofollow" name="4._各种操作符的运算优先级">4. 各种操作符的运算优先级</a></h2>　　相同优先级的从左到右进行运算，不同优先级的运算先高后低。各种操作符的优先级从高到低如下：<br />　 
<table cellspacing="1" cellpadding="3" border="0"><tbody><tr><th style="FONT-SIZE: 12px" align="left">操作符 </th><th style="FONT-SIZE: 12px" align="left">描述</th></tr><tr><td style="FONT-SIZE: 12px">\ </td><td style="FONT-SIZE: 12px">转义符</td></tr><tr><td style="FONT-SIZE: 12px">(), (?:), (?=), [] </td><td style="FONT-SIZE: 12px">圆括号和方括号</td></tr><tr><td style="FONT-SIZE: 12px">*, +, ?, {n}, {n,}, {n,m} </td><td style="FONT-SIZE: 12px">限定符</td></tr><tr><td style="FONT-SIZE: 12px">^, $, \anymetacharacter </td><td style="FONT-SIZE: 12px">位置和顺序</td></tr><tr><td style="FONT-SIZE: 12px">| </td><td style="FONT-SIZE: 12px">“或”操作</td></tr></tbody></table><h2><a target="_blank" rel="nofollow" name="5._全部符号解释">5. 全部符号解释</a></h2><table cellspacing="1" cellpadding="3" border="0"><tbody><tr><th style="FONT-SIZE: 12px" align="left">字符 </th><th style="FONT-SIZE: 12px" align="left">描述</th></tr><tr><td style="FONT-SIZE: 12px">\ </td><td style="FONT-SIZE: 12px">将下一个字符标记为一个特殊字符、或一个原义字符、或一个 向后引用、或一个八进制转义符。例如，'n' 匹配字符 "n"。'\n' 匹配一个换行符。序列 '\\' 匹配 "\" 而 "\(" 则匹配 "("。</td></tr><tr><td style="FONT-SIZE: 12px">^ </td><td style="FONT-SIZE: 12px">匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性，^ 也匹配 '\n' 或 '\r' 之后的位置。</td></tr><tr><td style="FONT-SIZE: 12px">$ </td><td style="FONT-SIZE: 12px">匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性，$ 也匹配 '\n' 或 '\r' 之前的位置。</td></tr><tr><td style="FONT-SIZE: 12px">* </td><td style="FONT-SIZE: 12px">匹配前面的子表达式零次或多次。例如，zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。</td></tr><tr><td style="FONT-SIZE: 12px">+ </td><td style="FONT-SIZE: 12px">匹配前面的子表达式一次或多次。例如，'zo+' 能匹配 "zo" 以及 "zoo"，但不能匹配 "z"。+ 等价于 {1,}。</td></tr><tr><td style="FONT-SIZE: 12px">? </td><td style="FONT-SIZE: 12px">匹配前面的子表达式零次或一次。例如，"do(es)?" 可以匹配 "do" 或 "does" 中的"do" 。? 等价于 {0,1}。</td></tr><tr><td style="FONT-SIZE: 12px">{n} </td><td style="FONT-SIZE: 12px">n 是一个非负整数。匹配确定的 n 次。例如，'o{2}' 不能匹配 "Bob" 中的 'o'，但是能匹配 "food" 中的两个 o。</td></tr><tr><td style="FONT-SIZE: 12px">{n,} </td><td style="FONT-SIZE: 12px">n 是一个非负整数。至少匹配n 次。例如，'o{2,}' 不能匹配 "Bob" 中的 'o'，但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。</td></tr><tr><td style="FONT-SIZE: 12px">{n,m} </td><td style="FONT-SIZE: 12px">m 和 n 均为非负整数，其中n &lt;= m。最少匹配 n 次且最多匹配 m 次。例如，"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。</td></tr><tr><td style="FONT-SIZE: 12px">? </td><td style="FONT-SIZE: 12px">当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时，匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串，而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如，对于字符串 "oooo"，'o+?' 将匹配单个 "o"，而 'o+' 将匹配所有 'o'。</td></tr><tr><td style="FONT-SIZE: 12px">. </td><td style="FONT-SIZE: 12px">匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符，请使用象 '[.\n]' 的模式。</td></tr><tr><td style="FONT-SIZE: 12px">(pattern) </td><td style="FONT-SIZE: 12px">匹配 pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到，在VBScript 中使用 SubMatches 集合，在JScript 中则使用 $0…$9 属性。要匹配圆括号字符，请使用 '\(' 或 '\)'。</td></tr><tr><td style="FONT-SIZE: 12px">(?:pattern) </td><td style="FONT-SIZE: 12px">匹配 pattern 但不获取匹配结果，也就是说这是一个非获取匹配，不进行存储供以后使用。这在使用 "或" 字符 (|) 来组合一个模式的各个部分是很有用。例如， 'industr(?:y|ies) 就是一个比 'industry|industries' 更简略的表达式。</td></tr><tr><td style="FONT-SIZE: 12px">(?=pattern) </td><td style="FONT-SIZE: 12px">正向预查，在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配，也就是说，该匹配不需要获取供以后使用。例如，'Windows (?=95|98|NT|2000)' 能匹配 "Windows 2000" 中的 "Windows" ，但不能匹配 "Windows 3.1" 中的 "Windows"。预查不消耗字符，也就是说，在一个匹配发生后，在最后一次匹配之后立即开始下一次匹配的搜索，而不是从包含预查的字符之后开始。</td></tr><tr><td style="FONT-SIZE: 12px">(?!pattern) </td><td style="FONT-SIZE: 12px">负向预查，在任何不匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配，也就是说，该匹配不需要获取供以后使用。例如'Windows (?!95|98|NT|2000)' 能匹配 "Windows 3.1" 中的 "Windows"，但不能匹配 "Windows 2000" 中的 "Windows"。预查不消耗字符，也就是说，在一个匹配发生后，在最后一次匹配之后立即开始下一次匹配的搜索，而不是从包含预查的字符之后开始</td></tr><tr><td style="FONT-SIZE: 12px">x|y </td><td style="FONT-SIZE: 12px">匹配 x 或 y。例如，'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 则匹配 "zood" 或 "food"。</td></tr><tr><td style="FONT-SIZE: 12px">[xyz] </td><td style="FONT-SIZE: 12px">字符集合。匹配所包含的任意一个字符。例如， '[abc]' 可以匹配 "plain" 中的 'a'。</td></tr><tr><td style="FONT-SIZE: 12px">[^xyz] </td><td style="FONT-SIZE: 12px">负值字符集合。匹配未包含的任意字符。例如， '[^abc]' 可以匹配 "plain" 中的'p'。</td></tr><tr><td style="FONT-SIZE: 12px">[a-z] </td><td style="FONT-SIZE: 12px">字符范围。匹配指定范围内的任意字符。例如，'[a-z]' 可以匹配 'a' 到 'z' 范围内的任意小写字母字符。</td></tr><tr><td style="FONT-SIZE: 12px">[^a-z] </td><td style="FONT-SIZE: 12px">负值字符范围。匹配任何不在指定范围内的任意字符。例如，'[^a-z]' 可以匹配任何不在 'a' 到 'z' 范围内的任意字符。</td></tr><tr><td style="FONT-SIZE: 12px">\b </td><td style="FONT-SIZE: 12px">匹配一个单词边界，也就是指单词和空格间的位置。例如， 'er\b' 可以匹配"never" 中的 'er'，但不能匹配 "verb" 中的 'er'。</td></tr><tr><td style="FONT-SIZE: 12px">\B </td><td style="FONT-SIZE: 12px">匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er'，但不能匹配 "never" 中的 'er'。</td></tr><tr><td style="FONT-SIZE: 12px">\cx </td><td style="FONT-SIZE: 12px">匹配由 x 指明的控制字符。例如， \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则，将 c 视为一个原义的 'c' 字符。</td></tr><tr><td style="FONT-SIZE: 12px">\d </td><td style="FONT-SIZE: 12px">匹配一个数字字符。等价于 [0-9]。</td></tr><tr><td style="FONT-SIZE: 12px">\D </td><td style="FONT-SIZE: 12px">匹配一个非数字字符。等价于 [^0-9]。</td></tr><tr><td style="FONT-SIZE: 12px">\f </td><td style="FONT-SIZE: 12px">匹配一个换页符。等价于 \x0c 和 \cL。</td></tr><tr><td style="FONT-SIZE: 12px">\n </td><td style="FONT-SIZE: 12px">匹配一个换行符。等价于 \x0a 和 \cJ。</td></tr><tr><td style="FONT-SIZE: 12px">\r </td><td style="FONT-SIZE: 12px">匹配一个回车符。等价于 \x0d 和 \cM。</td></tr><tr><td style="FONT-SIZE: 12px">\s </td><td style="FONT-SIZE: 12px">匹配任何空白字符，包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。</td></tr><tr><td style="FONT-SIZE: 12px">\S </td><td style="FONT-SIZE: 12px">匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。</td></tr><tr><td style="FONT-SIZE: 12px">\t </td><td style="FONT-SIZE: 12px">匹配一个制表符。等价于 \x09 和 \cI。</td></tr><tr><td style="FONT-SIZE: 12px">\v </td><td style="FONT-SIZE: 12px">匹配一个垂直制表符。等价于 \x0b 和 \cK。</td></tr><tr><td style="FONT-SIZE: 12px">\w </td><td style="FONT-SIZE: 12px">匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。</td></tr><tr><td style="FONT-SIZE: 12px">\W </td><td style="FONT-SIZE: 12px">匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。</td></tr><tr><td style="FONT-SIZE: 12px">\xn </td><td style="FONT-SIZE: 12px">匹配 n，其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如，'\x41' 匹配 "A"。'\x041' 则等价于 '\x04' &amp; "1"。正则表达式中可以使用 ASCII 编码。.</td></tr><tr><td style="FONT-SIZE: 12px">\num </td><td style="FONT-SIZE: 12px">匹配 num，其中 num 是一个正整数。对所获取的匹配的引用。例如，'(.)\1' 匹配两个连续的相同字符。</td></tr><tr><td style="FONT-SIZE: 12px">\n </td><td style="FONT-SIZE: 12px">标识一个八进制转义值或一个向后引用。如果 \n 之前至少 n 个获取的子表达式，则 n 为向后引用。否则，如果 n 为八进制数字 (0-7)，则 n 为一个八进制转义值。</td></tr><tr><td style="FONT-SIZE: 12px">\nm </td><td style="FONT-SIZE: 12px">标识一个八进制转义值或一个向后引用。如果 \nm 之前至少有 nm 个获得子表达式，则 nm 为向后引用。如果 \nm 之前至少有 n 个获取，则 n 为一个后跟文字 m 的向后引用。如果前面的条件都不满足，若 n 和 m 均为八进制数字 (0-7)，则 \nm 将匹配八进制转义值 nm。</td></tr><tr><td style="FONT-SIZE: 12px">\nml </td><td style="FONT-SIZE: 12px">如果 n 为八进制数字 (0-3)，且 m 和 l 均为八进制数字 (0-7)，则匹配八进制转义值 nml。</td></tr><tr><td style="FONT-SIZE: 12px">\un </td><td style="FONT-SIZE: 12px">匹配 n，其中 n 是一个用四个十六进制数字表示的 Unicode 字符。例如， \u00A9 匹配版权符号 (?)。</td></tr></tbody></table><p>　</p><h2><a target="_blank" rel="nofollow" name="6._部分例子">6. 部分例子</a></h2><table cellspacing="1" cellpadding="3" border="0"><tbody><tr><th style="FONT-SIZE: 12px" align="left">正则表达式</th><th style="FONT-SIZE: 12px" align="left">说明</th></tr><tr><td style="FONT-SIZE: 12px">/\b([a-z]+) \1\b/gi</td><td style="FONT-SIZE: 12px">一个单词连续出现的位置</td></tr><tr><td style="FONT-SIZE: 12px">/(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)/ </td><td style="FONT-SIZE: 12px">将一个URL解析为协议、域、端口及相对路径</td></tr><tr><td style="FONT-SIZE: 12px">/^(?:Chapter|Section) [1-9][0-9]{0,1}$/</td><td style="FONT-SIZE: 12px">定位章节的位置</td></tr><tr><td style="FONT-SIZE: 12px">/[-a-z]/</td><td style="FONT-SIZE: 12px">A至z共26个字母再加一个-号。</td></tr><tr><td style="FONT-SIZE: 12px">/ter\b/</td><td style="FONT-SIZE: 12px">可匹配chapter，而不能terminal</td></tr><tr><td style="FONT-SIZE: 12px">/\Bapt/</td><td style="FONT-SIZE: 12px">可匹配chapter，而不能aptitude</td></tr><tr><td style="FONT-SIZE: 12px">/Windows(?=95 |98 |NT )/</td><td style="FONT-SIZE: 12px">可匹配Windows95或Windows98或WindowsNT,当找到一个匹配后，从Windows后面开始进行下一次的检索匹配。</td></tr></tbody></table><p>　</p><h2><a target="_blank" rel="nofollow" name="7._正则表达式匹配规则">7. 正则表达式匹配规则</a></h2><p><strong><a target="_blank" rel="nofollow" name="7.1_基本模式匹配">7.1 基本模式匹配</a></strong><br /><br />　　一切从最基本的开始。模式，是正规表达式最基本的元素，它们是一组描述字符串特征的字符。模式可以很简单，由普通的字符串组成，也可以非常复杂，往往用特殊的字符表示一个范围内的字符、重复出现，或表示上下文。例如：</p><blockquote><p>^once </p></blockquote><p>　　这个模式包含一个特殊的字符^，表示该模式只匹配那些以once开头的字符串。例如该模式与字符串"once upon a time"匹配，与"There once was a man from NewYork"不匹配。正如如^符号表示开头一样，$符号用来匹配那些以给定模式结尾的字符串。</p><blockquote><p>bucket$ </p></blockquote><p>　　这个模式与"Who kept all of this cash in a bucket"匹配，与"buckets"不匹配。字符^和$同时使用时，表示精确匹配（字符串与模式一样）。例如：</p><blockquote><p>^bucket$ </p></blockquote><p>　　只匹配字符串"bucket"。如果一个模式不包括^和$，那么它与任何包含该模式的字符串匹配。例如：模式</p><blockquote><p>once </p></blockquote><p>与字符串</p><blockquote><p>There once was a man from NewYork<br />Who kept all of his cash in a bucket.</p></blockquote><p>是匹配的。<br /><br />　　在该模式中的字母(o-n-c-e)是字面的字符，也就是说，他们表示该字母本身，数字也是一样的。其他一些稍微复杂的字符，如标点符号和白字符（空格、制表符等），要用到转义序列。所有的转义序列都用反斜杠(\)打头。制表符的转义序列是：\t。所以如果我们要检测一个字符串是否以制表符开头，可以用这个模式：</p><blockquote><p>^\t </p></blockquote><p>类似的，用\n表示“新行”，\r表示回车。其他的特殊符号，可以用在前面加上反斜杠，如反斜杠本身用\\表示，句号.用\.表示，以此类推。<br /><br /><strong><a target="_blank" rel="nofollow" name="7.2_字符簇">7.2 字符簇</a></strong><br /><br />在INTERNET的程序中，正规表达式通常用来验证用户的输入。当用户提交一个form以后，要判断输入的电话号码、地址、EMAIL地址、信用卡号码等是否有效，用普通的基于字面的字符是不够的。<br /><br />所以要用一种更自由的描述我们要的模式的办法，它就是字符簇。要建立一个表示所有元音字符的字符簇，就把所有的元音字符放在一个方括号里：</p><blockquote><p>[AaEeIiOoUu] </p></blockquote><p>这个模式与任何元音字符匹配，但只能表示一个字符。用连字号可以表示一个字符的范围，如：</p><blockquote><p>[a-z] //匹配所有的小写字母 <br />[A-Z] //匹配所有的大写字母 <br />[a-zA-Z] //匹配所有的字母 <br />[0-9] //匹配所有的数字 <br />[0-9\.\-] //匹配所有的数字，句号和减号 <br />[ \f\r\t\n] //匹配所有的白字符 </p></blockquote><p>同样的，这些也只表示一个字符，这是一个非常重要的。如果要匹配一个由一个小写字母和一位数字组成的字符串，比如"z2"、"t6"或"g7"，但不是"ab2"、"r2d3" 或"b52"的话，用这个模式：</p><blockquote><p>^[a-z][0-9]$ </p></blockquote><p>尽管[a-z]代表26个字母的范围，但在这里它只能与第一个字符是小写字母的字符串匹配。<br /><br />前面曾经提到^表示字符串的开头，但它还有另外一个含义。当在一组方括号里使用^是，它表示“非”或“排除”的意思，常常用来剔除某个字符。还用前面的例子，我们要求第一个字符不能是数字：</p><blockquote><p>^[^0-9][0-9]$ </p></blockquote><p>这个模式与"&amp;5"、"g7"及"-2"是匹配的，但与"12"、"66"是不匹配的。下面是几个排除特定字符的例子：</p><blockquote><p>[^a-z] //除了小写字母以外的所有字符 <br />[^\\\/\^] //除了(\)(/)(^)之外的所有字符 <br />[^\"\'] //除了双引号(")和单引号(')之外的所有字符 </p></blockquote><p>特殊字符"." (点，句号)在正规表达式中用来表示除了“新行”之外的所有字符。所以模式"^.5$"与任何两个字符的、以数字5结尾和以其他非“新行”字符开头的字符串匹配。模式"."可以匹配任何字符串，除了空串和只包括一个“新行”的字符串。<br /><br />PHP的正规表达式有一些内置的通用字符簇，列表如下：</p><blockquote><p>字符簇 含义 <br />[[:alpha:]] 任何字母 <br />[[:digit:]] 任何数字 <br />[[:alnum:]] 任何字母和数字 <br />[[:space:]] 任何白字符 <br />[[:upper:]] 任何大写字母 <br />[[:lower:]] 任何小写字母 <br />[[:punct:]] 任何标点符号 <br />[[:xdigit:]] 任何16进制的数字，相当于[0-9a-fA-F] </p></blockquote><p><strong><a target="_blank" rel="nofollow" name="7.3_确定重复出现">7.3 确定重复出现</a></strong><br /><br />到现在为止，你已经知道如何去匹配一个字母或数字，但更多的情况下，可能要匹配一个单词或一组数字。一个单词有若干个字母组成，一组数字有若干个单数组成。跟在字符或字符簇后面的花括号({})用来确定前面的内容的重复出现的次数。 </p><blockquote><p>字符簇 含义 <br />^[a-zA-Z_]$ 所有的字母和下划线 <br />^[[:alpha:]]{3}$ 所有的3个字母的单词 <br />^a$ 字母a <br />^a{4}$ aaaa <br />^a{2,4}$ aa,aaa或aaaa <br />^a{1,3}$ a,aa或aaa <br />^a{2,}$ 包含多于两个a的字符串 <br />^a{2,} 如：aardvark和aaab，但apple不行 <br />a{2,} 如：baad和aaa，但Nantucket不行 <br />\t{2} 两个制表符 <br />.{2} 所有的两个字符 </p></blockquote><p>这些例子描述了花括号的三种不同的用法。一个数字，{x}的意思是“前面的字符或字符簇只出现x次”；一个数字加逗号，{x,}的意思是“前面的内容出现x或更多的次数”；两个用逗号分隔的数字，{x,y}表示“前面的内容至少出现x次，但不超过y次”。我们可以把模式扩展到更多的单词或数字：</p><blockquote><p>^[a-zA-Z0-9_]{1,}$ //所有包含一个以上的字母、数字或下划线的字符串 <br />^[0-9]{1,}$ //所有的正数 <br />^\-{0,1}[0-9]{1,}$ //所有的整数 <br />^\-{0,1}[0-9]{0,}\.{0,1}[0-9]{0,}$ //所有的小数 </p></blockquote><p>最后一个例子不太好理解，是吗？这么看吧：与所有以一个可选的负号(\-{0,1})开头(^)、跟着0个或更多的数字([0-9]{0,})、和一个可选的小数点(\.{0,1})再跟上0个或多个数字([0-9]{0,})，并且没有其他任何东西($)。下面你将知道能够使用的更为简单的方法。<br /><br />特殊字符"?"与{0,1}是相等的，它们都代表着：“0个或1个前面的内容”或“前面的内容是可选的”。所以刚才的例子可以简化为：</p><blockquote><p>^\-?[0-9]{0,}\.?[0-9]{0,}$ </p></blockquote><p>特殊字符"*"与{0,}是相等的，它们都代表着“0个或多个前面的内容”。最后，字符"+"与 {1,}是相等的，表示“1个或多个前面的内容”，所以上面的4个例子可以写成：</p><blockquote><p>^[a-zA-Z0-9_]+$ //所有包含一个以上的字母、数字或下划线的字符串 <br />^[0-9]+$ //所有的正数 <br />^\-?[0-9]+$ //所有的整数 <br />^\-?[0-9]*\.?[0-9]*$ //所有的小数 </p></blockquote><p>当然这并不能从技术上降低正规表达式的复杂性，但可以使它们更容易阅读。</p><img src ="http://www.blogjava.net/xzhoujun/aggbug/44663.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xzhoujun/" target="_blank">银色幻想</a> 2006-05-05 18:11 <a href="http://www.blogjava.net/xzhoujun/archive/2006/05/05/44663.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hibernate的性能优化</title><link>http://www.blogjava.net/xzhoujun/archive/2006/04/22/42500.html</link><dc:creator>银色幻想</dc:creator><author>银色幻想</author><pubDate>Sat, 22 Apr 2006 08:31:00 GMT</pubDate><guid>http://www.blogjava.net/xzhoujun/archive/2006/04/22/42500.html</guid><wfw:comment>http://www.blogjava.net/xzhoujun/comments/42500.html</wfw:comment><comments>http://www.blogjava.net/xzhoujun/archive/2006/04/22/42500.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xzhoujun/comments/commentRss/42500.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xzhoujun/services/trackbacks/42500.html</trackback:ping><description><![CDATA[
		<span class="postbody">1、针对oracle数据库而言，Fetch Size 是设定JDBC的Statement读取数据的时候每次从数据库中取出的记录条数，一般设置为30、50、100。Oracle数据库的JDBC驱动默认的Fetch Size=15，设置Fetch Size设置为：30、50，性能会有明显提升，如果继续增大，超出100，性能提升不明显，反而会消耗内存。 <br />即在hibernate配制文件中进行配制： <br />1 &lt;property name="hibernateProperties"&gt; <br />2 &lt;props&gt; <br />3 &lt;prop key="hibernate.dialect"&gt;org.hibernate.dialect.Oracle9Dialect&lt;/prop&gt; <br />4 &lt;prop key="hibernate.show_sql"&gt;false&lt;/prop&gt; <br />5 &lt;!-- Create/update the database tables automatically when the JVM starts up <br />6 &lt;prop key="hibernate.hbm2ddl.auto"&gt;update&lt;/prop&gt; --&gt; <br />7 &lt;!-- Turn batching off for better error messages under PostgreSQL <br />8 &lt;prop key="hibernate.jdbc.batch_size"&gt;100&lt;/prop&gt; --&gt; <br />9 &lt;prop key="hibernate.jdbc.batch_size"&gt;50&lt;/prop&gt; <br />10 &lt;/props&gt; <br />11 &lt;/property&gt;Fetch Size设的越大，读数据库的次数越少，速度越快；Fetch Size越小，读数据库的次数越多，速度越慢。 <br />2、如果是超大的系统，建议生成htm文件。加快页面提升速度。 <br />3、不要把所有的责任推在hibernate上，对代码进行重构，减少对数据库的操作，尽量避免在数据库查询时使用in操作，以及避免递归查询操作，代码质量、系统设计的合理性决定系统性能的高低。 <br />4、 对大数据量查询时，慎用list()或者iterator()返回查询结果， <br />（1）. 使用List()返回结果时，Hibernate会所有查询结果初始化为持久化对象，结果集较大时，会占用很多的处理时间。 <br />（2）. 而使用iterator()返回结果时，在每次调用iterator.next()返回对象并使用对象时，Hibernate才调用查询将对应的对象初始化，对于大数据量时，每调用一次查询都会花费较多的时间。当结果集较大，但是含有较大量相同的数据，或者结果集不是全部都会使用时，使用iterator()才有优势。 <br />5、在一对多、多对一的关系中，使用延迟加载机制，会使不少的对象在使用时方会初始化，这样可使得节省内存空间以及减少数据库的负荷，而且若PO中的集合没有被使用时，就可减少互数据库的交互从而减少处理时间。 <br />6、对含有关联的PO（持久化对象）时，若default-cascade="all"或者 “save-update”，新增PO时，请注意对PO中的集合的赋值操作，因为有可能使得多执行一次update操作。 <br />7、 对于大数据量新增、修改、删除操作或者是对大数据量的查询，与数据库的交互次数是决定处理时间的最重要因素，减少交互的次数是提升效率的最好途径，所以在开发过程中，请将show_sql设置为true，深入了解Hibernate的处理过程，尝试不同的方式，可以使得效率提升。尽可能对每个页面的显示，对数据库的操作减少到100----150条以内。越少越好。</span>
<img src ="http://www.blogjava.net/xzhoujun/aggbug/42500.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xzhoujun/" target="_blank">银色幻想</a> 2006-04-22 16:31 <a href="http://www.blogjava.net/xzhoujun/archive/2006/04/22/42500.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux下的打包压缩</title><link>http://www.blogjava.net/xzhoujun/archive/2006/04/21/42385.html</link><dc:creator>银色幻想</dc:creator><author>银色幻想</author><pubDate>Fri, 21 Apr 2006 09:54:00 GMT</pubDate><guid>http://www.blogjava.net/xzhoujun/archive/2006/04/21/42385.html</guid><wfw:comment>http://www.blogjava.net/xzhoujun/comments/42385.html</wfw:comment><comments>http://www.blogjava.net/xzhoujun/archive/2006/04/21/42385.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xzhoujun/comments/commentRss/42385.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xzhoujun/services/trackbacks/42385.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 命令																												： 																																																																																		compress  																																														...&nbsp;&nbsp;<a href='http://www.blogjava.net/xzhoujun/archive/2006/04/21/42385.html'>阅读全文</a><img src ="http://www.blogjava.net/xzhoujun/aggbug/42385.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xzhoujun/" target="_blank">银色幻想</a> 2006-04-21 17:54 <a href="http://www.blogjava.net/xzhoujun/archive/2006/04/21/42385.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux常用的日志文件</title><link>http://www.blogjava.net/xzhoujun/archive/2006/04/21/42382.html</link><dc:creator>银色幻想</dc:creator><author>银色幻想</author><pubDate>Fri, 21 Apr 2006 09:48:00 GMT</pubDate><guid>http://www.blogjava.net/xzhoujun/archive/2006/04/21/42382.html</guid><wfw:comment>http://www.blogjava.net/xzhoujun/comments/42382.html</wfw:comment><comments>http://www.blogjava.net/xzhoujun/archive/2006/04/21/42382.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xzhoujun/comments/commentRss/42382.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xzhoujun/services/trackbacks/42382.html</trackback:ping><description><![CDATA[
		<span lang="EN-US" style="FONT-SIZE: 10.5pt; COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">/var/log/boot.log<br /></span>
		<span style="FONT-SIZE: 10.5pt; COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">　　该文件记录了系统在引导过程中发生的事件，就是<span lang="EN-US">Linux</span>系统开机自检过程显示的信息。<br /><br /><span lang="EN-US" style="FONT-SIZE: 10.5pt; COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">/var/log/cron<br /></span><span style="FONT-SIZE: 10.5pt; COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">　　该日志文件记录<span lang="EN-US">crontab</span>守护进程<span lang="EN-US">crond</span>所派生的子进程的动作，前面加上用户、登录时间和<span lang="EN-US">PID</span>，以及派生出的进程的动作。<span lang="EN-US">CMD</span>的一个动作是<span lang="EN-US">cron</span>派生出一个调度进程的常见情况。<span lang="EN-US">REPLACE</span>（替换）动作记录用户对它的<span lang="EN-US">cron</span>文件的更新，该文件列出了要周期性执行的任务调度。<span lang="EN-US">RELOAD</span>动作在<span lang="EN-US">REPLACE</span>动作后不久发生，这意味着<span lang="EN-US">cron</span>注意到一个用户的<span lang="EN-US">cron</span>文件被更新而<span lang="EN-US">cron</span>需要把它重新装入内存。该文件可能会查到一些反常的情况。<br /><span lang="EN-US" style="FONT-SIZE: 10.5pt; COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA"><br />/var/log/maillog<br /></span><span style="FONT-SIZE: 10.5pt; COLOR: black; FONT-FAMILY: 宋体; mso-bidi-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">　　该日志文件记录了每一个发送到系统或从系统发出的电子邮件的活动。它可以用来查看用户使用哪个系统发送工具或把数据发送到哪个系统。</span></span></span>
<img src ="http://www.blogjava.net/xzhoujun/aggbug/42382.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xzhoujun/" target="_blank">银色幻想</a> 2006-04-21 17:48 <a href="http://www.blogjava.net/xzhoujun/archive/2006/04/21/42382.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>