`
javaonejcy
  • 浏览: 4837 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

可爱的javaee:让对象持久化变平

阅读更多

JDBC java 对象持久化提供了有效的支持,但仍然繁琐,以至于现在甚至没人再愿意提他。ORM 框架使java 对象持久化更聪明更简单,却并不一定轻松。hibernate 实现了“完全对象映射”的质量等级,为了解决长长的问题列表,他的开发团队付出了令人尊敬的努力。但是用好hibernate ,你需要掌握更多的知识而不是更少。由于应用软件和关系数据库面对的问题域的不同,设计差异、复杂对象、不恰当的映射配置、自动生成语句都可能给系统带来隐患。最糟糕的是,这种自动生成的sql 难于调试。

iBatis 是另一个选择,平面映射使事情变得简单,不过,数据持久层和sql 语句总是息息相关,sql 语句配置在外部文件的方式使得无论是开发还是维护,我们都要配置代码两头看。而且对于简单的CRUD 语句,SQL 是一个相当通用的标准,所以完全不自动生成sql 的做法也显得有点傻。

即使有了很多ORM 框架可供选择,但是重复发明轮子的事还是不断出现,比如,笔者将为你介绍一个小而简单的ORM 框架(真头疼,又是框架!)。与大多数ORM 框架相比,他能做的更少而不是更多,甚至能否跻身ORM 框架之列也是个问号。一个不太聪明的框架也许会使你扫兴,但笔者要说的是:如果能用更少的技术,做更多的事情,岂不是很好?

      假设我们有这样的类:

public class Foo {
	private String fooId;
	private User modifyMan;
	//getter and setter
}

      使用hibernate ,你可以这样得到这个对象:

// hibernate code
Foo foo = new Foo(“123”);
session.get(foo);

      这样,你得到了包括User的完整对象。换一种方式,如果这样做我们会有什么损失吗?

public class Foo {
	private String fooId;
	private String modifyManId;
	private User modifyMan;
	//getter and setter
}

// simple ORM framework code
Foo foo = new Foo(“123”);
if(broker.readBean(foo)){
	User modifyMan = new User(foo.getModifyManId());
	foo.setModifyMan(broker.readBean(modifyMan));
}

      多写了几行代码。当然,如果你的对象很复杂,需要的代码就更多,这是不够聪明的做法,但是这样做避免了复杂的自动对象映射。如果你不需要modifyMan的详细信息,你就可以不载入他,不加入这个属性。而为了CUD操作的方便,modifyManId属性总是应该加入,你可以象下面这样更新一条记录:

Foo foo = new Foo(“123”);
if(broker.readBean(foo)){
	foo.setModifyManId(“1”);
	broker.updateBean(foo);
}

      如果你要得到一个聚合,做法也是类似的:

public class Foo {
	private String fooId;
	private String modifyManId;
	private List childs;
	//getter and setter
}

SQLBuilder sql = new SQLBuilder();
sql.segment(“foo = ”);
sql.value(foo.getFooId());
foo.setChilds(broker.readBeanList(Foo.class,sql));

      SQLBuilder是一个sql语句的构建工具,他使你可以用类似StringBuilder的方式构建sql语句,而不必关心底层的处理方式。笔者介绍的ORM框架内部可以使用Statement,也可以使用PreparedStatement。至于为什么不始终使用PreparedStatement,是因为各种DBMS的JDBC驱动对这两种声明的支持程度不同,比如MySql用Statement速度更快,而Oracle用PreparedStatement可以提升整体性能。当然MySql和Oracle都有自己的JDBC扩展,效率更高,但是由于他们没有采用JDBC标准的接口,所以ORM框架也不能对其提供支持。
      好吧,必须再告诉你一个真相,即笔者介绍的ORM框架还是需要配置的,不过不是在配置文件里,而且需要JDK5以上的支持。没错,你猜对了,就是使用元数据。不过笔者并没有使用JPA的标准元数据,由于作用范围有限,所以这些元数据非常简单。使用了元数据,你的类就象是下面这个样子:

 

public class Foo {
	@Key
	@Column(name = “foo_id”)
	private String fooId;
	@Column(name = “modify_man_id”)
	private String modifyManId;
	@Column(type = ColumnType.OUT)	
	private String modifyManName;
	private List childs;
	//getter and setter
}

 

      元数据只能标注基本类型,包装类型和日期时间类型的属性。其中@Key标注主键,默认为用户指定类型,另外还有自增类型和序列类型;@Column标注列,如果属性名和列名相同就不必指明name属性;@Column(type=ColumnType.READ)标注只读的列,可以用来标注如更新时间这样的只读不写的字段,@Column(type=ColumnType.OUT),如果你只需要外表的某些属性用来显示,你就可以这样做:

SQLBuilder sql = new SQLBuilder();
sql.segment(“select t.*, t2.user_name as modifyManName from foo t, user t2
                                         where t.modify_man_id = t2.user_id and t.foo_id = ”);
sql.value(“123”);
Foo foo = new Foo();
broker.queryBean(foo, sql);

      你会得到你需要的数据。是的,本ORM框架也不生成关联查询语句,因为那样做会面临太多问题。除以上功能外,broker还可以为你查出数据行、列表和分页。当然这就不属于ORM的范畴了。如果broker不能满足你的需求,比如处理大对象,你还可以得到你想要的:

Connection connection = broker.getConnection();

      之后你就可以为所欲为了。
      说了半天,其实这个ORM框架并没有名字。这个没有名字的目标有限的框架只有简单功能并且没有发明新的概念。他遵循80/20原则,把棘手的问题都抛给了应用层。这些问题包括:对象组装、大对象、批处理、存储过程和缓存。现在总结一下他的特点:

 

  • 平面映射
  • 支持继承
  • 通用的sql 构建方法
  • 可直接运行的sql 输出
  • 支持多数据源

 

      普元说,让世界变平。这个平字寓意深刻,见仁见智。hibernate可以为你做很多事,也有适用范围的性能优化策略和技术,但在有一定规模和复杂度的场景中,使用hibernate会增加而不是减少架构设计和质量保证的难度。如果你的项目特点是读多写少,项目环境比较单一,并且你的团队技术和管理水平都跟得上,那么hibernate是个很好的选择。不过,相信也有很多场景,使用简单通用的ORM框架,加上灵活的按需而动的架构策略,还对象持久化一个直观透明的面貌会是更明智的选择。

 

      后记:这篇文章忽略了hibernate的优秀的懒加载机制,这的确是个大大的错误,另外笔者发现,在实际应用中,为了规避hibernate的复杂性,也有人拿hibernate完全当平面映射框架来用的,hibernate很多有用的特性都被闲置了,不过也确实简单易用了,这真是有些尴尬啊。

 

2013年2月19日更新说明:修正非字符型参数空值报空指针错误

2014年3月28日更新说明:加入了读取Oracle Clob字段的支持

1
0
分享到:
评论
2 楼 sp42 2015-05-24  
可否开源呢?
1 楼 sp42 2015-05-24  
非常不错!

相关推荐

    JavaEE课程设计:票据管理系统源码.zip

    JavaEE课程设计:票据管理系统源码 JavaEE课程设计:票据管理系统源码 JavaEE课程设计:票据管理系统源码 JavaEE课程设计:票据管理系统源码 JavaEE课程设计:票据管理系统源码 JavaEE课程设计:票据管理系统...

    Java 从入门到精通全程笔记(JavaSE+JavaEE :史上最全笔记)

    JavaSE+JavaEE企业级开发 全程笔记免费下载,内容详尽,doc文档,共173页,六号字体,双栏排版。 *、Java 基础, *、web, *、数据库(Mysql Oracle jdbc Hibernate hql/sql), *、JSP, *、Ajax *、Struts, *、...

    javaee-Session持久化小结

    这篇名为"javaee-Session持久化小结"的文章可能涵盖了如何在JavaEE应用中实现Session的创建、管理和持久化。 首先,Session的创建通常是通过HttpSession接口的`getSession()`方法完成的。当用户首次访问服务器时,...

    JavaEE 系统架构 持久化层 面向对象 工作流

    本主题将深入探讨JavaEE系统架构中的持久化层、面向对象编程以及工作流,同时结合实际案例——企业主流MySQL高可用集群架构三部曲之PXC,来增强理解。 首先,JavaEE的持久化层是处理数据库交互的核心部分。它通过...

    JavaEE:JavaEE 项目

    例如,可能包含一个使用Servlet和JSP实现的Web应用,EJB组件用于业务逻辑处理,JPA进行数据持久化,CDI进行依赖管理,以及可能涉及的JSF界面设计和JMS异步通信等。对于初学者或希望提升JavaEE技能的开发者来说,这是...

    javaee实验五 大学本科生 hibernate

    【JavaEE实验五:大学本科生Hibernate】实验主要目标在于让学生掌握Hibernate开发环境的搭建,理解ORM框架的概念,以及深入理解Hibernate映射文件和配置文件的使用。Hibernate是一个强大的ORM(对象关系映射)框架,...

    javaee大作业实例

    6. **JPA(Java Persistence API)**:JavaEE中的持久化框架,简化了对象关系映射,使得Java对象可以直接与数据库交互。 7. **JSF(JavaServer Faces)**:另一种用于构建用户界面的JavaEE技术,提供组件化和事件...

    JavaEE:JavaEE实战

    2. **EJB(Enterprise JavaBeans)**:EJB是JavaEE中的核心组件,提供了服务器端业务逻辑的容器管理和对象持久化。包括会话bean(Session Beans)用于方法调用,实体bean(Entity Beans)用于数据库持久化,以及消息...

    javaee:javaEE 应用程序

    EJB分为三种类型:会话Bean(Session Beans)处理客户端请求,实体Bean(Entity Beans)代表数据库中的持久化对象,消息驱动Bean(Message-Driven Beans)用于处理JMS消息。 4. **JMS(Java Message Service)**:...

    javaee办公自动化

    5. **JPA(Java Persistence API)**:JPA是JavaEE中的持久化框架,它提供了统一的API来操作数据库。在办公自动化系统中,JPA可以用来处理对象关系映射(ORM),将Java对象和数据库记录关联起来,简化数据库操作。 ...

    javaEE持久化

    javaEE 技术中JPA持久化技术 对实体的 一对一、 一对多、 多对多关系进行举例分析

Global site tag (gtag.js) - Google Analytics