Hibernate可以从Rails的ActiveRecord学到什么?

[size=medium]1. 约定大于配置[/size]
Rails的理念就是约定大于配置,这在ActiveRecord模块里面体现的淋漓尽致,没有hibernate繁琐的mapping xml或者annotation,它是直接根据数据库中表的字段信息配合少量关系定义去实现ORM。
以一个简单的论坛主题贴为例子:

class Topic < ActiveRecord::Base
belongs_to :user
belongs_to :forum
has_many :posts
end

class Post < ActiveRecord::Base
belongs_to :topic
belongs_to :user
end

只用定义对象之间的关系,其他属性,比如topic的id, title, created_at都是根据数据库中表的字段来自动生成。
而在Hibernate里面,就需要在pojo里面定义多个属性,以及getter/setter,然后用mapping xml或者annotation定义这些属性和数据库表/字段的映射以及各个对象之间的关系(one-to-many, many-to-one, etc)。

[color=red]Hibernate实现该特性难度:***[/color]
因为Hibernate和ActiveRecord设计出发点正好相反。前者是对象驱动数据库:定义mapping文件,然后自动生成数据库脚本。而后者是数据库驱动对象:设计好数据库,动态生成对象属性。


[size=medium]2. 数据库迁移工具[/size]
ActiveRecord的数据库migration脚本非常好用,能够让我们在开发/部署时候做方便的数据库结构变更。
而Hibernate本身并没有提供这项功能,我之前用hibernate开发的时候,经常为了这个问题而需要写一些迁移SQL,如果做产品,还要考虑到不同的数据库要提供不同的迁移脚本。

[color=red]Hibernate实现该特性难度:*[/color]
Hibernate应该提供内置的migration tool,让它作为一项最佳实践来推广。


[size=medium]3. 动态代码生成[/size]
由于Ruby动态语言的特性,ActiveRecord能够把原先在Hibernate里面麻烦的代码,变得很简洁。

还是以前面的论坛主题贴为模型,我们需要对一个主题贴进行回复,在rails里面我们可以这样写:

topic = Topic.find(10000)
topic.posts.create(:user => current_user, :body => "回复内容")

ActiveRecord利用动态代码生成,在Topic上的has_many posts集合,自动添加了一个create方法,负责处理往这个集合添加新对象以及维护关系。
而相应的Hibernate代码,大概是这样:
[code]
Topic topic = session.find(Topic.class, 10000);
Post post = new Post();
post.setUser(currentUser);
post.setBody("回复内容");
post.setTopic(topic);
topic.getPosts().add(post);
session.update(topic);
[/code]

再一个例子,为了性能考虑,我们往往会在Topic表上添加一个posts_count的冗余字段,在Rails里面只用添加一个counter_cache

class Post < ActiveRecord::Base
belongs_to :topic, :counter_cache => true
end

其他代码都不用动,ActiveRecord就可以利用动态代码生成,帮你在有新回帖的时候给这个栏位自动+1了。
而在Hibernate里面,我们就要手写几行代码来做这种事情了。

这类型的特性在Rails里面很多,这里就不一一列举了。

[color=red]Hibernate实现该特性难度:**[/color]
可以利用Hibernate的inteceptor或者event机制,配合mark性质的interface,来实现部分功能。


[size=medium]4. named_scope (Has Finder) 功能[/size]
这是Rails2.1的新特性,之前是用Has Finder插件实现的。
我们以JavaEye的新闻模型为例子,它有一个status栏位,代表是否被批准,还有一个category栏位,代表是属于什么分类:

class News < ActiveRecord::Base
named_scope :approved, :conditions => {:status => 'approved'}
named_scope :categoried, lambda { |category| { :conditions => ['category = ?', category] } }
named_score :recent, lambda { |time| { :conditions => ['created_at > ?'], time } }
end

我们在controller里面就可以这样组合使用:

#被批准的新闻
News.approved
#被批准的Java新闻
News.approved.categoried("java")
#最近2周被批准的Ruby新闻
News.approved.categoried("java").recent(2.weeks.ago)


这个代码看起来非常舒服,犹如阅读英文一般自然。

[color=red]Hibernate实现该特性难度:***[/color]
这其实也是动态语言特性所带来的,基于Java的Hibernate几乎是无法实现这个特性。

[size=medium]5. 高性能的集合操作[/size]
还是以前面的论坛主题贴为模型,显示一个主题贴的回帖数目,在rails里面我们这样写:

topic.posts.size

它只会生成select count(*)的语句,而不需要把整个posts集合初始化。

再比如对回帖做分页显示:

topic.posts.paginate(:page => 1, :per_page => 10)

它也只会生成相应的分页语句。

在Hibernate3,lazy collection proxy可以做到类似的操作,但是代码就复杂多了:
[code]
( (Integer) session.createFilter( posts, "select count(*)" ).list().get(0) ).intValue()
session.createFilter( posts, "").setFirstResult(0).setMaxResults(10).list();
[/code]
而且其他的更多集合操作特性也无法实现


-------广告分割线-------
还有许许多多其他优秀特性等待你去挖掘,Rails中除了ActiveRecord以外,也还有其他优秀的地方,试用一下Rails,会发现用它来写web应用是一件很享受的事情。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值