Java ORM JPA

从事研发管理奔八了,今天有点闲情,记录一下javaorm经过的日子;


刚工作时,写过简单网站,后来做过稍大的Web系统,整过ERP,当然都是Java方向的;


ORM(Object/Relation Mapping)(对象关系映射),相信现在大家已经非常熟悉,并且已经深刻理解;记得刚毕业那会Hibernate就已经非常火爆,当时跟他类似的框架也很多,如企业级的toplink(已经被oracle捐献给eclipse社区了),大家说半ORM的ibatis等,当时还有apache的commons-dbutils(对JDBC的一个简单封装);

toplink:虽然是企业级,代码质量也有保证,稳定性也有保证,但是因为没有hibernate开放,所以当时一般是跟Oracle厂家的产品有关系的开发使用这个最好;

ibatis:它的特点就是纯sql语句,网上有专门的测试数据,说它比hibernate执行快,最接近jdbc;后来更名为mybatis;

(其实不管是什么数据库操作框架,查询数据操作,到最后都是从数据库中取ResultSet进行读取)


commons-dbutils:简单,好用,入门快,看官网几个eg就行,只需要程序员会sql;


另外一些大型的ERP公司或专业做产品公司,都有公司自己一套ORM,不管是从开源拿来改,还是完全自己开发,都有;


还有Sun又引入了JPA ORM规范,出于两个原因:其一,简化现有Java EE和Java SE应用开发工作;其二,Sun希望整合ORM技术,实现天下归一;

(野心很大!)


使用:

hibernate,我最开始觉得并没有为我开发效率提高多少,当时觉得很麻烦,开发网站时用的是dbutils或ibatis,或者直接jdbc,其实这个时候对hibernate的定位错了,之后做大点的Web系统时,hibernate确实省了不少时间,特别是我们开发了一个hibernate相关自动化生成工具后,效率倍增;当时这个工具是使用dbutils、swing开发出来的,不过后来弃用了,因为网上出来了更好的工具;


ibatis,刚工作的时候,一个朋友做电信的项目,他们公司技术总监选数据库框架选的就是ibatis,记得当时他跟我说公司技术总监说这个速度快,当时hibernate效率瓶颈好像爆料不少(现在改变很大,特别是hibernate的缓存技术使效率提高不少);

我用过ibatis和jsf开发过一个系统,感觉查询很方便,特别是复杂的SQL查询;没有做过压力测试,效率方面不好发表意见;


toplink,这个框架没使用过,只是得知,是一个企业级的框架,并且有大公司oracle支持;


dbutils,其实这个不算一个ORM框架,但是个人使用的感觉很不错,写过不少代码自动化生成工具,及一些小工具,都是使用的dbutils; 

而且oschina也使用的dbutils;这里有相关代码:http://www.oschina.net/code/search?q=dbutils 


我所了解的几个ERP厂商的ORM使用的是自身开发的ORM,因为一般大型ERP系统都是部署在大型EJB中间件中,远程调用使用EJB调用,因为ERP系统最重要的是数据信息和数据安全,像这种企业组件,中间件会赋予很多特性,而且中间件本身也提供很多特性;


jpa,现在jpa已经很成熟稳定了,大家也都用了很长时间,我做的几个系统也用到了jpa,还不错,而且事务管理也很方便,移植更改实现也挺方便,因为有不少变态的客户,对你做系统的技术,他要参与并且知晓并指定;


不是说jpa没有缺点,反而缺点很明显,除了官方缺点,项目开发应用时缺点也很明显,记得之前一个项目,一个开发人员拿着一个纯属SQL找过来要讨论,问JPA里怎么查,好像只能返回Entity或List<Object[]>,自定义非Entity对象或其它集合对象均不行;

其实之前项目已经碰到过,不过都是返回List<Object[]>后再进行处理,一般不超过一二十个这样的查询,所以之前也就让开发直接那样处理,但是现在这个项目报表及复杂数据展现比较多,这种查询少说也有四五十个以上,考虑增加了一次中间转换影响效率不少,所以决定修改jpa实现;


分析hibernate jpa实现:

hibernate的EntityManager实现为:org.hibernate.ejb.AbstractEntityManagerImpl;536行createNativeQuery方法; 由这个入口,进行分析hibernate的jpa实现;

过程略一万字............

hibernate中处理加载数据集的是org.hibernate.loader.custom.CustomLoader,在其243行有如下代码:

this.rowProcessor = new ResultRowProcessor(
hasScalars,
       ( ResultColumnProcessor[] ) resultColumnProcessors.toArray( new ResultColumnProcessor[ resultColumnProcessors.size() ] )

这里就是一个类似ResultSetHandler的实现类,但是是按行处理,所以我们改造时,为了使改动最小化,也按行处理即可;

其中  Query createNativeQuery(String sqlString, Class resultClass)  中的Class最后存在这个参数中:


么现在我们看看,它是怎么传进这里的:

如下图,这是hibernate创建纯SQL查询的方法,最下面的一个方法就是新加的,准备使用ResultSet处理接口:


注意的是,要按第一个红框中的代码进行改造,加参数;

如下图:


然后在Query,NativeSQLQueryPlan,NativeSQLQuerySpecification,SQLQueryImpl,CustomQuery,SQLCustomQuery接口及类中增加RowResultSetProcessor传递的方法及属性;

最后改造一个CustomLoader构造方法最下面的代码即可,如下:

if (customQuery.getRowResultSetProcessor() == null) {
this.rowProcessor = new ResultRowProcessor(hasScalars,
(ResultColumnProcessor[]) resultColumnProcessors.toArray(new ResultColumnProcessor[resultColumnProcessors
.size()]));
} else {
this.rowProcessor = customQuery.getRowResultSetProcessor();
this.rowProcessor.setHasScalars(hasScalars);
this.rowProcessor.setColumnProcessors((ResultColumnProcessor[]) resultColumnProcessors
.toArray(new ResultColumnProcessor[resultColumnProcessors.size()]));
}

改造完后,编译覆盖即可;

当前hibernate版使用的是3.6版;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值