我要“冬眠”

我要“冬眠”

作者:zfive5(zhaozidong)

联系:[email protected]

道生一,一生二,二生三,三生万物。

老子--《道德经》

1. Hibernate由来

Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Web应用中使用,最具革命意义的是,Hibernate可以在J2EE架构中取代CMP,完成数据持久化的重任。

在软件任何新生的事物都是为了解决具体问题而诞生的,任何事都是先有因再有果!

说到Hibernate为什么会横空出世,那不得不从数据库系统的历史说起。

数据库系统的萌芽出现于60 年代。当时计算机开始广泛地应用于数据管理,对数据的共享提出了越来越高的要求。传统的文件系统已经不能满足人们的需要。能够统一管理和共享数据的数据库管理系统(DBMS)应运而生。然而按数据模型的特点将传统数据库系统分成网状数据库、层次数据库和关系数据库三类。现在大家接触的主流数据都是关系型数据库,代表产品有Oracle、IBM公司的 DB2、微软公司的MS SQL Server以及Informix、ADABASD等等。

1970年,IBM的研究员E.F.Codd博士发表了一篇名为“A Relational Model of Data for Large Shared Data Banks”的论文,提出了关系模型的概念,奠定了关系模型的理论基础。

1970年关系模型建立之后,IBM公司在San Jose实验室增加了更多的研究人员研究这个项目,这个项目就是著名的System R。其目标是论证一个全功能关系DBMS的可行性。该项目结束于1979年,完成了第一个实现SQL的 DBMS。

1983年IBM发布了DATABASE 2(DB2)for MVS。1993年IBM发布了DB2 for OS/2 V1和 DB2 for RS/6000V1,这是 DB2 第 一次在Intel 和Unix 平台上出现。1996年IBM发布 DB2 V2.1.2 ,这是第一个真正支持 JAVA 和 JDBC 的数据库产品。

1977年6月,Larry Ellison与Bob Miner和Ed Oates在硅谷共同创办了一家名为软件开发实验室的计算机公司(ORACLE公司的前身)。 1998年9月,ORACLE公司正式发布ORACLE 8i。“i”代表Internet,这一版本中添加了大量为支持Internet而设计的特性。这一版本为数据库用户提供了全方位的Java支持。ORACLE 8i成为第一个完全整合了本地Java运行时环境的数据库。

1984年,Mark B. Hiffman和Robert Epstern创建了Sybase公司,并在1987年推出了Sybase数据库产品。SYBASE主要有三种版本,一是UNIX操作系统下运行的版本,二是Novell Netware环境下运行的版本,三是Windows NT环境下运行的版本。对UNIX操作系统目前广泛应用的为SYBASE 10 及SYABSE 11 for SCO UNIX。

1988年推出了第一个OS/2版本。SQL Server近年来不断更新版本,1996年,Microsoft 推出了SQL Server 6.5版本;1998年,SQL Server 7.0版本和用户见面;SQL Server 2000是Microsoft公司于2000年推出,目前最新版本是SQL SERVER 2008。

这么多商业数据库系统,那么必然没有预置对应的操作语言标准,这便是现在耳熟能详的SQL,关于SQL还得回到1974 年,IBM的Ray Boyce和Don Chamberlin将Codd关系数据库的12条准则的数学定义以简单的关键字语法表现出来,里程碑式地提出了SQL语言。SQL语言是一个包括查询、操纵、定义和控制等功能通用的关系数据库语言。到二十世纪七十年代中期,关系理论才通过SQL在商业数据库Oracle和DB2中使用。   1986年,ANSI把SQL作为关系数据库语言的美国标准,同年公布了标准SQL文本。下面来自互联网一段IT往事(标准化有巨大的威力)

80年代,ORACLE的主要竞争对手是Ingres数据库。Ingres主要的设计者是当时鼎鼎大名的Michael Stonebraker教授。可以说Ingres数据库软件是上个世纪80年代技术上最好的数据库,Ingres市场分额的快速增长已经给ORACLE早成了很大的压力。IBM公司伸出“上帝之手”。 Ingres使用的是Stonebraker 发明的QUEL(Query Language))的查询技术,这和IBM的SQL大不相同。在某些地方QUEL甚至要优于SQL。IBM当时担心Ingres把QUEL变成标准会对自己不利。经过一番衡量,决定把自己的SQL提交给数据库标准委员会。而Stonebraker教授可不打算把QUEL提交给数据库标准委员会,学院派的他认为这麽做实际上是扼杀了创新精神。鹬蚌相争,渔翁得利。ORACLE看到并抓住了这个绝佳的机会,大肆宣布ORACLE全面与SQL兼容,加上ORACLE当时对Ingres PC上的版本的攻击(弱化对手优势,化解自己弱势是他们最拿手的本领),再加上ORACLE公司销售上的强势,Ingres不断丢城失地,等到后来推出支持SQL的数据库的时候为时已晚。紧跟IBM让ORACLE得以成长、壮大,拥抱标准,拥抱开放,拥抱变化,让ORACLE立于不败之地。

有了标准的SQL,接下了就是程序要访问它,在Java的世界里有JDBC接口规范,各个数据库厂商去实现,定义了JDBC接口族定义也是的扩展和重用的典范。如下面的就典型的通过JDBC操作数据库的例子:

import java.util.List;

import java.sql.*;

public class TestJDBC {

public static void main(String[] args) {

String connectionString = "jdbc:sqlserver://zhaozd19:1433;databaseName=TestHibernate;";

String user ="sa";

String password = "asddsa";

String sqlStr = "select * from AA_USER";

try{

Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");

Connection con = DriverManager.getConnection(connectionString,user,password);

Statement st = con.createStatement();

ResultSet rs = st.executeQuery( sqlStr );

List list=new java.util.ArrayList();

while(rs.next())

{

User e=new User();

//赋值语句很机械

e.name=rs.getString("name");//赋值语句很机械

e.code=rs.getString("code");

list.add(e);

}

rs.close();

st.close();

con.close();

}

catch(Exception err)

{

err.printStackTrace(System.out);

}

}

}

代码中加粗部分几乎是对应任务数据库应用来说都会有的,虽然代码很简单,但同样的代码让大家写大中型项目中重复上千遍,那对本来工期紧张的项目来说就是厄运。如果一处写,步步重写。《程序员修炼之道:从小工到专家》这本书里就写了这个DRY原则:Don't Repeat Yourself 同样的信息应该只在一处出现,不然会给以后的维护带来无穷无尽的烦恼。的确软件开发的实践是不断有问题,不断改进的过程。

关于消除重复的问题,同样在关系型数据库设计时也的要考虑重要问题。是否感觉软件世界里是相通的,好像有一个普适性原则在作用,可以概括为软件开发中任何该进和改良都逃不出“时间、成本、质量”这三个维度的改进, DRY规则和设计模式在软件项目就是这三个方面的努力。

我们优秀的前辈们厌倦了这种重复性的劳动,他们开始积极采用 “偷懒”做法来改进,把重复的代码及工作通过此来消化掉,使我们有更多的时间关心更重要的业务处理。现在这类帮助Java软件从业者消除JDBC缺点的框架及工具从昂贵的商业产品到内置于J2EE中的EJB标准应有应有。然而,在很多情况下,自身的复杂性,使得我们必须学习使用它们的详细规则,同时这类工具为应付复杂的持续变化的需求而不断加入新的特性,造成在比较简单和常见的场景中使用它们所面临的复杂性反而盖过了所能获得的好处盖过它们提供好处。正因为此才促进了轻量级O/R Mapping框架的出现,它们中有一个就Hibernate,我相信如果将来有更简单易用的出现,我们大家也还会像选择Hibernate一样,去选择另一个Hibernate。当然我坚信Hibernate也进化,例如它对JPA的实现就是最好的例证。

JPA:全称Java Persistence API.JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。JPA是需要Provider来实现其功能的,Hibernate就是JPA Provider中一个。

Hibernate安装包解压路径下的changelog.txt内容,就可以佐证Hibernate无尽的生命力,它不是一个人在战斗,而是全世界关心它的人再战斗。如果你使用它的过程中发现它存在缺陷,就可以改正它,说不定将来某一个版本的changelog.txt就会记录你的贡献。

Hibernate Changelog

===================

Note: Newer entries are automatically generated and the description might not

match the actual issue resolution (i.e. a bug might not be a bug). Please

refer to the particular case on JIRA using the issue tracking number to learn

more about each case.

Changes in version 4.0.0.Final (2011.12.14)

------------------------------------------------------------------------------------------------------------------------

https://hibernate.onjira.com/browse/HHH/fixforversion/11656

** Bug

* [HHH-6836] - some test failures on Oracle

* [HHH-6866] - UUID wrongly mapped as 'char(255) for bit data' on DB2

* [HHH-6867] - test data overflow causes org.hibernate.test.cut.CompositeUserTypeTest.testCustomColumnReadAndWrite fails on DB2

* [HHH-6870] - sysdate function in oracle dialect is a non argu and no parentheses function

** Improvement

* [HHH-6729] - Upgrade to Infinispan 5.1 and update default second level cache config file

以下略……

2. Hibernate版本历史

在2001年开始Hibernate是由Gavin King的替代式EJB2的实体bean。当时它的任务是简单的比EJB2的提供简化的复杂性,并允许缺少的功能,提供更好的持久能力。

2003年,Hibernate的开发团队开始Hibernate2释放过的第一个版本提供许多显着改善。

Hibernate 从3.2开始,就开始兼容JPA。Hibernate3.2获得了Sun 的JPA 兼容认证。

写本文时它的版本就到了4.0.0版

3. 从环境到程序

Hibernate的开发调试环境的配置很容易,只要按照如下步骤就可以轻松完成环境搭建:

Ø 下载JRE和eclipse开发工具,地址如下:

http://www.oracle.com/technetwork/java/javase/downloads/index.html

http://www.eclipse.org/downloads/

JRE就Java程序的运行时环境,Eclipse的需要JRE的支持,直接下载后安装就可以了。

Eclipse的安装更简单,下载后直接解压双击下图红色框中得图标就可以,简单吧,比起VS2008的安装那真的是小巫见大巫了,真正的绿色软件呀。

Eclipse已经从一种语言开发环境蜕变成了一个框架平台,通过众多插件的支持其他功能相对固定的IDE软件很难具有的灵活性。许多软件开发商以Eclipse为框架开发自己的IDE,例如:Rational ClearCase。如果要开发应用软件,大家不妨考虑一下它。

Ø 下载hibernate-release-4.0.0.Final,地址如下:

http://sourceforge.net/projects/hibernate/files/

解压hibernate-release-4.0.0.Final.zip,如下图复制required中的*.jar到jre6\lib\hibernate4.0.0就OK

到此软件安装配置完成,接一下在配置一下Eclipse环境,就可以使用Hibernate了。

Ø 创建TestHibernate工程,点击Project->Properties,弹出如下对话框,通过点击红色框部分的按钮“Add External JARs”或者 “Add Library”来完成刚才复制的Hibernate框架的加入。本文是通过Add Library来做的。

例子程序如下:

package zfive5;

import java.util.List;

import org.hibernate.HibernateException;

import org.hibernate.Query;

import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.hibernate.Transaction;

import org.hibernate.cfg.Configuration;

public class TestHibernate {

public static void main(String[] args) {

SessionFactory sessionFactory=null;

org.hibernate.cfg.Configuration cfg=null;

Session session=null;

Transaction tx=null;

try

{

cfg=new Configuration().configure(new java.io.File("E:/zhaozd/workspace/TestHibernate/bin/zfive5/hibernate.cfg.xml"));

sessionFactory=cfg.buildSessionFactory();

session=sessionFactory.openSession();

tx=session.beginTransaction();

Query query=session.createQuery("from User");

List lists=(List)query.list();

tx.commit();

session.close();

}

catch(HibernateException err)

{

if(tx!=null) tx.rollback();

err.printStackTrace(System.out);

}

finally

{

if(session!=null) session.close();

if(sessionFactory!=null) sessionFactory.close();

if(cfg!=null) cfg=null;

}

}

}

..bin/zfive5/hibernate.cfg.xml 内容如下,这个文件主要定义Hibernate连接数据等公共属性:

"-//Hibernate/Hibernate Configuration DTD//EN"

"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

com.microsoft.sqlserver.jdbc.SQLServerDriver

jdbc:sqlserver://zhaozd19:1433;databaseName=TestHibernate;

sa

asddsa

org.hibernate.dialect.SQLServer2008Dialect

true

true

update

5

20

300

50

3000

../bin/zfive5/User.hbm.xml内容如下,这个文件主要定义了实体与数据的关系:

PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

注意:如果是第一次Hibernate程序的话,有80%会遇到如下这个问题:

org.hibernate.InvalidMappingException: Unable to read XML

看到这个摸不着头脑的提示,简直不知如何是好:(

画线部分的具体内容如下:

The content of element type "class" must match "(meta*,subselect?,cache?,synchronize*,comment?,tuplizer*,(id|composite-id),discriminator?,natural-id?,(version|timestamp)?,(property|many-to-one|one-to-one|component|dynamic-component|properties|any|map|set|list|bag|idbag|array|primitive-array)*,((join*,subclass*)|joined-subclass*|union-subclass*),loader?,sql-insert?,sql-update?,sql-delete?,filter*,fetch-profile*,resultset*,(query|sql-query)*)

看了半天终于知道了每一个实体对应关系必须指定一个id|composite-id主键,来唯一标示一个对象实例。

Hibernate把程序语句转化成配置文件是否是终极解决方案?如果不是,还有其它的方案处理。至少到现在,个人对Hibernate感觉无非是从JDBC一个大陷阱里刚出来有到了另一个它的陷阱里去。

JPA的整合Hibernate配置文件和实体类,这也是进步。

在软件界,做任何事情,都应该抱着 “保存简洁”,不要让人们感觉到“发疯了”!

4. 授权方式

关于Hibernate开放源代码也是大家选择它的一个原因,因为它对开发人员来说再也不是一个黑盒子了,再也不用去猜什么原因照成了该死的缺陷。用Hibernate发现问题的时候,可以先看代码,是在不行挂上源代码调试---相信源代码下无秘密。提到开源,大家第一个想到Linux,Hibernate授权方式是否也像Linux那样商业开发不友好(企业应用很关心这一点,别因为用它,把自己核心的东西给开源了)。现在提到了开源项目的授权,不妨把现在几个主流的授权方式介绍一下,

BSD:

BSD开源协议是一个给于使用者很大自由的协议。基本上使用者可以”为所欲为”,可以自由的使用,修改源代码,也可以将修改后的代码作为开源或者专有软件再发布。但”为所欲为”的前提当你发布使用了BSD协议的代码,或则以BSD协议代码为基础做二次开发自己的产品时,

需要满足三个条件:   

◆如果再发布的产品中包含源代码,则在源代码中必须带有原来代码中的BSD协议。

◆如果再发布的只是二进制类库/软件,则需要在类库/软件的文档和版权声明中包含原来代码中的BSD协议。   

◆不可以用开源代码的作者/机构名字和原来产品的名字做市场推广。

例如, FreeBSD,NetBSD

Apache Licence 2.0:

Apache Licence是著名的非盈利开源组织Apache采用的协议。该协议和BSD类似,同

样鼓励代码共享和尊重原作者的著作权,同样允许代码修改,再发布(作为开源或商业软件)。

需要满足的条件也和BSD类似:   

◆需要给代码的用户一份Apache Licence   

◆如果你修改了代码,需要再被修改的文件中说明。   

◆在延伸的代码中(修改和有源代码衍生的代码中)需要带有原来代码中的协议,商标,专利声明和其他原来作者规定需要包含的说明。   

◆如果再发布的产品中包含一个Notice文件,则在Notice文件中需要带有Apache Licence。

你可以在Notice中增加自己的许可,但不可以表现为对Apache Licence构成更改。   Apache Licence也是对商业应用友好的许可。使用者也可以在需要的时候修改代码来满足需要并作为开源或商业产品发布/销售。

例如:Apache、Tomcat,Struct 、spring和Andriod 等

GNU GPL:

我们很熟悉的Linux就是采用了GPL。GPL协议和BSD, Apache Licence等鼓励代码重用的许可很不一样。GPL的出发点是代码的开源/免费使用和引用/修改/衍生代码的开源/免费使用,但不允许修改后和衍生的代码做为闭源的商业软件发布和销售。这也就是为什么我们能用免费的各种linux,包括商业公司的linux和linux上各种各样的由个人,组织,以及商业软件公司开发的免费软件了。GPL协议的主要内容是只要在一个软件中使用(”使用”指类库引用,修改后的代码或者衍生代码)GPL 协议的产品,则该软件产品必须也采用GPL协议,既必须也是开源和免费。这就是所谓的”传染性”。GPL协议的产品作为一个单独的产品使用没有任何问题, 还可以享受免费的优势。由于GPL严格要求使用了GPL类库的软件产品必须使用GPL协议,对于使用GPL协议的开源代码,商业软件或者对代码有保密要求的部门就不适合集成/采用作为类库和二次开发的基础。 其它细节如再发布的时候需要伴随GPL协议等和BSD/Apache等类似。

例如:Linux,GNU C++,KDE

GUN LGPL:

LGPL 是GPL的一个为主要为类库使用设计的开源协议。和GPL要求任何使用/修改/衍生之GPL类库的的软件必须采用GPL协议不同。LGPL 允许商业软件通过类库引用(link)方式使用LGPL类库而不需要开源商业软件的代码。这使得采用LGPL协议的开源代码可以被商业软件作为类库引用并 发布和销售。但是如果修改LGPL协议的代码或者衍生,则所有修改的代码,涉及修改部分的额外代码和衍生的代码都必须采用LGPL协议。因 此LGPL协议的开源 代码很适合作为第三方类库被商业软件引用,但不适合希望以LGPL协议代码为基础,通过修改和衍生的方式做二次开发的商业软件采用。   

GPL/LGPL都保障原作者的知识产权,避免有人利用开源代码复制并开发类似的产品。

例如: Hibernate,PHP-GTK

MIT

MIT是和BSD一样宽范的许可协议,作者只想保留版权,而无任何其他了限制。也就是说,你必须在你的发行版里包含原许可协议的声明,无论你是以二进制发布的还是以源代码发布的。MIT协议又称麻省理工学院许可证,最初由麻省理工学院开发。被授权人权利:

u 被授权人有权利使用、复制、修改、合并、出版发行、散布、再授权及贩售软件及软件的副本。

被授权人可根据程式的需要修改授权条款为适当的内容。被授权人义务:在软件和软件的所有副本中都必须包含版权声明和许可声明。

例如:BitTorrent

MPL:

MPL是The Mozilla Public License的简写,是1998年初Netscape的 Mozilla小组为其开源软件项目设计的软件许可证。MPL许可证出现的最重要原因就是,Netscape公司认为GPL许可证没有很好地平衡开发者对 源代码的需求和他们利用源代码获得的利益。同著名的GPL许可证和BSD许可证相比,MPL在许多权利与义务的约定方面与它们相同(因为都是符合OSIA 认定的开源软件许可证)。但是,相比而言MPL还有以下几个显著的不同之处:

◆ MPL虽然要求对于经MPL许可证发布的源代码的修改也要以MPL许可证的方式再许可出来,以保证其他人可以在MPL的条款下共享源代码。但是,在MPL 许可证中对“发布”的定义是“以源代码方式发布的文件”,这就意味着MPL允许一个企业在自己已有的源代码库上加一个接口,除了接口程序的源代码以MPL 许可证的形式对外许可外,源代码库中的源代码就可以不用MPL许可证的方式强制对外许可。这些,就为借鉴别人的源代码用做自己商业软件开发的行为留了一个 豁口。
◆ MPL许可证第三条第7款中允许被许可人将经过MPL许可证获得的源代码同自己其他类型的代码混合得到自己的软件程序。
◆ 对软件专利的态度,MPL许可证不像GPL许可证那样明确表示反对软件专利,但是却明确要求源代码的提供者不能提供已经受专利保护的源代码(除非他本人是 专利权人,并书面向公众免费许可这些源代码),也不能在将这些源代码以开放源代码许可证形式许可后再去申请与这些源代码有关的专利。
◆ 对源代码的定义
而在MPL(1.1版本)许可证中,对源代码的定义是:“源代码指的是对作品进行修改最优先择 取的形式,它包括:所有模块的所有源程序,加上有关的接口的定义,加上控制可执行作品的安装和编译的‘原本’(原文为‘Script’),或者不是与初始 源代码显著不同的源代码就是被源代码贡献者选择的从公共领域可以得到的程序代码。”
◆ MPL许可证第3条有专门的一款是关于对源代码修改进行描述的规定,就是要求所有再发布者都得有一个专门的文件就对源代码程序修改的时间和修改的方式有描述。

例如:FireFox

在Hibernate安装的下载包得解压路径的根目录,有一个lgpl.txt,说明它符合GUN LGPL,它允许商业软件通过类库引用(link)方式使用LGPL类库而不需要开源商业软件的代码。这使得采用LGPL协议的开源代码可以被商业软件作为类库引用并 发布和销售。大家可以放心用在企业应用中调用Hibernate的类库了。

关于开源协议并不只有以上列举的那些,经由Open Source Initiative组织通过批准的开源协议目前就有58种之多,大家如果感兴趣的话,可以访问一下地址:http://www.opensource.org/licenses/alphabetical去看一下,在我们使用开源项目的时候也做到心中有数。

你可能感兴趣的:(我要“冬眠”)