??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲精品国产成人片,久久久久久亚洲精品中文字幕,亚洲精品无码日韩国产不卡avhttp://www.tkk7.com/iamtin/category/7427.htmlYou are coming a long way, baby~Thinking, feeling, memory...zh-cnMon, 17 Sep 2007 20:09:17 GMTMon, 17 Sep 2007 20:09:17 GMT60大型Java Web目的架构和部v调优问题http://www.tkk7.com/iamtin/archive/2007/09/17/java_web_architecture_and_performance_turnning.htmlTinTinMon, 17 Sep 2007 14:48:00 GMThttp://www.tkk7.com/iamtin/archive/2007/09/17/java_web_architecture_and_performance_turnning.htmlhttp://www.tkk7.com/iamtin/comments/146003.htmlhttp://www.tkk7.com/iamtin/archive/2007/09/17/java_web_architecture_and_performance_turnning.html#Feedback0http://www.tkk7.com/iamtin/comments/commentRss/146003.htmlhttp://www.tkk7.com/iamtin/services/trackbacks/146003.html 本文已经发表于InfoQ中文站,Q?a >大型Java Web目的架构和部v问题Q?br />

一位ID是jackson1225的网友在javaeye询问?a title="一个大型Webpȝ的架构和部v选型问题" target="_blank">一个大型Webpȝ的架构和部v选型问题Q希望能提高现有的基于Java的Web应用的服务能力。由于架构模式和部v调优一直是JavaC֌的热门话题,q个问题引发了很多热心网友的讨论Q其中一些意见对其它大型Web目也有很好的指导意义。在讨论之初jackson1225q样描述了当前的应用的架构和部vҎ(gu)Q?/p>

目前pȝ架构如下:

  1. web层采用struts+tomcat实现Q整个系l采?0多台web服务器,其负载均衡采用硬件F5来实玎ͼ
  2. 中间层采用无状态会(x)话Bean+DAO+helpercL实现Q共3台weblogic服务器,部v有多个EJBQ其负蝲均衡也采用F5来实玎ͼ
  3. 数据库层的操作是自己写的通用cd现的Q两台ORACLE数据库服务器Q分别存攄户信息和业务数据Q一台SQL SERVER数据库,是第三方的业务数据信息;

web层调用EJBq程接口来访问中间g层。web层首先通过一个XML配置文g中配|的EJB接口信息来调用相应的EJBq程接口Q?/p>

该系l中一ơ操作涉?qing)到两个ORACLE库以?qing)一个SQL SERVER库的讉K和操作,x三个数据库连接,在一个事务中完成?/p>

q样的架构其实很多公叔R在用,因ؓ(f)Struts和Tomcat分别是最行的Java Web MVC框架和Servlet容器Q而F5公司的负载均衡是横向扩展常见的解x案(例如配置session stickyҎ(gu)Q。由于这个系l中有跨数据源的事务Q所以用Weblogic Server EJB容器和支持两阶段提交的数据库驱动可以保证跨数据源的事物完整性(当然Q容器管理的分布式事务ƈ非是唯一和最优的解决Ҏ(gu)Q?/p>

但是随着Rod Johnson重量U的著作《J2EE Development without EJB》和其中的Spring框架的流行,轻量U框架和轻量U容器的概念已经深入人心。所以对于jackson1225提出的这个场景,大多数网友都提出了置疑,认ؓ(f)q个pȝ滥用了技术,完全是在费钱。网友们大都认ؓ(f)SLSBQ无状态会(x)话BeanQ完全没有必要出现在q个场景中,认ؓ(f)SLSB通过q程接口讉K本地资源?x)有很大的性能开销Q这U观点也是Rod johnson在without EJB中批判EJB 2.x中的一大反模式?/p>

׃JavaEE是一个以模式见长的解x案,模式和架构在JavaEE中占有很重要的地位,所以很多业内专家也都警?#8220;反模式(Anti-patternsQ?#8221;的出现。对于上面所q的Ҏ(gu)是否是反模式Qjackson1225马上站出来申辩:(x)

我们目是把EJB作ؓ(f)一个FacadeQ只是提供给WEB层调用的q程接口Q而且只用了无状态会(x)话BeanQ所以性能上还可以的?/p>

q个解释很快得到了一些网友的认可Q但是大家很快意识到架构的好坏决定于是否能够满用户的需求,davexinQ可能是jackson1225的同事)描述了这个系l的用户和ƈ发情况:(x)

现在有用?000万,马上要和另一个公司的?x)员pȝ合ƈQ加h一共有9000万用戗数据量单表中有一亿条以上的数据。这是基本的情况Q其实我觉得现在的架构还是可以的Q现在支持的q发大概5000q发用户左右Q接下来?x)进行系l改造,目标支持1万个q发用户?/p>

具体的ƈ发量公布后又有网友置疑这个数据,认ؓ(f)q个pȝ的Servlet容器支持的ƈ发数太小Q怀疑是否配|不够优化。davexin又补充了该项目的服务器配|:(x)

pȝ前端tomcat都是用的刀片,配置?G内存Qcpu大概?.0GQ每台机器也支?50-400个ƈ发,再多的话Q就?x)相应时间非常的常,?0U,失去了意?Q所以我们才得出q样的结论的?/p>

一位ID是cauherk的网友提Z比较中肯的意见,他没有从Web容器单纯的ƈ发支持能力上提出改进Ҏ(gu)Q而是提出了对于类似的应用?a title="一些通用的改q提C? target="_blank">一些通用的改q提C?/a>Q这里摘要一下:(x)

  1. 数据库压力问?

    可以按照业务、区域等{特性对数据库进行配|,可以考虑分库、用rac、分区、分表等{策略,保数据库能正常的进行交易?/p>

  2. 事务问题

    要在两个数据库中操作Q那么必考虑到分布式事务。你应该仔细的设计你的系l,来避免用分布式事务Q以避免分布式事务带来更多的数据库压力和其它问题。推荐你采用延迟提交的策?q不保证数据的完?Q来避免分布式事务的问题Q毕竟commitp|的几率很低?/p>

  3. web的优?

    静态、图片独立用不同的服务器,对于常态的静态文Ӟ采用E-TAG或者客L(fng)~存Q?google很多是q样q的。对于热点的功能Q考虑使用完全装蝲到内存,保证l对的响应速度Q对于需要频J访问的热点数据Q采用集中缓?多个可以采用负蝲均衡)Q减L据库的压力?/p>

    对于几乎除二q制文gQ都应该在L4上配|基于硬件的压羃Ҏ(gu)Q减网l的量。提高用户用的感知?/p>

  4. |络问题

    可以考虑采用镜像、多路网l接入、基于DNS的负载均衡。如果有_的投资,可以采用CDN(内容分发|?Q减M的服务器压力?/p>

cauherk的这个分析比较到位,其中ETags的方案是最q的一个热点,InfoQ?#8220;使用ETags减少Web应用带宽和负?/a>”里面对这U方案有很详l的介绍。一般以数据库ؓ(f)中心的Web应用的性能瓉都在数据库上Q所以cauherk把数据库和事务问题放C前两位来讨论。但是davexin解释在所讨论的这个项目中数据库ƈ非瓶颈:(x)

我们的压力不在数据库层,在web层和F5?当高峰的时?QF5也被Ҏ(gu)了,是每秒点击过30万,web动态部分根本承受不了。根据我们程序记录,20台web最多承?000个ƈ发,如果再多Qtomcat׃响应了。就像死了一栗?/p>

q个回复让接下来的讨论都集中于Web容器的性能优化Q但?a title="JavaEye站长robbin发表了自q意见" target="_blank">JavaEye站长robbin发表了自q意见Q将话题引回了这个项目的架构本nQ?/p>

performance tuning最重要的就是定位瓶颈在哪里Q以?qing)瓶颈是怎么产生的?/strong>

我的推测是瓶颈还是出在EJBq程Ҏ(gu)调用上!

tomcat上面的java应用要通过EJBq程Ҏ(gu)调用Q来讉Kweblogic上面的无状态SessionBeanQ这L(fng)q程Ҏ(gu)调用一般都?00ms~500msU别Q或者更多。而如果没有远E方法调用,即大量采用spring的动态反,一ơ完整的webh处理在本地JVM内部的完成时间一般也不过20ms而已。一ơwebh需要过长的执行旉Q就?x)导致servletU程被占用更多的旉Q从而无法及(qing)时响应更多的后箋h?/p>

如果q个推测是成立的话,那么我的是既然你没有用到分布式事务Q那么就q脆LEJB。weblogic也可以全部撤掉,业务层用spring取代EJBQ不要搞分布式架构,在每个tomcat实例上面部v一个完整的分层l构?/p>

另外在高q发情况下,apache处理静态资源也很耗内存和CPUQ可以考虑用轻量web server如lighttpd/litespeed/nginx取代之?/p>

robbin的推断得C|友们的支持Qdavexin也认同robbin的看法,但是他解释说公司认ؓ(f)攑ּSLSB存在风险Q所以公司們֐于通过Tomcat替换为Weblogic Server 10来提升系l的用户支撑能力?a title="robbin则马上批评了q种做法" target="_blank">robbin则马上批评了q种做法Q?/p>

坦白说我q从来没有听说过大规模互联网应用使用EJB的先例。ؓ(f)什么大规模互联|应用不能用EJBQ其实就是因为EJB性能太差Q用了EJB几乎必然出现性能障碍?/p>

web容器的性能说到底无非就是ServletU程调度能力而已QTomcat不像WebLogic那样附加n多管理功能,跑得快很正常。对比测试一下WebLogic的数据库q接池和C3P0q接池的性能也会(x)发现cM的结论,C3P0可要比WebLogic的连接池快好几倍了。这不是说WebLogic性能不好Q只不过weblogic要实现更多的功能Q所以在单一的速度斚w׃(x)牺牲很多东西?/p>

以我的经验来判断Q用tomcat5.5以上的版本,配置a(chn)pr支持Q进行必要的tuningQ用BEA JRockit JVM的话Q在你们目前的刀片上面,支撑500个ƈ发完全是可以做到的。结合你们目?0个刀片的gQ那么达?万ƈ发是没问题的。当然这样做的前提是必须扔掉EJBQƈ|web层和业务层在同一个JVM内部?/p>

接下来robbinq针对davexin对话题中的应用分别在tomcat和weblogic上的试数据q行了分析:(x)

引用Q?

2?台weblogic10 ExpressQ相当于1台tomcatQ用于发布jsp应用Q加1台weblogic10Q发布ejb应用Q,能支?000个ƈ发用?.....
......
4?台tomcat4.1?台weblogic8Q只能支?50个ƈ发用Ptomcatpl超Ӟ说明此种l构瓉在tomcat?

q说明瓶颈还不在EJBq程调用上,但是问题已经逐渐清楚了。ؓ(f)什么weblogic充当web容器发vq程EJB调用的时候可以支?000个ƈ发,但是tomcat只能?50个?只有两个可能的原因:(x)

  1. 你的tomcat没有配置好,严重影响了性能表现
  2. tomcat和weblogic之间的接口出了问?

 

接着springside目发v者江南白衣也提出了一个M的优化指|(x)

1.基础配置优化

tomcat 6Q?tomcat参数调优?
JRockit JVM? JVM参数调优Q?br /> Apache+Squid 处理静态内容?

2.业务层优?/p>

部分功能本地化,而不调remote session bean?
异步提交操作,JMSQ?br /> cache热点数据Q?

3.展示层优?/p>

动态页面发布ؓ(f)静态页面?
Cache部分动态页面内容?

davexin在调整了Tomcat配置后应验了robbin对tomcat配置问题的质疑,davexinq样描述l过配置优化以后的测试结果:(x)

l过试Qƈ发h数是可以辑ֈ像robbin所说的一P能够?00人左叻I如果压到q发700人,有15%左右的失败,虽然在调整上面参C后,q发人数上去了,但是在同L(fng)旉内所完成的事务数量下降了10%左右Qƈ且响应时间gq了1U左叻I但从整体上来_(d)牺牲一点事务吞吐量和响应时_(d)q发人数能够提高500Q觉得还是值得的?/p>

xq个话题有了一个比较好的结果。这个话题ƈ非完全针对一个具体的目才有意义Q更重要的是在分析和讨论问题的过E中|友们解决问题的思\Q尤其是cauherk、robbin、江南白衣等几位|友提出的意见可以让q大Java Web目开发者了解到中、大型项目所需要考虑的架构和部v所需要考虑的关键问题,也消除了很多人对轻量Servlet容器与EJB容器性能的一些误解?/p>

在讨Zq有一些小插曲Q如davexin和江南白衣讨ZJRocket的实ӞRealtimeQ版本是否可以提升Servlet容器的相应能?/a>Q答案是不可以。还有ID为mfc42d的网友从Servlet容器的ƈ发支持能力引甛_?a title="Java的线E调度能力和NIO对Servelet容器的意? target="_blank">Java的线E调度能力和NIO对Servelet容器的意?/a>Q他推荐了自q两篇不错的blog“java的线E实?/a>”?#8220;javaq程使用的最大内存的数?/a>”Qblog文章里面从JVM源码U别分析了Java的线E支持能力,面(f)JVM性能调优问题的网友可以认真阅M下?/p>

Tin 2007-09-17 22:48 发表评论
]]>
TSS上面关于hibernate的get和loadҎ(gu)区别的讨?/title><link>http://www.tkk7.com/iamtin/archive/2007/01/26/comment_about_tss_hibernate_difference_between_get_and_load.html</link><dc:creator>Tin</dc:creator><author>Tin</author><pubDate>Fri, 26 Jan 2007 06:27:00 GMT</pubDate><guid>http://www.tkk7.com/iamtin/archive/2007/01/26/comment_about_tss_hibernate_difference_between_get_and_load.html</guid><wfw:comment>http://www.tkk7.com/iamtin/comments/96146.html</wfw:comment><comments>http://www.tkk7.com/iamtin/archive/2007/01/26/comment_about_tss_hibernate_difference_between_get_and_load.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.tkk7.com/iamtin/comments/commentRss/96146.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/iamtin/services/trackbacks/96146.html</trackback:ping><description><![CDATA[ <p>TSS上面Ganesh同志的文章内Ҏ(gu)非常有益的,讨论了session的这两个api的区别。get是每ơ都?x)从数据库取数据以保证数据的可靠。而load则会(x)q回一个proxyQ相当于一个存根,讉K的时候从当前session或者hibernate二~存中查找,如果找不到则从数据库中Lazy Load一下。从Hibernate的复杂性上来说Q这个概念应该算比较Ҏ(gu)理解的,而且q种存在也是非常合理的。顺侉K面还补充了一下JPA里面也有cM的getReferenceҎ(gu)Q行为类似load。看完文章你?x)开始注意这个细节?br />可是Q这个细节的下面却引起了n多h的讨论,讨论的核心就是Hibernate是不是有太多l节了?<br />很多q样不是OO的,很多Hibernate的细节造成它复杂,有h说Hibernate影响了他们的工作效率Q等{,反正反对者站出来很多。我惌是可喜的?br />说明在Java的Killer-APPl合Spring+Hibernate后面q是有很多持怀疑态度的h的,我们随时都需要提问题的大脑!<br />所以,我们也思考一下吧Q?br />1、你一定要量的不断地熟?zhn)你所使用的技术,可以是Hibernate也可以是JDBCQ时M持对相关知识的饥渴。这样减因Z的无知造成的失误?br />2、思考别人的批评Q或者说ORM不好Q或者说q种那种ORM不好Q你都要听着Q然后思考,然后坚持你思考的l果Q直C一ơ思考。这个过E最好保持一定的技术偏执,因ؓ(f)没有性格的程序员不是好程序员?br />3、放眼各U技术,了解怼技术,q样你不?x)在城头更换大王旗的时候失?D。现在我们可以回头看看JDBC Dataset和JPAQ向上向下都要看齐嘛。了解了怼技术更有助于你的思考?br />4、知道你在讨Z么,知道背景。你需要知道Hibernate主要在Java or JavaEE中用,当然有Hibernate.netQ但是它不怎么火。还有,Hibernate的基q是SQL和DBMSQ你需要仔l了解这两种东西?br />5、?zhn)道?/p> <p>Ganesh的原文:(x)<br />Hibernate - Difference between session's get() and load()<br /><a >http://gmarwaha.blogspot.com/2007/01/hibernate-difference-between-sessions.html</a><br />TSS上的讨论Q?br />Difference between Hibernate's get() and load()?<br /><a >http://www.theserverside.com/news/thread.tss?thread_id=43887</a><br /></p> <p>我以前翻译的Hibernate的session的javadocQ当时好像从字面上没有什么大的区别,配合q个帖子Q要重新想一?D<br /><a href="/iamtin/archive/2006/03/06/33910.html">http://www.tkk7.com/iamtin/archive/2006/03/06/33910.html</a><br /><br />BTWQ因为做手术在家休养Q所以才有时间发发牢?D</p> <img src ="http://www.tkk7.com/iamtin/aggbug/96146.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/iamtin/" target="_blank">Tin</a> 2007-01-26 14:27 <a href="http://www.tkk7.com/iamtin/archive/2007/01/26/comment_about_tss_hibernate_difference_between_get_and_load.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>手动为HibernateDAO里面的DetachedCriteria的Projection擦屁?/title><link>http://www.tkk7.com/iamtin/archive/2006/06/06/50702.html</link><dc:creator>Tin</dc:creator><author>Tin</author><pubDate>Tue, 06 Jun 2006 03:28:00 GMT</pubDate><guid>http://www.tkk7.com/iamtin/archive/2006/06/06/50702.html</guid><wfw:comment>http://www.tkk7.com/iamtin/comments/50702.html</wfw:comment><comments>http://www.tkk7.com/iamtin/archive/2006/06/06/50702.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.tkk7.com/iamtin/comments/commentRss/50702.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/iamtin/services/trackbacks/50702.html</trackback:ping><description><![CDATA[ <p>无奈Q寻扑֥的解x法,把我现在擦屁股的现场记录下来?br />我用GenericHibernateDAOQ慢慢积累下来的Q有q几个DetachedCriteria的方法:(x)</p> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"> <span style="COLOR: #0000ff">public</span> <span style="COLOR: #000000"> List findByDetachedCriteriaByPage(<br />        </span> <span style="COLOR: #0000ff">final</span> <span style="COLOR: #000000"> DetachedCriteria detachedCriteria, </span> <span style="COLOR: #0000ff">final</span> <span style="COLOR: #000000"> </span> <span style="COLOR: #0000ff">int</span> <span style="COLOR: #000000"> pagesize,<br />        </span> <span style="COLOR: #0000ff">final</span> <span style="COLOR: #000000"> </span> <span style="COLOR: #0000ff">int</span> <span style="COLOR: #000000"> pageno) {<br />        </span> <span style="COLOR: #0000ff">return</span> <span style="COLOR: #000000"> getHibernateTemplate()<br />                   .findByCriteria(detachedCriteria, pagesize </span> <span style="COLOR: #000000">*</span> <span style="COLOR: #000000"> pageno, pagesize);<br />    }<br /><br /></span> <span style="COLOR: #0000ff">int</span> <span style="COLOR: #000000"> getCountByDetachedCriteria(<br />        </span> <span style="COLOR: #0000ff">final</span> <span style="COLOR: #000000"> DetachedCriteria detachedCriteria) {<br />        Integer count </span> <span style="COLOR: #000000">=</span> <span style="COLOR: #000000"> (Integer) getHibernateTemplate().execute(</span> <span style="COLOR: #0000ff">new</span> <span style="COLOR: #000000"> HibernateCallback() {<br />                    </span> <span style="COLOR: #0000ff">public</span> <span style="COLOR: #000000"> Object doInHibernate(Session session)<br />                        </span> <span style="COLOR: #0000ff">throws</span> <span style="COLOR: #000000"> HibernateException {<br />                        Criteria criteria </span> <span style="COLOR: #000000">=</span> <span style="COLOR: #000000"> detachedCriteria.getExecutableCriteria(session);<br /><br />                        </span> <span style="COLOR: #0000ff">return</span> <span style="COLOR: #000000"> criteria.setProjection(Projections.rowCount())<br />                                       .uniqueResult();<br />                    }<br />                }, </span> <span style="COLOR: #0000ff">true</span> <span style="COLOR: #000000">);<br /><br />        detachedCriteria.setProjection(</span> <span style="COLOR: #0000ff">null</span> <span style="COLOR: #000000">);<br /><br />        </span> <span style="COLOR: #0000ff">return</span> <span style="COLOR: #000000"> count.intValue();<br />    }</span> </div>q是一Ҏ(gu)法,l常一L(fng)Q一开始没有注意,后来发现有副作用?br />生成一个DetachedCriteriaQ调用完getCountByDetachedCriteria以后再调用findByDetachedCriteriaByPageq回的结果居然是一个Integer…?br />原来getCountByDetachedCriteriaҎ(gu)里面对detachedCriteria.getExecutableCriteria(session)产生的criteria讑֮了ProjectionQ这也媄响到了DetachedCriteria本nQ以后再用它作查询都回返回Projection的结果?br />现在的解x法是手动擦屁股,重新set Null。(我原先以为final关键字会(x)保证detachedCriteria不被修改Q后来发现只是引用不能修改,实例本n可以随便修改Q请问大Ӟ有什么更好的解决Ҏ(gu)么,我决得复杂一点的话这个detachedCriteria如何能擦除回来?<br /><hr /><br />Reply from BJUG Groups by <strong><font color="#c88900">whimetQ?br /></font></strong><font face="Courier New" size="2">q个问题在javaeye上已l讨Q?/font><a target="_blank"><font face="Courier New" color="#551a8b" size="2">http://www.hibernate.org.cn/viewtopic.php?t=14657</font></a><font face="Courier New" size="2"><br />你这U情况还单,若DetachedCriteria中包含排序设|就更不好办?<br /></font><p>其实关键问题是DetachedCriteria.getExecutableCriteriaq回的Criteria实例中已l包含了投媄和排序信息,如果你­想先查LQ?<br />得先去掉这些信息;查完LQ再查实际数据时Q又得加上这些信息。而Criteria可没提供对它Ҏ(gu)改去的接口?<br /></p><p>不过Q仔l考察一下DetachedCriteria可以发现Q它cM一U暂存了查询条g的值对象,通过与一个session对象l合生成 <br />一个“可执行的”CriteriaQ相当于先执行session.createCriteriaQ然后把自己保存的条件设|进厅R?<br /></p><p>既然如此Q我q脆自己提供一个类似的c,暂存查询条gQ与sessionl合生成executableCriteriaQ但我先提供l用户一个只包含 <br />查询条g的Criteria实例Q让用户先拿着它去查LQ然后再提供加入投媄和排序信息的Ҏ(gu)Q让用户拿着它去查数据,不就解决问题了?<br /></p><p>-------------- CZ代码Q?<br /></p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">MyDetachedCriteria dc </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> <img src="http://www.tkk7.com/images/dot.gif" /> <br />Criteria c </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> dc.getExecutableCriteria( session );       </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">q里的c只包含查询条Ӟ不包括投影和排序 </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">c.setProjection( Projections.rowCount() ); <br />Integer total </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (Integer) c.uniqueResult();             </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">得到L </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">dc.fillProjectionSetting( c );          </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">把dc中保存的投媄信息讄q去 </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">dc.fillOrdersSetting( c );          </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">把dc中保存的排序信息讄q去 </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">List data </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> c.list();                           </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">取回数据 </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000"><br /><br /></span><span style="COLOR: #000000">--------------</span><span style="COLOR: #000000"> MyDetachedCriteria的代码:(x) <br /></span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"> <br /> * 单独的值对象,用于暂存与Criteria相关的查询条Ӟq可与Sessionl合生成一个可执行的Criteria<br> <br /> * <br> <br /> * 该类l承自DetachedCriteria只是Z保持接口兼容性,其实与DetachedCriteria没关p?lt;br> <br /> * Q之所以叫“Detached”,是指与SessionqQ?br /> </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"> <br /></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> MyDetachedCriteria </span><span style="COLOR: #0000ff">extends</span><span style="COLOR: #000000"> DetachedCriteria { <br /><br /><br />        </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> Class entityClass; <br /><br /><br />        </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> ArrayList criterions </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> ArrayList(); <br /><br /><br />        </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> ArrayList orders </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> ArrayList(); <br /><br /><br />        </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> Projection projection; <br /><br /><br />        </span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"> <br />         * </span><span style="COLOR: #808080">@param</span><span style="COLOR: #008000"> entityClass <br />         </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"> <br />        </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> MyDetachedCriteria( Class entityClass ) { <br />                </span><span style="COLOR: #0000ff">super</span><span style="COLOR: #000000">( entityClass.getName() ); <br />                </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.entityClass </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> entityClass; <br />        } <br /><br /><br />        </span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"> <br />         * </span><span style="COLOR: #808080">@see</span><span style="COLOR: #008000"> org.hibernate.criterion.DetachedCriteria#add(org.hibernate.criterion.CriterBion) <br />         </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"> <br />        </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> DetachedCriteria add( Criterion criterion ) { <br />                criterions.add( criterion ); <br />                </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">; <br />        } <br /><br /><br />        </span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"> <br />         * </span><span style="COLOR: #808080">@see</span><span style="COLOR: #008000"> org.hibernate.criterion.DetachedCriteria#addOrder(org.hibernate.criterion.OBrder) <br />         </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"> <br />        </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> DetachedCriteria addOrder( Order order ) { <br />                orders.add( order ); <br />                </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">; <br />        } <br /><br /><br />        </span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"> <br />         * </span><span style="COLOR: #808080">@see</span><span style="COLOR: #008000"> org.hibernate.criterion.DetachedCriteria#setProjection(org.hibernate.criterBion.Projection) <br />         </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"> <br />        </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> DetachedCriteria setProjection( Projection projection ) { <br />                </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.projection </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> projection; <br />                </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">; <br />        } <br /><br /><br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> --------------------------------------------------------------------------- </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000"><br /><br />        </span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"> <br />         * Ҏ(gu)Session实例创徏一个Criteria实例Qƈ填充入此对象自n保存的条件后q回<br> <br />         * 注意Q返回的Criteria实例不含排序和投׃息,用户需要自p用fillOrdersSetting、?br />         * fillProjectionSetting填充入排序和投媄信息 <br />         * <br />         * </span><span style="COLOR: #808080">@see</span><span style="COLOR: #008000"> org.hibernate.criterion.DetachedCriteria#getExecutableCriteria(org.hibernatBe.Session) <br />         </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"> <br />        </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> Criteria getExecutableCriteria( Session session ) { <br />                Criteria result </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> session.createCriteria( entityClass ); <br /><br /><br />                </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> ( Iterator i </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> criterions.iterator(); i.hasNext(); ) { <br />                        Criterion criterion </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> ( Criterion ) i.next(); <br />                        result.add( criterion ); <br />                } <br /><br /><br />                </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> result; <br />        } <br /><br /><br />        </span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"> <br />         * 填充入排序信息设|?br />         * <br />         * </span><span style="COLOR: #808080">@param</span><span style="COLOR: #008000"> criteria <br />         * </span><span style="COLOR: #808080">@return</span><span style="COLOR: #008000"> <br />         </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"> <br />        </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> Criteria fillOrdersSetting( Criteria criteria ) { <br />                </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> ( Iterator i </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> orders.iterator(); i.hasNext(); ) { <br />                        Order order </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> ( Order ) i.next(); <br />                        criteria.addOrder( order ); <br />                } <br /><br /><br />                </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> criteria; <br />        } <br /><br /><br />        </span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"> <br />         * 填充入投׃息设|?br />         * <br />         * </span><span style="COLOR: #808080">@param</span><span style="COLOR: #008000"> criteria <br />         * </span><span style="COLOR: #808080">@return</span><span style="COLOR: #008000"> <br />         </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"> <br />        </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> Criteria fillProjectionSetting( Criteria criteria ) { <br />                criteria.setProjection( projection ); <br />                </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> criteria; <br />        } <br /><br /><br /><br />} <br /></span></div><hr /><p><br />Update 2006-6-6 20:52Q?br />恩,谢谢怽。想了想q是DetachedCriteria设计的目的和我想要的不一栗DetachedCriteria目前只是Zqsession可以构造,而ƈ不是Z反复使用?br />因ؓ(f)Q?、它里面只包装了一个CriteriaImplQ所以实际上两者生命周期比较一致。而且每次getExecutableCriteria都直接返回这个CriteriaImplQ而不是重新创建,q就造成了容易被意外修改?2、它没有提供与add对应的removeҎ(gu)Q这造成它只能篏U而不能擦拭(对于OrderQ,用反就太脏了?br />whimet写的q个MyDetachedCriteria倒是可以解决问题Q更W合我们惌复用DetachedCriteria的需求,不过我觉得调用v来接口上不太l一。Order和Projection一般不用复用,我想可以不用实现DetachedCriteria接口Q干脆修改GenericDAO的方法好了,写个接受List<Criteria>或者Criteria...的方法对应就可以了。反正觉得DetachedCriteria目前的实现是不如意,hack它吧……我想提供removeq些Order和Projection的方法?br />q里用反解决了他遇到的Order的问题,大家可以参考,看来DetachedCriteria目前实现的还不够令h满意Q?br /><a class="singleposttitle" id="viewpost1_TitleUrl" href="/rory/archive/2006/05/29/48850.html">关于Hibernate的DetachedCriteria查询的addOrder问题的解军_?/a></p><img src ="http://www.tkk7.com/iamtin/aggbug/50702.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/iamtin/" target="_blank">Tin</a> 2006-06-06 11:28 <a href="http://www.tkk7.com/iamtin/archive/2006/06/06/50702.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>060523-JDO2和EJB3 JPA见闻http://www.tkk7.com/iamtin/archive/2006/05/24/47759.htmlTinTinWed, 24 May 2006 01:54:00 GMThttp://www.tkk7.com/iamtin/archive/2006/05/24/47759.htmlhttp://www.tkk7.com/iamtin/comments/47759.htmlhttp://www.tkk7.com/iamtin/archive/2006/05/24/47759.html#Feedback0http://www.tkk7.com/iamtin/comments/commentRss/47759.htmlhttp://www.tkk7.com/iamtin/services/trackbacks/47759.html原来q有个JDO 2.0实现叫做JPOX。而且发现JDO 2.0的接口等定义是由Apache发布的,它是有Sun捐献的?br />JPOX?003q?月才开始开发的Q目前实现支持JDO 1.0和JDO 2.0QJSR-243Q规范?br />JPOXL(fng)支持JDOQL和SQLQ而且以后也要实现EJB3持久化规范中的JPAQJava Persistence APIQ?br />看来BEA有了KodoQJBoss有了HibernateQOracle和Sun有了融合了TopLink的Glassfish中的EJB3持久化容器后Q应该还有其它的厂商可以提供q样的东西出来。而且gJDO 2.0变成真正透明持久化后Q从JDO商业实现转而支持JPA不会(x)很难。本源上说JPA本来是JDO 2.0风格被Gavin King的Hivernate搅合后出来的规范?br />然后发现国内U工厂的Liberator EJB3也是一个JPA和JDO2兼容的EJB3容器Q看来EJB3持久化引擎的实现q是不少的?br />看了一介lEJB3 API的讲座,是TSS和BeJUG提供的:(x)
http://media.techtarget.com/tss/BeJUG/EJB3/index.html
感觉很不错,现在听英文的PPT也比较流畅了。感惛_是和Hibernate非常接近Q其中EntityManager的概念和session非常怼。annotation的用是代码U元数据的最?jng)_c而且发现EJB3吸收了RoR中ActiveRecord的CoCQ惯例代曉K|)的理念,大部分的影射参数都有默认配置Q而且可以通过annotation灉|的覆盖。所以说Q认真学?fn)Hibernate是有用的QShift to EJB3 Persistence的时候就?x)比较容易。后面看到persistence.xml是ؓ(f)了在容器外用EntityManager设计的,对于支持EJB3 Persistence的Java EE容器完全可以直接用EJB3 Persistence模型+元数据编E而不用额外的配置Q这的确是非常方便的Q提供了透明的持久化模型。而persistence.xml则保证J2SE下面也可以用代码管理的EntityManagerQ带来可试和可qJava EE Server的编E模型,更方便且可插拔?br />



Tin 2006-05-24 09:54 发表评论
]]>
hibernate中获取关联属性ؓ(f)null的方?/title><link>http://www.tkk7.com/iamtin/archive/2006/05/11/45643.html</link><dc:creator>Tin</dc:creator><author>Tin</author><pubDate>Thu, 11 May 2006 05:09:00 GMT</pubDate><guid>http://www.tkk7.com/iamtin/archive/2006/05/11/45643.html</guid><wfw:comment>http://www.tkk7.com/iamtin/comments/45643.html</wfw:comment><comments>http://www.tkk7.com/iamtin/archive/2006/05/11/45643.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/iamtin/comments/commentRss/45643.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/iamtin/services/trackbacks/45643.html</trackback:ping><description><![CDATA[在Hibernate中获取有兌关系的pojo。我是指例如一个UserQ用P拥有一个many-to-one的属性UnitQ单位)Q但是有时有些用L(fng)Unit属性ؓ(f)I,如果按单位查询用L(fng)时候那些单位ؓ(f)null的用户就?x)被遗漏Q如何调取呢Q这本来是很单的Q但是我惛_然的使用了Restriction.eqQ但是不行,后来看了手册才发现应该用Restrictions.isNul。下面是Test代码...<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id="Codehighlighter1_1_144_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1_144_Open_Text.style.display='none'; Codehighlighter1_1_144_Closed_Image.style.display='inline'; Codehighlighter1_1_144_Closed_Text.style.display='inline';" src="http://www.tkk7.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_1_144_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1_144_Closed_Text.style.display='none'; Codehighlighter1_1_144_Open_Image.style.display='inline'; Codehighlighter1_1_144_Open_Text.style.display='inline';" src="http://www.tkk7.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="COLOR: #000000">    </span><span id="Codehighlighter1_1_144_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/** */</span><span id="Codehighlighter1_1_144_Open_Text"><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"><br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />     * Z获取一个unit为null的用P如果传入一个null作ؓ(f)Uint实例则返回的l果L0<br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />     * 因ؓ(f)执行的SQL为:(x)(select * ) from USER_INF this_ where this_.UNIT_ID=''<br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />     * q不是我们所期望的结?br /><img src="http://www.tkk7.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />     </span><span style="COLOR: #008000">*/</span></span><span style="COLOR: #000000"><br /><img src="http://www.tkk7.com/images/OutliningIndicators/None.gif" align="top" />    @Test<br /><img id="Codehighlighter1_221_494_Open_Image" onclick="this.style.display='none'; Codehighlighter1_221_494_Open_Text.style.display='none'; Codehighlighter1_221_494_Closed_Image.style.display='inline'; Codehighlighter1_221_494_Closed_Text.style.display='inline';" src="http://www.tkk7.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_221_494_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_221_494_Closed_Text.style.display='none'; Codehighlighter1_221_494_Open_Image.style.display='inline'; Codehighlighter1_221_494_Open_Text.style.display='inline';" src="http://www.tkk7.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> getUsersWhosUnitIsNullByRestrictionsEqNullUnit() </span><span id="Codehighlighter1_221_494_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.tkk7.com/images/dot.gif" /></span><span id="Codehighlighter1_221_494_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />        DetachedCriteria dc </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> DetachedCriteria.forClass(User.</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">);<br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />        dc.add(Restrictions.eq(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">unit</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, </span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">));<br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />        Criteria cri </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> dc.getExecutableCriteria(session);<br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />        log.debug(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">getUsersWhosUnitIsNullByRestrictionsEqNullUnit():</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> cri.list().size());<br /><img src="http://www.tkk7.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />    }</span></span><span style="COLOR: #000000"><br /><img src="http://www.tkk7.com/images/OutliningIndicators/None.gif" align="top" />    <br /><img id="Codehighlighter1_505_647_Open_Image" onclick="this.style.display='none'; Codehighlighter1_505_647_Open_Text.style.display='none'; Codehighlighter1_505_647_Closed_Image.style.display='inline'; Codehighlighter1_505_647_Closed_Text.style.display='inline';" src="http://www.tkk7.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_505_647_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_505_647_Closed_Text.style.display='none'; Codehighlighter1_505_647_Open_Image.style.display='inline'; Codehighlighter1_505_647_Open_Text.style.display='inline';" src="http://www.tkk7.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />    </span><span id="Codehighlighter1_505_647_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/** */</span><span id="Codehighlighter1_505_647_Open_Text"><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"><br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />     * Z获取一个unit为null的用P如果传入一个id为null的Unit实例则会(x)报错Q无法翻译ؓ(f)SQL<br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />     * 错误cd为:(x)org.hibernate.TransientObjectException<br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />     * q也不是我们所期望的结?br /><img src="http://www.tkk7.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />     </span><span style="COLOR: #008000">*/</span></span><span style="COLOR: #000000"><br /><img src="http://www.tkk7.com/images/OutliningIndicators/None.gif" align="top" />    @Ignore<br /><img src="http://www.tkk7.com/images/OutliningIndicators/None.gif" align="top" />    @Test(expected</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">TransientObjectException.</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">)<br /><img id="Codehighlighter1_779_1087_Open_Image" onclick="this.style.display='none'; Codehighlighter1_779_1087_Open_Text.style.display='none'; Codehighlighter1_779_1087_Closed_Image.style.display='inline'; Codehighlighter1_779_1087_Closed_Text.style.display='inline';" src="http://www.tkk7.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_779_1087_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_779_1087_Closed_Text.style.display='none'; Codehighlighter1_779_1087_Open_Image.style.display='inline'; Codehighlighter1_779_1087_Open_Text.style.display='inline';" src="http://www.tkk7.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> getUsersWhosUnitIsNullByRestrictionsEqUnitNullId() </span><span id="Codehighlighter1_779_1087_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.tkk7.com/images/dot.gif" /></span><span id="Codehighlighter1_779_1087_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />        Unit unit </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> Unit();<br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />        log.debug(unit.getId());<br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />        DetachedCriteria dc </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> DetachedCriteria.forClass(User.</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">);<br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />        dc.add(Restrictions.eq(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">unit</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, unit));<br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />        Criteria cri </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> dc.getExecutableCriteria(session);<br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />        log.debug(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">getUsersWhosUnitIsNull():</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> cri.list().size());<br /><img src="http://www.tkk7.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />    }</span></span><span style="COLOR: #000000"><br /><img src="http://www.tkk7.com/images/OutliningIndicators/None.gif" align="top" /><br /><img id="Codehighlighter1_1094_1257_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1094_1257_Open_Text.style.display='none'; Codehighlighter1_1094_1257_Closed_Image.style.display='inline'; Codehighlighter1_1094_1257_Closed_Text.style.display='inline';" src="http://www.tkk7.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_1094_1257_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1094_1257_Closed_Text.style.display='none'; Codehighlighter1_1094_1257_Open_Image.style.display='inline'; Codehighlighter1_1094_1257_Open_Text.style.display='inline';" src="http://www.tkk7.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />    </span><span id="Codehighlighter1_1094_1257_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/** */</span><span id="Codehighlighter1_1094_1257_Open_Text"><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"><br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />     * Z获取一个unit为null的用h的Ҏ(gu)应该是用Restrictions.isNullҎ(gu)<br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />     * 因ؓ(f)执行的SQL为:(x)(select * ) from USER_INF this_ where this_.UNIT_ID is null<br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />     * q才是我们所希望的结?br /><img src="http://www.tkk7.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />     </span><span style="COLOR: #008000">*/</span></span><span style="COLOR: #000000"><br /><img src="http://www.tkk7.com/images/OutliningIndicators/None.gif" align="top" />    @Test<br /><img id="Codehighlighter1_1330_1597_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1330_1597_Open_Text.style.display='none'; Codehighlighter1_1330_1597_Closed_Image.style.display='inline'; Codehighlighter1_1330_1597_Closed_Text.style.display='inline';" src="http://www.tkk7.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_1330_1597_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1330_1597_Closed_Text.style.display='none'; Codehighlighter1_1330_1597_Open_Image.style.display='inline'; Codehighlighter1_1330_1597_Open_Text.style.display='inline';" src="http://www.tkk7.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> getUsersWhosUnitIsNullByRestrictionsIsNull() </span><span id="Codehighlighter1_1330_1597_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.tkk7.com/images/dot.gif" /></span><span id="Codehighlighter1_1330_1597_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />        DetachedCriteria dc </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> DetachedCriteria.forClass(User.</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">);<br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />        dc.add(Restrictions.isNull(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">unit</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">));<br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" /><br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />        Criteria cri </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> dc.getExecutableCriteria(session);<br /><img src="http://www.tkk7.com/images/OutliningIndicators/InBlock.gif" align="top" />        log.debug(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">getUsersWhosUnitIsNullByRestrictionsIsNull():</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> cri.list().size());<br /><img src="http://www.tkk7.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />    }</span></span></div><img src ="http://www.tkk7.com/iamtin/aggbug/45643.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/iamtin/" target="_blank">Tin</a> 2006-05-11 13:09 <a href="http://www.tkk7.com/iamtin/archive/2006/05/11/45643.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>译的Hibernate的Session的javadochttp://www.tkk7.com/iamtin/archive/2006/03/06/33910.htmlTinTinMon, 06 Mar 2006 12:09:00 GMThttp://www.tkk7.com/iamtin/archive/2006/03/06/33910.htmlhttp://www.tkk7.com/iamtin/comments/33910.htmlhttp://www.tkk7.com/iamtin/archive/2006/03/06/33910.html#Feedback6http://www.tkk7.com/iamtin/comments/commentRss/33910.htmlhttp://www.tkk7.com/iamtin/services/trackbacks/33910.html


org.hibernate
Interface Session

All Superinterfaces:
Serializable
All Known Subinterfaces:
EventSource, Session
All Known Implementing Classes:
SessionImpl

public interface Session
extends Serializable

Java应用E序与Hibernate之间的主要运行时接口。它是抽象了持久化服务概늚核心抽象APIcR?br />
Session的生命周期绑定在一个物理的事务QtansactionQ上面。(长的事务可能跨越多个数据库事物。)

Session的主要功能是提供Ҏ(gu)的实体cd例的创徏Q读取和删除操作。实例可能以下面三种状态存在:(x)

自由状态(transientQ? 不曾q行持久化,未与MSession相关?br />持久化状态(persistentQ? 仅与一?tt>Session相关?br />游离状态(detachedQ? 已经q行q持久化Q但当前未与MSession相关?br />
游离状态的实例可以通过调用save()?tt>persist()或?tt>saveOrUpdate()Ҏ(gu)q行持久化。持久化实例可以通过调用 delete()变成游离状态。通过get()?tt>load()Ҏ(gu)得到的实例都是持久化状态的。游ȝ态的实例可以通过调用 update()?saveOrUpdate()?tt>lock()或?tt>replicate()q行持久化。游L者自q态下的实例可以通过调用merge()Ҏ(gu)成ؓ(f)一个新的持久化实例?br />
save()?tt>persist()会(x)引发SQL?tt>INSERTQ?tt>delete()?x)引发SQLDELETEQ?tt>update()?tt>merge()?x)引发SQLUPDATE。对持久化(persistentQ?/i>实例的修改在h提交的时候会(x)被检到Q它也会(x)引vSQLUPDATE?tt>saveOrUpdate()或?tt>replicate()?x)引发SQLINSERT或?tt>UPDATE?br />
其具体实现ƈ不一定是U程安全的。每个线E?事务应该从一?tt>SessionFactory获取自己的session实例?br />
如果其持久化对象cL可序列化的,?tt>Session实例也是可序列化的?br />
一个典型的事务应该使用下面的Ş式:(x)

 Session sess = factory.openSession();
 Transaction tx;
 try {
     tx = sess.beginTransaction();
     //do some work
     ...
     tx.commit();
 }
 catch (Exception e) {
     if (tx!=null) tx.rollback();
     throw e;
 }
 finally {
     sess.close();
 }
 

如果Session抛出了异? 事务必须回滚而session?x)被废弃。在异常发生?tt>Session的内部状态可能会(x)与数据库失去同步?

Author:
Gavin King
See Also:
SessionFactory

Method Summary
 TransactionbeginTransaction()
          开始一个工作单元ƈ且返回相兌?tt>事务QTransactionQ?/tt>对象?
 voidcancelQuery()
          l止执行当前查询?/td>
 voidclear()
          完整的清除这个session?/td>
 Connectionclose()
          停止q个SessionQ通过中断JDBCq接q且清空Qcleaning upQ它?/td>
 Connectionconnection()
          获取q个Session的JDBCq接?br />
如果q个session使用了积极的collection释放{略Q如CMT-容器控制事务的环境下Q,关闭q个调用的连接的职责应该由当前应用程序负责?
 booleancontains(Object object)
          查这个对象实例是否与当前?tt>Session兌Q即是否为Persistent状态)?/td>
 CriteriacreateCriteria(Class persistentClass)
          为给定的实体cL它的类创徏一个新?tt>Criteria实例?/td>
 CriteriacreateCriteria(Class persistentClass, String alias)
          Ҏ(gu)l定的实体类或者它的超cdZ个新?tt>Criteria实例Qƈ赋予它(实体c)一个别名?/td>
 CriteriacreateCriteria(String entityName)
          Ҏ(gu)l定的实体的名称QnameQ,创徏一个新?tt>Criteria实例?/td>
 CriteriacreateCriteria(String entityName, String alias)
          Ҏ(gu)l定的实体的名称QnameQ,创徏一个新?tt>Criteria实例Qƈ赋予它(实体c)一个别?/td>
 QuerycreateFilter(Object collection, String queryString)
          Ҏ(gu)l定的collection和过滤字W串Q查询条Ӟ创徏一个新?tt>Query实例?/td>
 QuerycreateQuery(String queryString)
          Ҏ(gu)l定的HQL查询条g创徏一个新?tt>Query实例?/td>
 SQLQuerycreateSQLQuery(String queryString)
          Ҏ(gu)l定的SQL查询条g创徏一个新?tt>SQLQuery实例?/td>
 voiddelete(Object object)
          从数据库中移除持久化QpersistentQ对象的实例?/td>
 voiddelete(String entityName, Object object)
          从数据库中移除持久化QpersistentQ对象的实例?/td>
 voiddisableFilter(String filterName)
          用当前session的名U过滤器?/td>
 Connectiondisconnect()
          断开Session与当前的JDBCq接?/td>
 FilterenableFilter(String filterName)
          打开当前session的名U过滤器?/td>
 voidevict(Object object)
          当前对象实例从session~存中清除?/td>
 voidflush()
          强制提交hQflushQ?tt>Session?/td>
 Objectget(Class clazz, Serializable id)
          Ҏ(gu)l定标识和实体类q回持久化对象的实例Q如果没有符合条件的持久化对象实例则q回null?/td>
 Objectget(Class clazz, Serializable id, LockMode lockMode)
          Ҏ(gu)l定标识和实体类q回持久化对象的实例Q如果没有符合条件的持久化对象实例则q回null?/td>
 Objectget(String entityName, Serializable id)
          q回与给定的实体命名和标识匹配的持久化实例,如果没有对应的持久化实例则返回null?/td>
 Objectget(String entityName, Serializable id, LockMode lockMode)
          q回与给定的实体cd标识所匚w的持久化实例Q如果没有对应的持久化实例则q回null?/td>
 CacheModegetCacheMode()
          得到当前的缓存模式?/td>
 LockModegetCurrentLockMode(Object object)
          给定对象当前的锁定U别?/td>
 FiltergetEnabledFilter(String filterName)
          Ҏ(gu)名称获取一个当前允许的qo(h)器(filterQ?/td>
 EntityModegetEntityMode()
          获取q个session有效的实体模式?/td>
 StringgetEntityName(Object object)
          q回一个持久化对象的实体名U?/td>
 FlushModegetFlushMode()
          获得当前的刷新提交(flushQ模式?/td>
 SerializablegetIdentifier(Object object)
          获取l定的实体对象实例在Session的缓存中的标识,如果该实例是自由状态(TransientQ的或者与其它Session兌则抛Z个异常?/td>
 QuerygetNamedQuery(String queryName)
          从映文件中Ҏ(gu)l定的查询的名称字符串获取一?tt>QueryQ查询)实例?/td>
 SessiongetSession(EntityMode entityMode)
          Ҏ(gu)l定的实体模式(Entity ModeQ开始一个新的有效的Session?/td>
 SessionFactorygetSessionFactory()
          获取创徏q个session?tt>SessionFactory实例?
 SessionStatisticsgetStatistics()
          获取q个session的统计信息?/td>
 TransactiongetTransaction()
          获取与这个session兌?tt>TransactionQ事务)实例?instance associated with this session.
 booleanisConnected()
          查当?tt>Session是否处于q接状态?/td>
 booleanisDirty()
          当前Session是否包含需要与数据库同步的Q数据状态)变化 Q如果我们刷新提交(flushQ这个session是否?x)有SQL执行Q?/td>
 booleanisOpen()
          查当?tt>Session是否仍然打开?/td>
 Objectload(Class theClass, Serializable id)
          在符合条件的实例存在的情况下Q根据给定的实体cd标识q回持久化状态的实例?/td>
 Objectload(Class theClass, Serializable id, LockMode lockMode)
          在符合条件的实例存在的情况下Q根据给定的实体cR标识及(qing)指定的锁定等U返回持久化状态的实例?/td>
 voidload(Object object, Serializable id)
          与l定的标C对应的持久化状态(|复制到给定的自由状态(trasientQ实例上?/td>
 Objectload(String entityName, Serializable id)
          在符合条件的实例存在的情况下Q根据给定的实体cd标识q回持久化状态的实例?/td>
 Objectload(String entityName, Serializable id, LockMode lockMode)
          在符合条件的实例存在的情况下Q根据给定的实体cR标识及(qing)指定的锁定等U返回持久化状态的实例?/td>
 voidlock(Object object, LockMode lockMode)
          从给定的对象上获取指定的锁定U别?/td>
 voidlock(String entityName, Object object, LockMode lockMode)
          从给定的对象上获取指定的锁定U别?/td>
 Objectmerge(Object object)
          给定的对象的状态复制到h相同标识的持久化对象上?/td>
 Objectmerge(String entityName, Object object)
          给定的对象的状态复制到h相同标识的持久化对象上?/td>
 voidpersist(Object object)
          一个自q态(transientQ的实例持久化?/td>
 voidpersist(String entityName, Object object)
          一个自q态(transientQ的实例持久化?/td>
 voidreconnect()
          不推荐的?/b> 手工的重新连接只应用于应用程序提供连接的情况Q在q种情况下或许应该?a href="/org/hibernate/Session.html#reconnect(java.sql.Connection)">reconnect(java.sql.Connection)?/i>
 voidreconnect(Connection connection)
          重新q接到给定的JDBCq接?/td>
 voidrefresh(Object object)
          从数据库中重新读取给定实例的状态?/td>
 voidrefresh(Object object, LockMode lockMode)
          Ҏ(gu)指定?tt>锁定模式QLockModeQ?/tt>Q从数据库中重新dl定实例的状态?/td>
 voidreplicate(Object object, ReplicationMode replicationMode)
          使用当前的标识值持久化l定的游ȝ态(TransientQ的实体?/td>
 voidreplicate(String entityName, Object object, ReplicationMode replicationMode)
          使用当前的标识值持久化l定的游ȝ态(TransientQ的实体?/td>
 Serializablesave(Object object)
          首先为给定的自由状态(TransientQ的对象Q根据配|)生成一个标识ƈ赋|然后其持久化?/td>
 Serializablesave(String entityName, Object object)
          首先为给定的自由状态(TransientQ的对象Q根据配|)生成一个标识ƈ赋|然后其持久化?/td>
 voidsaveOrUpdate(Object object)
          Ҏ(gu)l定的实例的标识属性的|注:(x)可以指定unsaved-value。一般默认null。)来决定执?save() ?tt>update()操作?/td>
 voidsaveOrUpdate(String entityName, Object object)
          Ҏ(gu)l定的实例的标识属性的|注:(x)可以指定unsaved-value。一般默认null。)来决定执?save() ?tt>update()操作?/td>
 voidsetCacheMode(CacheMode cacheMode)
          讄h提交模式?/td>
 voidsetFlushMode(FlushMode flushMode)
          讄h提交模式?/td>
 voidsetReadOnly(Object entity, boolean readOnly)
          一个未l更改的持久化对象设|ؓ(f)只读模式Q或者将一个只d象标Cؓ(f)可以修改的模式?/td>
 voidupdate(Object object)
          Ҏ(gu)l定的detachedQ游ȝ态)对象实例的标识更新对应的持久化实例?/td>
 voidupdate(String entityName, Object object)
          Ҏ(gu)l定的detachedQ游ȝ态)对象实例的标识更新对应的持久化实例?/td>
 



Tin 2006-03-06 20:09 发表评论
]]>
DomainModel中的hashCode和equalsҎ(gu)http://www.tkk7.com/iamtin/archive/2006/02/15/30775.htmlTinTinWed, 15 Feb 2006 03:34:00 GMThttp://www.tkk7.com/iamtin/archive/2006/02/15/30775.htmlhttp://www.tkk7.com/iamtin/comments/30775.htmlhttp://www.tkk7.com/iamtin/archive/2006/02/15/30775.html#Feedback0http://www.tkk7.com/iamtin/comments/commentRss/30775.htmlhttp://www.tkk7.com/iamtin/services/trackbacks/30775.htmlhashCode:
他是用来产生hash值的Q用在Hashtable上,也包括HashMap{实现?BR>hashCode的基本约定是Q?BR>1、hashCodeҎ(gu)在同一个object上不被调用了多次Q在同一ơ执行的JavaE序中,hashCodeҎ(gu)必须q回一个持l相同的int。在object被修Ҏ(gu)Q不lequalsҎ(gu)提供信息。这个int值在同一个程序的两次不同执行q程中(同一E序执行两次Q,不需要保持恒定?BR>2、如果两个object通过equals()Ҏ(gu)判断相等Q则调用它们的hashCodeҎ(gu)应该产生相同的结果?BR>3、两个通过equals()Ҏ(gu)判定不相{的objectQ调用它们的hashCOdeҎ(gu)q不是必返回不同的l果。但是,成序a们应该意识到对于不相{的object产生不同的intl果有助于提升hashtables的效率?BR>一般技术上Q通过object的内部地址转换为integer的方法来产生hashCodeQ但q不是必需的?/P>

equals:
是判断是否相等的方法?BR>基本U定如下Q?BR>自反Q就是x.equals(x)应该q回true
对称Qx.equals(y)q回true则y.equals(x)q回true
传递:(x)x.euqls(y)==trueQy.equals(z)==trueQ那么x.equals(z)也必返回true
持箋性:(x)是说如果x.equals(y)==trueQ不它调用多少ơ都应该q回true
非空引用Qx.equals(null)应该q回false

准则原因q里Q?BR>http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html#hashCode()

在实际Domain中如何实C们比较好呢?从eclipseWork中的模板生成如下Q?/P>

public boolean equals(Object rhs) {
        
if (rhs == null{
            
return false;
        }


        
if (!(rhs instanceof Town)) {
            
return false;
        }


        Town that 
= (Town) rhs;

        
if ((this.getId() == null|| (that.getId() == null)) {
            
return false;
        }


        
return (this.getId().equals(that.getId()));
    }

public int hashCode() {
        
if (this.hashValue == 0{
            
int result = 17;
            
int idValue = (this.getId() == null? 0 : this.getId().hashCode();
            result 
= (result * 37+ idValue;
            
this.hashValue = result;
        }


        
return this.hashValue;
    }

下一步还要l研IӞ上面的的Ҏ(gu)很类g?SPAN style="COLOR: #999999">Java theory and practice: Hashing it out?BR>http://www-128.ibm.com/developerworks/java/library/j-jtp05273.html

Tin 2006-02-15 11:34 发表评论
]]>
վ֩ģ壺 ƷAVƬ߹ۿ| ޾Ʒպav| ޾Ʒרþþ| þþþ?V| þþþù˾Ʒҹ| ?VƷ | С豻| ɫƵ| 18ëƬaëƬѿ| ˳߲VA| þþƷѴƬƬ| aƬѹۿ| Ļһ| Ʒһʽâ | ݺɫúݺݺۺ| ޾Ʒþþþ| btձһ| Ƶ߹ۿַ| ޾Ʒbv߹ۿ| ޹Ʒþþϼ1 | ߲| 456˳߲վ| ޾Ʒþþþ| ŮվɫƵ| ƷҳѸ߹ۿ| aëƬƵ| þùѸ| ˼˼99re66߾Ʒѹۿ| ߾ƷƵ| ҹþþþ| ޾ƷѹۿƵ| ձVAĻþõ| ̱߳ˬƵ99| ĻһƵ| 99þù-99þù 99þùĻ | ˾Ʒ2020| ŮƵվa| ȫ߹ۿѹۿȫ | þþþùɫAVѹۿ| 99þ99þþƷѹۿ| ĻƵ|