<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>firebody</title>
    <description>我很难过，因为我已经失去了很多东西！</description>
    <link>http://firebody.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>谈谈应用ORM框架针对遗留数据库做模型设计的一些技巧。</title>
        <author>firebody</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://firebody.javaeye.com">firebody</a>&nbsp;
          链接：<a href="http://firebody.javaeye.com/blog/152008" style="color:red;">http://firebody.javaeye.com/blog/152008</a>&nbsp;
          发表时间: 2007年12月30日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          很多项目的开发都是基于已有数据库做开发的。遗留数据库的存在增加了java模型和数据模型之间的障碍。<br />很多朋友为此是否选择hibernate或者别的Jdbc wrapper的开发框架而犹豫不决。 <br /><br />其实，用hibernate类似的orm工具总归是明智的选择，当然不是唯一的明智的选择，我写这篇文章只是希望能够给那些还在犹豫不决的人提供一些自信的力量，可以果断的作出自己的决定。<br /><br />有一个朋友询问过针对遗留系统做模型设计的问题 。很难简单回答这个问题，但是我可以提供我的一些经验，同时也把这篇帖子作为对那位朋友的一个完整的回答，希望能顾对他有所帮助。 <br /><br /><br /><strong>针对统一的业务逻辑，对 业务模型，DAO/Service 分别设计精巧的的继承体系</strong>。 <br />          很多朋友对此抱很谨慎的态度，因为他们觉得遗留系统很难有效支持业务模型的继承体系。 <br />          他们的担心是有理的，而且通常情况下，遗留系统确实无法支持现有ORM的类继承体系。然而，遗留系统不支持，并不能阻碍我们在业务模型畅通无阻的使用类继承，达到DRY的目标。抽取出的抽象模型可以更容易实现DRY，同时这里面的业务模型的层次设计很多时候也是真正反映了“业务统一处理”的需求。 <br />          这样的设计出现了很有意思的一个局面，业务模型是继承体系的模型，而数据模型是一对一映射的表模型，当用这种设计来处理业务的时候，特别是在处理“统一的抽象的业务逻辑”的时候，比支持继承模型的表模型 付出更多的一些努力才能达到，很多朋友一直担心这个“多付出”的努力是否会很可怕。 真的不用担心，并没有付出多少努力，你只需要在 DAO或者你的Service模块里面，做针对性的继承性的设计。通过这个合理的继承体系的DAO/Service模块，我们就可以在里面减少甚至完美弥补 因为 表模型不支持继承体系的业务模型带来的问题。 <br /><br />          一般来说，DAO/Service最好有这样的层次:<br /><br /><pre name="code" class="java">BaseService&lt;----UserService,OrderService

class BaseService { update,create,delete,findById..} </pre><br /><br />保证各个子类最终的CRUD都是通过 baseService.CRUD来完成 。 <br /><br />这样的DAO/Service类层次设计，为我们设计的业务模型的继承体系带来了“用武之地” ，在baseService的这个地方，大家可以把一些“需要统一处理的”业务逻辑放在此来做，比较有代表性的一点是 :<br /><br /><pre name="code" class="java">class abstract BaseService extends HibernateDAOSupport {

     public void create(Object o){
                 if(o instanceof PublishableModel){
                           publish((PublishableModel)o);
                  }
                 getHibernateTemplate().save(o);
    }

}</pre><br />似乎很别扭但却很有“意义”的一段代码，PublishableModel这个抽象类代表了业务模型中某个可以统一处理的业务抽象模型，而 这段代码:<br /><pre name="code" class="java">
   if(o instanceof PublishableModel){
                           publish((PublishableModel)o);
                  }
 </pre><br />给了这个业务模型抽象体系以真正发挥作用的“用武之地” 。<br /><br /><br /><strong>作为有经验的 开发人员，无论何时何地，都应该始终不渝的坚持并且贯彻“DRY”的宗旨。</strong>
          <br/>
          <span style="color:red;">
            <a href="http://firebody.javaeye.com/blog/152008#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 30 Dec 2007 23:07:19 +0800</pubDate>
        <link>http://firebody.javaeye.com/blog/152008</link>
        <guid>http://firebody.javaeye.com/blog/152008</guid>
      </item>
      <item>
        <title>一个简易的ruby AOP框架 。</title>
        <author>firebody</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://firebody.javaeye.com">firebody</a>&nbsp;
          链接：<a href="http://firebody.javaeye.com/blog/148274" style="color:red;">http://firebody.javaeye.com/blog/148274</a>&nbsp;
          发表时间: 2007年12月14日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          在开发smart memcache的过程中 ，开发了一个简易的 ruby aop 。<br /><br />支持 before,after,rescue 的拦截，支持重复，任意组合的拦截声明 。<br /><br />在后续的版本支持 arround interceptor声明。 <br /><br />基本的使用代码如下:<br />after 拦截使用:<br /><pre name="code" class="java">
@ruby_aop = AOP::RubyAop.new 
@ruby_aop.interceptor(:classes=>["User","Teacher"],:methods=>[:update_all],:interceptor_type=>:after) { |aop_info,*args| # your after block here }</pre><br /><br />说明:<br /><br />aop_info 为aop的元数据，类型为hash。 主要元数据:<br /><pre name="code" class="java">
 @aop_inf[:intercepted_class]  被拦截的类名(quanlified class name)
 @aop_inf[:intercepted_method]  被拦截的方法名（symbol)
 @aop_inf[:intercepted_method_is_class_method] 是否类方法) (true|false)</pre><br /><br />*args 为被拦截的方法调用的参数。<br /><br />before 拦截使用:<br /><pre name="code" class="java">@ruby_aop = AOP::RubyAop.new 
@ruby_aop.interceptor(:classes=>["User","Teacher"],:methods=>[:update_all],:interceptor_type=>:before) { |aop_info,*args| # your after block here }</pre><br /><br />:interceptor_type=>:before 由after改为 before <br /><br />rescue同样的 : :interceptor_type=>:rescue<br /><br />rescue的话，aopinfo里面可以通过 :error获取到异常信息。<br /><br />后续版本会做一个arround interceptor的支持 ，大概使用例子如下:<br /><pre name="code" class="java">arround_statement_str=&lt;&lt;END
   #hahahah before statement here
   AOP_ORIGINAL_METHOD_CALL
   ##bla bla after statement here 
   
END</pre><br /><br /><pre name="code" class="java">@ruby_aop = AOP::RubyAop.new 
@ruby_aop.interceptor(:classes=>["User","Teacher"],:methods=>[:update_all],:interceptor_type=>:arround,:arround_body=>arround_statement_str) 

</pre><br />其中arround_statement_str里面的原来方法的调用必须使用一个特殊的标志串 : <br />AOP_ORIGINAL_METHOD_CALL
          <br/>
          <span style="color:red;">
            <a href="http://firebody.javaeye.com/blog/148274#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 14 Dec 2007 11:13:08 +0800</pubDate>
        <link>http://firebody.javaeye.com/blog/148274</link>
        <guid>http://firebody.javaeye.com/blog/148274</guid>
      </item>
      <item>
        <title>关于实现一个rails smart cache 的思路草稿。</title>
        <author>firebody</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://firebody.javaeye.com">firebody</a>&nbsp;
          链接：<a href="http://firebody.javaeye.com/blog/147223" style="color:red;">http://firebody.javaeye.com/blog/147223</a>&nbsp;
          发表时间: 2007年12月10日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          最近研究了一下 rails的cache设计，发现其中一些不尽如人意的地方:<br /><br />* cache expiry 编写繁琐<br /><br />* 分页缓存的清除，现有cache实现的支持都不是很完善<br /><br />* 在一次清除大量缓存的时候，脏数据读的问题。<br /><br /><br />我查阅了一些blog以及相关的文章，从他们的抱怨和设计中得到一些启发，我觉得cache可以做得更好，更智能，更能够减少开发人员的工作量。 下面是我设计思路的一些草稿，如果深入分析，觉得可行的话，就可以动手做他:<br /><br />* 支持 cache 分组。 <br /><br />* 支持简化的expiry rules <br /><br />* 适当的设计减少一次清除大量缓存时脏数据读的概率和时间窗<br /><br />* 仅考虑memcache的支持。<br /><br />* 尽可能在现有框架的基础上做简单的扩展，减少开发量。<br /><br /><br /><br />	支持cache 分组可以同时带来很多好处，第一，支持分页缓存的一次expire。同时也有利于“减少脏数据读的时间窗”，cache分组的设计是整个设计的关键思路之一。下面来谈谈cache分组的设计:<br /><br />* 内存开辟一个hash。key是group ID。value是一个特有的Group对象，这个Group对象的设计目的是<strong>尽可能简便并且尽快地</strong> 清除同一组的所有cache key。<br /><br />* 要expire 同组所有脏缓存数据，有两种策略： 1） 按照cacheKey 逐一清楚 2) 不清除，而是加版本号<br />	第一种策略意味着需要保存Group和 CacheKey的一对多关系，这个保存可能需要通过数据库来保存，带来的复杂和性能开销似乎不是上选。<br />	第二种策略不用清除缓存，也不用查询数据库。但这种策略也需要做一些工作，在加入缓存的时候，我们需要修改原有的cacheKey，在后面加上Version=1这样版本标识。get cache的时候<br />		也需要做同样的工作。当expire脏Group的时候，只需要将Group对象上的version属性递增一。原有的脏数据通过memcache的自动清理策略来自动清除。<br /> 从这个分析来看，我觉得选择第二种策略更好。		<br /><br />整个smart_cache的设计实现应该在现有的cache实现的基础上，通过alias_method(rails的AOP）加入我们自己的中间逻辑。这样开发量最少。<br /><br />设计中的另外一个关键点是 expiry rules的设计，目前rails cache的expire的编写已经比较简单了，我们只需要更进一步，初步<br />设计如下，在config目录下增加一个 cache_expiry_rules.rb，示例代码如下:<br /><pre name="code" class="java">
SmartCache::Rules do  |config|
	
	config.add_rule(:group=>"user list",:expire_rules=>[cud_rule(User,Department,Room),rule(User.update*)])
	config.add_rule(:group=>"department list",:expire_rules=>[cud_rule(Department,Room),rule(Department.update*)])
	
end</pre><br />上面代码中的关键部分:<br /><strong>:expire_rules=>[cud_rule(User,Department,Room),rule(User.update*)])</strong><br />其中，cud表示某个model对象上的create,update,delete方法完成后。 <br />后面的rule(user.update*) 表示UserModel上的符合规则的某些方法被调用了之后。<br /><br /><br /><br />原有的缓存的方法 cache 需要最后增加一个属性 :group=>"your group",比如 cache fragment 的编写<br /><br /><pre name="code" class="java"> &lt;% cache :controller="user",:action=>"list",:page=>"params[:page]",:group=>"user list" do %>

	//rhtml code here to renderring view
 &lt;% end %>


 caches_action :list, :show,:group="test group"

</pre><br /><br />参考文章:<br /><br />* web agile devel....<br /><br />* <a href="http://www.railsenvy.com/2007/2/28/rails-caching-tutorial" target="_blank">http://www.railsenvy.com/2007/2/28/rails-caching-tutorial</a><br /><br />* <a href="http://blog.leetsoft.com/2007/5/22/the-secret-to-memcached" target="_blank">http://blog.leetsoft.com/2007/5/22/the-secret-to-memcached</a><br /><br />* <a href="http://blog.craigambrose.com/past/2007/11/13/caching_makes_your_brain_explode/" target="_blank">http://blog.craigambrose.com/past/2007/11/13/caching_makes_your_brain_explode/</a><br /><br />* <a href="http://cfis.savagexi.com/articles/2007/09/05/rails-unusual-architecture" target="_blank">http://cfis.savagexi.com/articles/2007/09/05/rails-unusual-architecture</a><br /><br />.............
          <br/>
          <span style="color:red;">
            <a href="http://firebody.javaeye.com/blog/147223#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 10 Dec 2007 12:33:53 +0800</pubDate>
        <link>http://firebody.javaeye.com/blog/147223</link>
        <guid>http://firebody.javaeye.com/blog/147223</guid>
      </item>
      <item>
        <title>PATCH for restore fixtures data after every test running</title>
        <author>firebody</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://firebody.javaeye.com">firebody</a>&nbsp;
          链接：<a href="http://firebody.javaeye.com/blog/146847" style="color:red;">http://firebody.javaeye.com/blog/146847</a>&nbsp;
          发表时间: 2007年12月08日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          rails的fixtures有一个令人讨厌的地方：<br /><br />fixtures 的数据不会在测试结束后自动清除 ，这样就使得fixtures遗留的数据影响到后来的测试。<br /><br />相关的争论也持续了很久 ，具体的连接请看  http://dev.rubyonrails.org/ticket/2404<br /><br />里面的 Rick的patch我在rspec下用了，不见好用，我只能自己搞了一个patch，在rspec的 spec_helper.rb下引入 <br />，解决了这个问题 。<br /><br />patch主要的思路是： 每次测试setup运行前插入fixture的数据，保证这个插入 fixtures数据的事务和test运行时的事务是同一个 ，teardown结束前，清空一些类变量, 原有的teardown运行的时候会作事务回滚的动作，这样就可以保证每次测试都回滚圆来插入的 fixtures的数据。 <br /><br />相关的配置 ：<br /><pre name="code" class="java">
  config.use_transactional_fixtures = true
  config.use_instantiated_fixtures  = false</pre><br /><br /><br /><pre name="code" class="java">
module Test #:nodoc:
  module Unit #:nodoc:
    class TestCase #:nodoc:
      alias_method : old_setup_with_fixtures, :setup_with_fixtures unless method_defined?(: old_setup_with_fixtures)
      alias_method : old_teardown_with_fixtures, :teardown_with_fixtures unless method_defined?(: old_teardown_with_fixtures)
      def setup_with_fixtures

        if use_transactional_fixtures?

          ActiveRecord::Base.send :increment_open_transactions
          ActiveRecord::Base.connection.begin_db_transaction
          close_original_activerecord_transaction_methods
        end
        old_setup_with_fixtures
        if use_transactional_fixtures?
          open_original_activerecord_transaction_methods
        end
        
      
      end
      
      def teardown_with_fixtures
        if use_transactional_fixtures?
          clear_fixtures_states_when_use_transactional_fixtures
        end
        old_teardown_with_fixtures       
      end      
      #prevent the next code:alias_method from trigger invoking the self.method_added introspected method
      class&lt;&lt;TestCase
        alias old_method_added method_added
        def method_added(m) 
          #do nothing
        end
      end

      alias_method :setup,:setup_with_fixtures
      alias_method :teardown,:teardown_with_fixtures
      #reopen the introspector class method:method_added
      class&lt;&lt;TestCase
        alias method_added old_method_added
      		
      end
      
      private
      def clear_fixtures_states_when_use_transactional_fixtures
        @@already_loaded_fixtures.clear if @@already_loaded_fixtures
        @loaded_fixtures.clear if  @loaded_fixtures

      end
      def close_original_activerecord_transaction_methods
        self.class.class_eval(%Q[
          	class&lt;&lt;ActiveRecord::Base
          		alias old_increment_open_transactions increment_open_transactions
          		def increment_open_transactions
          			#do nothing
      			end
      		end
          ])
        ActiveRecord::Base.connection.class.class_eval(%Q[
          	alias_method : old_begin_db_transaction,:begin_db_transaction
          	def begin_db_transaction
          		#do nothing
      		end
          ])
        
      end
      
      def open_original_activerecord_transaction_methods
        self.class.class_eval(%Q[
          	class&lt;&lt;ActiveRecord::Base
          		alias increment_open_transactions old_increment_open_transactions
          		
      		end
          ])
        ActiveRecord::Base.connection.class.class_eval(%Q[
          	alias_method :begin_db_transaction,: old_begin_db_transaction
          	
          ])
      end
    end
  end
end
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://firebody.javaeye.com/blog/146847#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 08 Dec 2007 11:17:57 +0800</pubDate>
        <link>http://firebody.javaeye.com/blog/146847</link>
        <guid>http://firebody.javaeye.com/blog/146847</guid>
      </item>
      <item>
        <title>记录一些学习 Portlet开放额地址 。</title>
        <author>firebody</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://firebody.javaeye.com">firebody</a>&nbsp;
          链接：<a href="http://firebody.javaeye.com/blog/142183" style="color:red;">http://firebody.javaeye.com/blog/142183</a>&nbsp;
          发表时间: 2007年11月20日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <a href="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/0401_hanis/hanis.html" target="_blank">http://www.ibm.com/developerworks/cn/websphere/library/techarticles/0401_hanis/hanis.html</a><br />
<br />
<br />
<a href="http://www.ibm.com/developerworks/cn/views/websphere/articles.jsp?view_by=search&amp;search_by=Portlet">IBM developerWorks 中国 : WebSphere : 文档库</a><br />
<br />
<a href="http://www.ibm.com/developerworks/cn/views/websphere/articles.jsp?view_by=search&amp;search_by=Portlet" target="_blank">http://www.ibm.com/developerworks/cn/views/websphere/articles.jsp?view_by=search&amp;search_by=Portlet</a>
          <br/>
          <span style="color:red;">
            <a href="http://firebody.javaeye.com/blog/142183#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 20 Nov 2007 23:38:44 +0800</pubDate>
        <link>http://firebody.javaeye.com/blog/142183</link>
        <guid>http://firebody.javaeye.com/blog/142183</guid>
      </item>
      <item>
        <title>谁了解Paulo提出的String B-Tree理论？出来讲解一下，我没有找到可以看懂的资料。</title>
        <author>firebody</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://firebody.javaeye.com">firebody</a>&nbsp;
          链接：<a href="http://firebody.javaeye.com/blog/118094" style="color:red;">http://firebody.javaeye.com/blog/118094</a>&nbsp;
          发表时间: 2007年08月29日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          下了一个会议纪要，内容太过粗略，不过大概看了一点设计理念，似乎是<br />B-Tree+Patricia Tree。<br />结合了两者优点。<br />更具体的分析，谁能够给出来？ <br />时空复杂度，IO效率等等。
          <br/>
          <span style="color:red;">
            <a href="http://firebody.javaeye.com/blog/118094#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 29 Aug 2007 23:14:47 +0800</pubDate>
        <link>http://firebody.javaeye.com/blog/118094</link>
        <guid>http://firebody.javaeye.com/blog/118094</guid>
      </item>
      <item>
        <title>对迷茫于Hibernate/JPA的人提一些建议。</title>
        <author>firebody</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://firebody.javaeye.com">firebody</a>&nbsp;
          链接：<a href="http://firebody.javaeye.com/blog/113101" style="color:red;">http://firebody.javaeye.com/blog/113101</a>&nbsp;
          发表时间: 2007年08月16日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          想对那些“迷惑”于Java ORM框架的J2EE开发人员提一些建议，希望能够对他们<br />更深入的理解和运用J2EE ORM框架来提速工作有所帮助，这些建议可能显得有些”陈旧“和”肤浅“，<br />因为最近半年我没有再过多的关注Java ORM，并且也没有继续关注J2EE领域新进展。<br /><br />在合理的使用Java ORM框架之前，必须要对他们有基本的了解，以下几点是最基本的也应该需要<br />深刻掌握的基础：<br /><br />* 关键API接口的深刻理解，并且大致清楚其内部逻辑机制。<br /><br /><br />* 深刻理解经典对象关系与数据库表schema之间的映射关系，特别是外键的关系。理解为何需要如此建立外键。<br /><br /><br />* Session对象状态管理机制的深刻理解，受管对象的状态迁移如何进行？ 受管对象的状态如何发生变化？ 这些状态对应于<br />	底层数据库何种操作(update,insert,delete)？<br /><br />* 级联操作的深刻理解<br /><br /><br />* Session 和 Transaction的关系,Session和Transaction的生命周期。<br /><br />* 一级缓存和二级缓存的深刻理解<br /><br />* 常见的ORM异常错误产生的原因和解决方式:<br />	>> a different object with the same identifier value was already associated with the session<br />	>> session already closed Exception<br /><br />* Lazy load对于性能优化的作用与机制。<br /><br /><br />* 在二级缓存中存在脏数据的操作陷阱。<br /><br />* 性能调优的基本技巧： 观察生成的SQL，优化HQL/EQL查询。几个基本建议: SQL查询优化技巧完全<br />	可以应用于HQL/EQL的查询，比如:合理索引的建立，注意复合索引的处理技巧，<br />		避免过长的join，注意Join的顺序，注意where条件的顺序。<br /><br />* 二级缓存的合理优化，如果二级缓存对于内存有限制，请合理设计二级缓存的使用。<br /><br />* 清楚ORM和传统JDBC操作的优缺点，在Ibatis、Spring JDBC Template、ORM等框架间作合理的选择。<br /><br />* 使用Spring框架的时候，深刻理解Spring的事务管理机制。如果是初学，请仔细阅读文档，并反复实践。
          <br/>
          <span style="color:red;">
            <a href="http://firebody.javaeye.com/blog/113101#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 16 Aug 2007 18:57:42 +0800</pubDate>
        <link>http://firebody.javaeye.com/blog/113101</link>
        <guid>http://firebody.javaeye.com/blog/113101</guid>
      </item>
      <item>
        <title>想赶在年前发布Redsoft JPA.但是sf鬼速，有何办法捏??</title>
        <author>firebody</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://firebody.javaeye.com">firebody</a>&nbsp;
          链接：<a href="http://firebody.javaeye.com/blog/51630" style="color:red;">http://firebody.javaeye.com/blog/51630</a>&nbsp;
          发表时间: 2007年02月01日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          先是断网，中断了我们发布开源免费的JPA产品的计划，好不容易修复了，可是网速依然龟速。<br /><br />有好的代理吗？
          <br/>
          <span style="color:red;">
            <a href="http://firebody.javaeye.com/blog/51630#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 01 Feb 2007 16:02:20 +0800</pubDate>
        <link>http://firebody.javaeye.com/blog/51630</link>
        <guid>http://firebody.javaeye.com/blog/51630</guid>
      </item>
  </channel>
</rss>