`
wyuch
  • 浏览: 74551 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

反思Hibernate,可以有更简洁、更高效的ORM实现

 
阅读更多
  我思考了良久才决定发这篇文章,各位老大手下留情。

  假设有一张表Student,有几个字段ID,Name,Gender,BirthDay,实际上这么一个从数据库设计中直接生成的类就可以很好地满足我们对于ORM的要求:

public class StudentSchema extends Schema {
	private int ID;

	private String Name;

	private String Gender;

	private Date BirthDay;

	public static final TableName = "Student";

	public static final PrimaryKeys PKs = new PrimaryKeys(new String[] { "ID" });

	public Date getBirthDay() {
		return BirthDay;
	}

	public void setBirthDay(Date birthDay) {
		BirthDay = birthDay;
	}

	public String getGender() {
		return Gender;
	}

	public void setGender(String gender) {
		Gender = gender;
	}

	public int getID() {
		return ID;
	}

	public void setID(int id) {
		ID = id;
	}

	public String getName() {
		return Name;
	}

	public void setName(String name) {
		Name = name;
	}
}


  其中Schema是一个公用类,里面主要是提供了fill(),update(),delete(),backup()等功能。其中fill()就是通过主键返回一条记录,其他几个方法就不用说了吧。

  但反观Hibernate呢?我们需要一个与StudentSchema类似的POJO类,一个DAO类,一个*.hbm.xml映射文件,才能达到类似的效果,机制繁琐,性能消耗明显要高。

  我不知道为什么这么简单的高下立见的对比没有引起大家的注意,我也承认我对Hibernate浅尝辄止,并且我估计会引来大片的攻击,但我确实想像不出Hibernate有可能会比这更简洁更高效。在我们的实际应用中,StudentSchema是由工具从PowerDesigner中直接生成的,开发人员根本不管ORM,直接使用即可。StudentSchema是硬编码的类,不需要进行字节码动态生成,不需反射,不需配置文件,十分简单。

  更重要的是,我们这个ORM实现总共才几千行代码。Hibernate功能很多,但我们的ORM实现虽然代码很少,但己能覆盖实际开发中的全部ORM需求。我将以回复的方式加以说明。
分享到:
评论
31 楼 zozoh 2009-06-07  
注:这不是拍砖。 我对这方面很感兴趣:

我的问题:
1. 关联怎么处理,级联怎么处理?
2. 还有 用 static 的 TableName 显得不够优雅,但却可以让使用者的 POJO 不被侵入,这是个有点。然而楼主又要求用户继承自己的一个类,这是非常具有侵入性的设计。所以这个设计很矛盾。你到底要不要侵入使用者的 POJO呢?
3. 复杂的查询,分页,等怎么处理,似乎还不够好
4. 事务方面,如果我想在一个事务里执行一段我自定义的 SQL 怎么办? 是否要来个 Transaction.ExecuteSQL
之类的类型?

我的经验分享:
我在 01年的时候写了一套类似楼主的这种方法, 也要求实体类继承我的鸡肋。后来,发现的确有点不那么优雅,因为我剥夺了用户的一种选择(他们原本可以继承自别的什么类) 我的侵入性几乎不亚于 EJB 了。在复杂的项目开发中,我逐渐的发现了这种做法的局限性。但是,在80%-90%的时候,这种做法似乎的确问题不大。

我的解决方案:
我去年年底到现在一直在作这个项目 http://nutz.googlecode.com ,也是一个 SSH 的替代方案,它是完全开源的,并且在不断完善中,现在已经是版本 aplpha 12 了,这里是在 JE 上的专栏,还有几篇文章
http://www.iteye.com/wiki/nutz
不知道是否对楼主的这个想法有所帮助。
30 楼 zypro 2009-06-06  
标题是"反思Hibernate"

这个标题的意思应该是,已经对Hibernate非常熟悉,有多年的应用经验,然后回过头来说说Hibernate的不足之处.

但是显然,LZ对Hibernate几乎不懂.

Hibernate之所以复杂,是因为有了强大的关系支持,1对1,乃至多对多,都有了最合理的支持,而且为了保证效率,引入了一系列的辅助措施,Lazy,Cache等等. 所以配置选项非常多,感觉上要做一件简单的事情,也要配置一下. 但这个不是缺陷,这个是能力,是能够对应复杂情况的能力,就象用Java写一个HelloWorld,也要写一个class,还要有main,最终还要编译... 我完全相信可以开发一种语言,专为输出HelloWorld,只需写一个字就可以执行... 你能说比java更好吗?

LZ的方案,简单讲,只是省略了一些sql.用了自动化的代码生成工具,可以省去重复的代码编写. 这个思路,从OO诞生之日起,就已经在很多公司运用了. 当然,这是一个简洁有效的方案. 只不过如果要去和Hibernate比高低,那是自不量力了...

跟LZ的框架类似的,我见过的做的最好的,是.net平台下的SPL,国人的产品.只不过三年前就不更新了. 如果有兴趣,可以去参考一下.
29 楼 mikeandmore 2009-06-06  
wyuch 写道

1、Schema是可以加入事务的,其实你说的第4点说明你已经看到了。
2、可能你没有太明白这个东西,fill()只是根据主键取数据,一个schema可以fill多次,每次都是取数据,比如说可以设置setID(1)后fill一次,然后取其他字段的值参加运算,再setID(2)后fill一次,取第二条记录的字段值参加运算。如果主键对应的记录不存在,fill会报异常。总之一切围绕主键。
3、有外挂式的Cache,能够与Memcache集成。我觉得一方面数据库本身已经有很好的缓存策略了,另一方面内存中数据的缓存有一个与ORM无关的实现可能会比较好。
4、我倒是不觉得有什么不OO的。在一个事务的一系列操作中,由事务负责哪个数据执行什么操作是很自然的事情。特别是这样子应该是代码行数最少的写事务的方式之一。OO不OO其实我并不那么关心,我只关心我要写几行代码。


其实就像上边回帖说的那样,这不是我的独创,思想本身来源于一个规模比较大的公司,国内有不少公司在用类似的方案。而且本身这个ORM框架已经经过了很多项目检验了的,效果是很好的。

1 提供事物支持和transactional不可同日而语
2 哦,那我就是还看不懂你那个fill是什么意思
3 是说orm自己的cache。。。这个cache和memcache不是一个层次的。。。当然,你也可以选择,没有cache。。。就我个人而言,我的确觉得orm里面的cache把问题弄的过于复杂了。
4 哦,那我倒是觉得干脆jdbc代码最少了。。。
28 楼 rrsy23 2009-06-06  
hibernate最伟大之处 不是技术;

是-------推广成功,是统一;

技术的本质是什么?

看看李小龙电视吧!

webwork 好还是 struts好

我04年用webwork后来跳槽一些面试者说你不熟悉struts什么的,就无语了


struts1+filter+interface+thking====???


呵呵 技术不是唯一;
27 楼 linginfanta 2009-06-06  
用Hibernate很久了,觉得需要改进。
强烈关注你的作品。
26 楼 BearRui 2009-06-06  
但反观Hibernate呢?我们需要一个与StudentSchema类似的POJO类,一个DAO类,一个*.hbm.xml映射文件,才能达到类似的效果,机制繁琐,性能消耗明显要高。
------------------------------
POJO类是肯定需要的,楼主的也一样需要,是否需要DAO类完全是自定义的,如果你喜欢1个POJO对应1个DAO(甚至再加上1个DAO的接口),都可以。如果你喜欢只用1个DAOHelper类也可以,只需要对hibernate做很简单的封装就可以了。hbm.xml也可以不用,使用JPA注解就OK。

其实怎么使用都看个人喜欢和水平。
25 楼 Jwind 2009-06-06  
liujunsong 写道
学那个Hibernate就快把人搞死了,
现在用这个又要学新东西.
现在的技术啊,老是与时惧进,东西越来越多.

用这个东西也许能提高些效率,可是以后维护怎么办?
来的人还得从头开始学习,理解,消化...
不看好.


把目的搞清楚,学了是为了用,用是为了提高效率。
如果‘学那个Hibernate就快把人搞死了’的话,何必去学它?
24 楼 kjj 2009-06-06  
即然挑战hibernate 那就作为一个开源项目发布一下,拼拼,看谁到底更厉害,不过我觉得渺茫,hibernate 已经参加ejb3的团队了,最好弄个完整的东东,然后相对于hibernate的相同的操作,来个测试对比什么的!!
23 楼 dch1287 2009-06-06  
楼主描述的这个框架的行为确实可以用Hibernate完美模拟 因为全部是Hibernate的子集而已

说Hibernate复杂 不过是Hibernate帮你考虑了更多的事情 但是通常情况下你更本不用关心 因为Hibernate是透明地帮你做了这些事情 比如 底层数据库的任意替换 数据库自动建表 缓存(Hibernate也是用的第三方缓存工具, 而且是完全可替换的) 复杂关系映射关联 面向对象的查询语言HQL 编程化的查询QBC 按照例子查询QBE EJB3,JPA支持.. 太多太多
Hibernate的完善程度恐怕已经没有框架(TopLink也许和它接近 毕竟Hibernate从他身上学了很多 但是早就青出于蓝了)能和它相比了 所以gorm并没有自己搞一套 而是直接在Hibernate之上 让Hibernate更方便使用

phoenix.clt 写道
已经有很多种实现了。 grails 中的 gorm 就是这种 形式的, 虽然 它在底层是借助的 hibernate, 但是在 api 的形式上 都是直接的 domain.get(id)   domain.find(expression)  domain.findAll(expression) 等。
不过它 的 实现不是用的继承, 而是用动态修改 class ,为 domain 添加 动态行为实现的。 此外还可以用 findByNameAddress("abc","中国") 的形式。 连拼SQL都省了,可以直接拿 字段名做查询方法。

最近正在关注 Groovy, Grails。 对Java程序员来说他们确实是很有意思的东西
22 楼 lucky16 2009-06-06  
我来学习学习!
21 楼 flyfan 2009-06-06  
Schema中的代码没贴出来?到底是怎么样跟数据库表产生orm关系的呢
20 楼 phoenix.clt 2009-06-06  
已经有很多种实现了。 grails 中的 gorm 就是这种 形式的, 虽然 它在底层是借助的 hibernate, 但是在 api 的形式上 都是直接的 domain.get(id)   domain.find(expression)  domain.findAll(expression) 等。
不过它 的 实现不是用的继承, 而是用动态修改 class ,为 domain 添加 动态行为实现的。 此外还可以用 findByNameAddress("abc","中国") 的形式。 连拼SQL都省了,可以直接拿 字段名做查询方法。
19 楼 holan 2009-06-06  
楼主解决方案其实真的没有hibernate来的简单
用上hiberante注解配置
我也就只需要一个POJO,其他什么也不要。你这里唯一的好处是类对象可以有fill update delete的操作
你的实体类如何获得这种操作??是因为它继承了schema!!!我需要的话也可以写一个针对hibernate的schema基类,获取sesseion实现你所谓的fill update delete操作。

你的QueryBuilder也就仅仅是一个弱化版的session,还没有session的可重复读,对象一致性范围等等的功能。说穿了你的QueryBuilder就是一个sql执行器。



18 楼 madbluesky 2009-06-06  
  缓存策略呢
17 楼 jenlp520 2009-06-06  
holan 写道
jenlp520 写道
引用
但反观Hibernate呢?我们需要一个与StudentSchema类似的POJO类,一个DAO类,一个*.hbm.xml映射文件,才能达到类似的效果,机制繁琐,性能消耗明显要高。


POJO类,一个DAO类,一个*.hbm.xml映射文件 除了*.hbm.xml以外 另外2个跟hibernate无关
pojo 和dao是我们设计分层的时候加入的 所以说来hibernate跟你的orm比起来就多个*.hbm.xml
这个配置文件大家知道数据映射用的 LZ你的orm没有这个类似的文件 那你bean的字段名和数据库列名是根据自己定义的某种规范来起的吧 或者直接就是你例子里的 取一样的名字, 你能把数据库一个叫id的字段映射成bean中的name字段吗?

这个倒不是问题,hibernate现在也支持注解配置,他写的这个东西实际上也可以引入注解解决你说的映射问题。


就LZ的话来说 如果他引入注解配置 那么就跟hibernate无异了
16 楼 holan 2009-06-06  
jenlp520 写道
引用
但反观Hibernate呢?我们需要一个与StudentSchema类似的POJO类,一个DAO类,一个*.hbm.xml映射文件,才能达到类似的效果,机制繁琐,性能消耗明显要高。


POJO类,一个DAO类,一个*.hbm.xml映射文件 除了*.hbm.xml以外 另外2个跟hibernate无关
pojo 和dao是我们设计分层的时候加入的 所以说来hibernate跟你的orm比起来就多个*.hbm.xml
这个配置文件大家知道数据映射用的 LZ你的orm没有这个类似的文件 那你bean的字段名和数据库列名是根据自己定义的某种规范来起的吧 或者直接就是你例子里的 取一样的名字, 你能把数据库一个叫id的字段映射成bean中的name字段吗?

这个倒不是问题,hibernate现在也支持注解配置,他写的这个东西实际上也可以引入注解解决你说的映射问题。
15 楼 bcw104 2009-06-06  
希望楼主介绍一下如下两个问题:
1.关联的问题,一对多,多对多是怎么实现的,
2.还有对象/关系范式不匹配的问题是怎么解决
比如说两个表user,address对应一个User对象
user表
id  name addressid

address表
id  province country

User对象: id name address
14 楼 wyuch 2009-06-06  
mikeandmore 写道
感觉
1 那个schema应该是非transactional的设计。。。不是个好设计
2 对bean的作用域封装的不太清晰。比如你fill了一个东西以后在去fill,应该是update了。。。或者这个bean有争抢,delete以后再fill会发生一些很神奇的事情。。
3 没有把cache考虑进去。这个的确是很困难的。
4 transaction的封装不是OO的风格。。。insert或者是delete怎么能使transaction的责任呢。。。。明明是bean自己的事情。。。

反正。。。lz思考的还比较浅。。。不过我估计深入了,也就复杂了。。。SQL本身就是FP的东西,OO化不是很简单的。。。


1、Schema是可以加入事务的,其实你说的第4点说明你已经看到了。
2、可能你没有太明白这个东西,fill()只是根据主键取数据,一个schema可以fill多次,每次都是取数据,比如说可以设置setID(1)后fill一次,然后取其他字段的值参加运算,再setID(2)后fill一次,取第二条记录的字段值参加运算。如果主键对应的记录不存在,fill会报异常。总之一切围绕主键。
3、有外挂式的Cache,能够与Memcache集成。我觉得一方面数据库本身已经有很好的缓存策略了,另一方面内存中数据的缓存有一个与ORM无关的实现可能会比较好。
4、我倒是不觉得有什么不OO的。在一个事务的一系列操作中,由事务负责哪个数据执行什么操作是很自然的事情。特别是这样子应该是代码行数最少的写事务的方式之一。OO不OO其实我并不那么关心,我只关心我要写几行代码。


其实就像上边回帖说的那样,这不是我的独创,思想本身来源于一个规模比较大的公司,国内有不少公司在用类似的方案。而且本身这个ORM框架已经经过了很多项目检验了的,效果是很好的。
13 楼 jenlp520 2009-06-06  
引用
但反观Hibernate呢?我们需要一个与StudentSchema类似的POJO类,一个DAO类,一个*.hbm.xml映射文件,才能达到类似的效果,机制繁琐,性能消耗明显要高。


POJO类,一个DAO类,一个*.hbm.xml映射文件 除了*.hbm.xml以外 另外2个跟hibernate无关
pojo 和dao是我们设计分层的时候加入的 所以说来hibernate跟你的orm比起来就多个*.hbm.xml
这个配置文件大家知道数据映射用的 LZ你的orm没有这个类似的文件 那你bean的字段名和数据库列名是根据自己定义的某种规范来起的吧 或者直接就是你例子里的 取一样的名字, 你能把数据库一个叫id的字段映射成bean中的name字段吗?
12 楼 mikeandmore 2009-06-06  
感觉
1 那个schema应该是非transactional的设计。。。不是个好设计
2 对bean的作用域封装的不太清晰。比如你fill了一个东西以后在去fill,应该是update了。。。或者这个bean有争抢,delete以后再fill会发生一些很神奇的事情。。
3 没有把cache考虑进去。这个的确是很困难的。
4 transaction的封装不是OO的风格。。。insert或者是delete怎么能使transaction的责任呢。。。。明明是bean自己的事情。。。

反正。。。lz思考的还比较浅。。。不过我估计深入了,也就复杂了。。。SQL本身就是FP的东西,OO化不是很简单的。。。

相关推荐

    Hibernate框架ORM的实现原理

    ### Hibernate框架ORM的实现原理详解 #### 一、ORM概念及意义 **ORM**,即**对象关系映射**(Object Relational Mapping),是一种程序...了解Hibernate的实现原理有助于更好地运用这一框架,解决实际开发中的问题。

    Hibernate orm 实现原理

    Hibernate orm 实现原理 主要讲解了关于hibernate 的一些知识

    hibernate-orm-master.zip

    在实际开发中,理解并熟练运用这些核心概念和机制,可以帮助我们更高效地利用Hibernate ORM进行数据访问层的设计,减少数据库操作的复杂性,提高代码的可维护性。对于初学者,建议从简单的JAR包开始,逐步熟悉其API...

    HibernateORM

    Hibernate作为Java领域广泛使用的ORM框架,它极大地简化了数据库操作,将面向对象的编程思想与关系型数据库相结合,使得开发者可以更加专注于业务逻辑,而不是繁琐的SQL语句。在本书中,作者深入浅出地讲解了如何...

    hibernate-orm-3.3源码

    总结,通过分析《hibernate-orm-3.3源码》,我们可以深入理解 Hibernate 的工作机制,掌握如何高效地使用 ORM 技术,以及如何根据需求扩展和定制 Hibernate。对于任何想提升数据库操作效率和代码可维护性的 Java ...

    ORM hibernate。jar包

    标题提到的"ORM Hibernate .jar包"指的是Hibernate框架的可执行库文件,通常包含了一系列类、接口和实现,供开发者在项目中引用,以实现ORM功能。"hibernate5+jars包"表明这是Hibernate的第五个主要版本,5.2.16....

    hibernate-orm-4.3.9源码

    本文将基于从Hibernate官网下载的hibernate-orm-4.3.9源码,深入解析其内部机制,帮助开发者更好地理解和应用Hibernate。 一、Hibernate概述 Hibernate的核心功能是将Java对象与数据库表进行映射,实现了数据持久...

    Hibernate_ORM步骤详解

    Hibernate ORM 是一种强大的Java持久层框架,它实现了对象关系映射(ORM)的概念,使得开发者可以使用面向对象的方式来操作数据库,而无需关心底层SQL语句的编写。在本教程中,我们将详细介绍如何利用Hibernate 3...

    hibernate-orm-3.2.zip

    Hibernate ORM 是一个强大的Java对象关系映射(ORM)框架,它极大地简化了数据库与Java应用程序之间的数据交互...虽然现在Hibernate已经发展到了更高级的版本,但理解3.2的基础知识仍然有助于理解ORM的本质和工作原理。

    hibernate-orm-master

    hibernate-orm-master

    hibernate-search-orm-4.4.2.Final.zip

    总结来说,Hibernate Search ORM 4.4.2.Final是Java开发中实现全文检索的强大工具,而AtomicMapOperations则提供了并发映射的非阻塞原子操作,两者结合可以构建出高性能、高并发的搜索应用。对于任何处理大量数据和...

    hibernate-framework-orm-4.2.4.Final.zip

    Hibernate作为ORM工具,主要解决了Java应用与数据库之间的数据交互问题,通过将数据库表映射为Java类,实现对象与数据的自动转换。这使得开发者可以使用面向对象的方式来操作数据库,降低了数据库操作的复杂性。 2...

    自定义Orm框架的实现

    本项目旨在实现一个基于JDK5.0注解的小型ORM框架,模拟Hibernate的部分功能。 首先,我们要理解ORM的基本原理。ORM的核心思想是将数据库中的表映射为Java对象,将表中的记录映射为对象的实例,这样就可以通过操作...

    org.springframework.orm.hibernate3.LocalSessionFactoryBean

    ### 关于 "org.springframework.orm.hibernate3.LocalSessionFactoryBean" 未找到问题的知识点解析 #### 一、问题背景 在开发基于Spring与Hibernate整合的应用时,可能会遇到“`org.springframework.orm.hibernate...

    Hibernate源码(hibernate-orm-main.zip)

    Hibernate源码(hibernate-orm-main.zip)Source Code: Hibernate ORM 是一个为应用程序、库和框架提供对象/关系映射 (ORM) 支持的库。 它还提供了 JPA 规范的实现,这是 ORM 的标准 Java 规范。

    Hibernate ORM - 一对多双向关联关系

    在Hibernate中,这种关系可以通过`@OneToMany`注解实现。例如,User类可能会有如下注解: ```java @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; ...

    ORM的简单介绍及相应ORM工具Hibernate的使用规则

    对象关系映射的概念,及相应Hibernate的使用规范,同时通过实例展示到底什么是对象关系映射。

    Hibernate入门到精通

    Hibernate 是一个基于Java的ORM(Object-Relational Mapping,对象关系映射)框架,它提供了一种简洁高效的方式来访问和操作关系数据库。下面是 Hibernate 的主要知识点: Hibernate 简介 Hibernate 是一个开源的...

Global site tag (gtag.js) - Google Analytics