在这篇文章中我们就来讨论一下 hbm.xml 与 Annotations的优缺点,看看那种情况最适合你.
首先,讨论一下 xml 配置文件的优点, 个人认为主要优点就是当你改变底层配置时 不需要改变和重新编译代码,只需要在xml 中更改就可以了,例如 Hibernate.cfg.xml 当你要更改底层数据库时, 只要更改配置文件就可以了.Hibernate会为你做好别的事情.
那么xml的缺点呢,个人认为有以下几点:
描述符多,不容易记忆,掌握 要深入了解还有看DTD文件
无法做自动校验,需要人工查找
读取和解析xml配置要消耗一定时间,导致应用启动慢,不便于测试和维护
当系统很大时,大量的xml文件难以管理
运行中保存xml配置需要消耗额外的内存
在O/R Mapping的时候需要在java文件和xml配置文件之间交替,增大了工作量
其中第一 二点 借助于先进的IDE 可能不是什么问题. 但是对初学者还是个问题
下面我们看看 Annotations的 特性吧! 可以解决xml遇到的问题,有以下优点
描述符减少。以前在xml配置中往往需要描述java属性的类型,关系等等。而元数据本身就是java语言,从而省略了大量的描述符
编译期校验。错误的批注在编译期间就会报错。
元数据批注在java代码中,避免了额外的文件维护工作
元数据被编译成java bytecode,消耗的内存少,读取也很快,利于测试和维护
关于映射文件是使用 hbm.xml 文件还是使用 Annotations 我们来看看2者的性能吧. 先声明一下,个人认为映射文件一旦配置好就不会在很大程度上改变了.所以使用xml文件并不会带来很大的好处.如果你认为 映射文件在你的项目中也经常变化,比如一列String数据 ,今天你使用 length="16" 明天你认为 该数据的长度应该更长才能满足业务需求 于是改为length="128" 等等类似的问题 . 如果你经常有这方面的变动的话,下面的比较你可以不用看了 , 你应该使用 xml文件 因为Annotations 无法很好的满足你的要求.
现在让我们就来看看2者的性能比较吧.
(说明: 这里只是比较查找 插入 的时间快慢,没有比较除运行时间以外的其他性能,如 内存占用量 等等)
先来看看测试程序和配置.
首先在 Hibernate.cfg.xml 文件中去掉了
<property name="hibernate.hbm2ddl.auto">update</property>
这一行, 因为在前面的实验中以及建立了数据库表了 不再需要更新了.如果你是第一次运行该例子 还是要该行的.
Test.java 如下:
/*
*Createdon2005
*@author
*/
packagetest.hibernate.annotation;
importorg.hibernate.Session;
importorg.hibernate.Transaction;
publicclassTest{
publicstaticvoidmain(String[]args){
longstart=0;
longend=0;
start=System.currentTimeMillis();//程序开始时间
Sessions=HibernateUtil.currentSession();
longmid=System.currentTimeMillis();//初始化完毕的时间 (可能此时并没有初始化完毕^_^)
Transactiontx=s.beginTransaction();
/********************测试读取的代码************************/
Personp=null;
for(inti=1;i<=100;i++){
p=(Person)s.get(Person.class,i);
System.out.println(p.getName());
}
System.out.println(p.getName());
/********************测试读取1次的代码************************/
Personp=null;
p=(Person)s.get(Person.class,1);
System.out.println(p.getName());
/*********************测试插入的代码*************************************/
/*
for(inti=0;i<100;i++){
Personp=newPerson();
p.setAge(i+1);
p.setName("icerain"+i);
p.setSex("male"+i);
s.save(p);
s.flush();
}
*/
tx.commit();
HibernateUtil.closeSession();
end=System.currentTimeMillis();//测试结束时间
System.out.println("String[]-starttime:"+start);
System.out.println("String[]-endtime:"+end);
System.out.println("Inittime:"+(mid-start)); // 打印初始化用的时间
System.out.println("Lasttimeis:"+(end-mid)); //打印 数据操作的时间
System.out.println("Totaltime:"+(end-start)); //打印总时间
}
}
Annotations 包中的Person.java 如下
packagetest.hibernate.annotation;
importjava.util.LinkedList;
importjava.util.List;
importjavax.persistence.AccessType;
importjavax.persistence.Basic;
importjavax.persistence.Entity;
importjavax.persistence.GeneratorType;
importjavax.persistence.Id;
importjavax.persistence.Table;
importjavax.persistence.Transient;
/**
*Persongeneratedbyhbm2java
*/
@SuppressWarnings("serial")
@Entity(access=AccessType.PROPERTY)
@Table
publicclassPersonimplementsjava.io.Serializable{
privateIntegerid;
privateStringname;
privateStringsex;
privateIntegerage;
privateListlist=newLinkedList();
//Constructors
/**defaultconstructor*/
publicPerson(){
}
/**constructorwithid*/
publicPerson(Integerid){
this.id=id;
}
//Propertyaccessors
@Id(generate=GeneratorType.AUTO)
publicIntegergetId(){
returnthis.id;
}
publicvoidsetId(Integerid){
this.id=id;
}
@Basic
publicStringgetName(){
returnthis.name;
}
publicvoidsetName(Stringname){
this.name=name;
}
@Basic
publicStringgetSex(){
returnthis.sex;
}
publicvoidsetSex(Stringsex){
this.sex=sex;
}
@Basic
publicIntegergetAge(){
returnthis.age;
}
publicvoidsetAge(Integerage){
this.age=age;
}
@Transient
publicListgetList(){
returnlist;
}
publicvoidsetList(Listlist){
this.list=list;
}
}
其他的代码几乎没有改变:
下面的每种类型的测试都测试了3次以上, 取中间的测试时间.
测试机器配置:
CPU: AMD Athlon (xp) 2000+
内存: 784880KB
硬盘: 三星 SP0812N
读取一次的比较:(单位: 毫秒)
使用Annotations 的测试数据
使用Xml文件的测试数据
简要说明
Init time :
2444
Init time :
2431
测试前我认为该项结果xml应该比较大,要读取映射文件啊,实际情况不是这样,不知道为什么?
Last time is :
62
Last time is :
85
相差比较大不知道为什么?
Total time :
2506
Total time :
2516
xml文件总体上慢了一点
读取100次的比较:
使用Annotations 的测试数据
使用Xml文件的测试数据
简要说明
Init time :
2437
Init time :
2422
和前面初始化差不多
Last time is :
438
Last time is :
484
有时间差
Total time :
2875
Total time :
2906
也是xml文件总体上慢了一点
插入100次的比较:
使用Annotations 的测试数据
使用Xml文件的测试数据
简要说明
Init time :
2453
Init time :
2469
和前面初始化差不多
Last time is :
469
Last time is :
656
有时间差
Total time :
2922
Total time :
3125
也是xml文件总体上慢了一点
从上面的三次对比中大家可以看到 初始化的部分几乎两者是一样的, 在数据操作上面 使用xml文件 总是比使用Annotations 慢一点.在我们只操纵一个只有几个属性的小持久化类的操作中就有 几十毫秒的差距. 几十毫秒在计算机中算不算很大 大家应该都知道,我就不在多说了.
总结: 经过 xml 文件 和Annotations 的优缺点和 性能上的对比.现在使用那个作为你持久化映射策略.我相信大家都会正确选择的.