论坛首页 Java企业应用论坛

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

浏览 34470 次
该帖已经被评为隐藏帖
作者 正文
   发表时间:2009-06-07  
metadmin 写道
我几年前就抛弃了hibernate。

抛弃原因不是因为它不强大,而是它不满足我的需求。我的很多东西都是动态的。。。另外,我不喜欢复杂的东西。。。


我也想抛弃之,老兄现在做持久化怎么做?
0 请登录后投票
   发表时间:2009-06-07  
我看清楚了,楼主实际上并不是为了反思什么hibernate,而是为了展示自己的框架罢了, 从自己承认对hibernate 不甚了解就可以看出来端倪,这样的话,我几乎看不出来所列代码比hibernate好在哪里,你说hibernate 复杂,主要就是你没解决的hibernate 比如,关联,缓存,什么的高级特性罢了,这个所谓的 框架 貌似就是hibernate的阉割版而已,没看出推陈出新的地方!!!!!!!!!!!!!!!
最后鄙视一下,为了表现自己随意贬低别人的做法,还对人家不了解,这不是几个踏实的技术人员的态度吧!!
0 请登录后投票
   发表时间:2009-06-07  

嘿嘿,这个帖子挺热。似乎javaeye上的这种帖子都很热。。。。。都要成框架生产基地了。每天都有伟大的东西诞生,不知道是喜还是忧。

看了一下楼主的想法,无非是根据tableName和类的属性生成SQL语句。这种做的原因无非是觉得hibernate是如何如何的差。其实事情没有那么糟糕,

 

如果说Hibernate差,那么楼主的东西比Hibernate更差。

 

楼主的东西也是一种根据Class推导出SQL语句的。而hibernate也是这样的。所以设计思想上是相通的。而楼主的做法不如hibernate的原因是因为,hibernate底层有不通的数据库SQL生成引擎(这个命名。。。呵呵),而且有二级缓存,关联查询,HQL查询语句等等功能。而比起楼主的做法要丰富的多。所以如果说Hibernate差那么楼主的做法比Hibernate更差。

 

楼主觉得Hibernate差的原因无非是因为“我们需要一个与StudentSchema类似的POJO类,一个DAO类,一个*.hbm.xml映射文件,才能达到类似的效果,机制繁琐,性能消耗明显要高。 ”事实果真如此吗?不尽然,不妨分析一下:

 

首先是需要一个POJO得javabean,里面到底要不要包含序列化得业务逻辑?如果包含,那么就是富领域对象了,如果不包含就是贫血对象了。而对于java开发人员来讲贫血的是更普遍的。数据承载对象由javabean的model负责,而业务逻辑有service负责。所以POJO类是一定需要的。至于DAO,完全可以省略了,我们只需要一个Service层就可以了。这里不妨引用一下我随手找大一些代码段

 

	public Page<SiteUser> findUserByPage(int pageno) {
		String hql = "FROM SiteUser siteUser";
		return siteUserDao.pagedQuery(hql, pageno, Constants.PAGE_SIZE);
	}

	public void saveUser(String userName) {
		SiteUser entity = new SiteUser();
		entity.setName(userName);
		entity.setSiteId(UUIDGenerator.generateUUID());
		entity.setPwd(MD5.crypt(entity.calPwdCode()));
		siteUserDao.save(entity);
	}

	public void updateUser(String userId, String userName) {
		SiteUser entity = siteUserDao.get(userId);
		entity.setName(userName);
		entity.setSiteId(UUIDGenerator.generateUUID());
		entity.setPwd(MD5.crypt(entity.calPwdCode()));
		siteUserDao.save(entity);
	}

	public SiteUser auth(String userName, String siteId) {
		String hql = "FROM SiteUser siteUser WHERE siteUser.name=? AND siteUser.siteId=?";
		return siteUserDao.findOne(hql, userName, siteId);
	}

 

这里的DAO其实是

private HibernateDao<SiteUser> siteUserDao;

 也就是所DAO层名存实亡了。

 

那么还有一个配置文件的问题,这个基本上不是问题,使用JPA的注解。最佳实践是尽量的少写JPA的注解,尽量默认。看我的注解对象

 

@Entity
public class SiteUser extends JPAModel {
	@Id
	private String id = UUIDGenerator.generateUUID();
	@Column
	private String name;
	@Column
	private String siteId;
	@Column
	private String pwd;
	@Column
	private Date addDate = new Date();

 只需要在spring里的sessionFactory定义一下

 

<property name="namingStrategy">
	<bean class="org.hibernate.cfg.ImprovedNamingStrategy" />
</property>

 就会完成名称的“约定大于配置”

 

如此,这些事情也不再繁琐了。得到的好处也是显而易见的了:我们能使用hibernate的save,update,deleteById等基本操作,书写HQL语句要比书写SQL语句更短一点更容易理解一点。现在Hibernate才是被我们玩而不是我们被它玩了。

1 请登录后投票
   发表时间:2009-06-07  
看来看去,觉得楼主这个东西根本不是ORM,其目标也不是去解决ORM的问题,整个就是一个dbutils,如果比较可以去和apache里面的dbutils比较一下还差不多。

不是说把数据表里面的一个个字段,都自动化或者半自动化的转换为类里面的一个个简单属性就可以叫做ORM了。

地球人都知道ORM是用来解决对象模型和关系模型的不匹配的,于是级联、对相关联、面向对象的查询方式才是ORM的主要课题。楼主这个东西是什么?
0 请登录后投票
   发表时间:2009-06-07  
楼主的ORM貌似很像.NET的subsonic
http://subsonicproject.com/active-record/
楼主可以参考下,貌似在博客园好像也见到过楼主写过一篇文章
0 请登录后投票
   发表时间:2009-06-07  
linginfanta 写道
metadmin 写道
我几年前就抛弃了hibernate。

抛弃原因不是因为它不强大,而是它不满足我的需求。我的很多东西都是动态的。。。另外,我不喜欢复杂的东西。。。


我也想抛弃之,老兄现在做持久化怎么做?

我是开发产品的,很多不确定动态的东东。
当时我们整个团队认为:只要知道数据库表格信息,和实体类,那么相关代码基本上不需要写了。所以就动手写了相关CURD操作引擎,没有使用任何开源产品。至于这种CURD操作,并不需要很多创新的。

基本方式是这样的:
1, 面向对象的方式,描述数据库信息和实体类信息;
2, 编写通用引擎,该引擎得到上面的参数,执行CURD方法;
3, 缓存是外挂的(这点和楼主一样)。

这是我们的快速定制查询演示:http://www.metadmin.com/download/showEmployees.html
0 请登录后投票
   发表时间:2009-06-07   最后修改:2009-06-07
fireflyc 写道

现在Hibernate才是被我们玩而不是我们被它玩了。

很有味道!

0 请登录后投票
   发表时间:2009-06-07  
kjj 写道
我看清楚了,楼主实际上并不是为了反思什么hibernate,而是为了展示自己的框架罢了, 从自己承认对hibernate 不甚了解就可以看出来端倪,这样的话,我几乎看不出来所列代码比hibernate好在哪里,你说hibernate 复杂,主要就是你没解决的hibernate 比如,关联,缓存,什么的高级特性罢了,这个所谓的 框架 貌似就是hibernate的阉割版而已,没看出推陈出新的地方!!!!!!!!!!!!!!!
最后鄙视一下,为了表现自己随意贬低别人的做法,还对人家不了解,这不是几个踏实的技术人员的态度吧!!


收获这样的砖头是在意料之中的,这个是有争议的话题。
我列出这样的一堆代码,我希望的是能够看到使用Hibernate的代码能够比我列的代码要好,因为我想像不出来它怎样做到更简洁更高效,而不是得到一个“看不出来所列代码比hibernate好在哪里”,“使用Hibernate可以完美模拟这样的需求”之类的答案。
如果Hibernate不能做得比我的框架更简洁更高效,那么我的框架的意义就有了,很明显,他的学习曲线很短。
我是没有让ORM直接管理关联,没有内嵌在ORM里的缓存,但问题是我不需要这样子,很多企业也不需要。

我不厌其乏再次重申一下这样的ORM方案的优点:
1、学习曲线,易于掌握,一个小时的学习即可。这对于一个企业来说意味着成本的降低,极有意义。
2、代码量极少,1500行左右,一个开发团队完全有能力实现一个这种类型的ORM框架,并且扩展之。
3、机制极为简单,达到了JDBC同等的性能,不需要字节码动态生成,不需要配置,直接使用。


虽然我对Hibernate了解不够深入,但还没有弄错概念,既然我用了实例去“贬低”Hibernate,那么请用实例反驳我。而且,我想JavaEye的论坛应该不禁止展示自己的框架,也不禁止表现自我。
0 请登录后投票
   发表时间:2009-06-07  
引用
楼主的东西也是一种根据Class推导出SQL语句的。而hibernate也是这样的。所以设计思想上是相通的。而楼主的做法不如 hibernate的原因是因为,hibernate底层有不通的数据库SQL生成引擎(这个命名。。。呵呵),而且有二级缓存,关联查询,HQL查询语句等等功能。而比起楼主的做法要丰富的多。所以如果说Hibernate差那么楼主的做法比Hibernate更差。


我从未否认Hibernate的强大,从未否认它的功能丰富。正如我的标题所说,我想要的简洁,是高效,这关系到学习曲线,关系到人月,关系到成本。所以我觉得你从功能丰富的角度认为我的做法比Hibernate差我是不认同的。

我们也有SQL生成器,依照一个简单的编程规范写成的代码是可以直接在不同数据库上运行的。我们也提供数据库兼容的分页功能。

我想核心的问题是Hibernate是不是太庞大?缓存真的需要内嵌在ORM中吗?一定需要在ORM层面上实现关联吗?可不可以不用HQL?
0 请登录后投票
   发表时间:2009-06-07  
fireflyc 写道

在Hibernate才是被我们玩而不是我们被它玩了。


如果一种技术使得开发人员有被它玩的风险,那么它本身确实很值得玩味了。

我用我们的框架来重写一下你的代码:
	public SiteUserSet findUserByPage(int pageno) {
		return new SiteUserSchema().query("", Constants.PAGE_SIZE , pageno);
	}

	public void saveUser(String userName) {
		SiteUserSchema su = new SiteUserSchema();
		su.setName(userName);
		su.setSiteId(UUIDGenerator.generateUUID());
		su.setPwd(MD5.crypt(su.calPwdCode()));
		su.insert();
	}

	public void updateUser(String userId, String userName) {
		SiteUserSchema su = new SiteUserSchema();
		su.setUserId(userId);
		su.fill();
		su.setName(userName);
		su.setSiteId(UUIDGenerator.generateUUID());
		su.setPwd(MD5.crypt(entity.calPwdCode()));
		su.update();
	}

	public SiteUserSchema auth(String userName, String siteId) {
		SiteUserSchema su = new SiteUserSchema();
		SiteUserSet set = su.query(new QueryBuilder("FROM SiteUser WHERE name=? AND siteId=?",userName,siteId));
		if(set.size()>0){
			return null;
		}else{
			return set.get(0);	
		}
	}


以上就是全部,没有名存实亡的siteUserDAO,没有其他类,没有配置。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics