- 描述符多,不容易记忆,掌握 要深入了解还有看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 如下:
/*
* created on 2005
* @author
*/
package test.hibernate.annotation;
import org.hibernate.session;
import org.hibernate.transaction;
public class test {
public static void main(string [] args) {
long start = 0;
long end = 0;
start = system.currenttimemillis(); //程序开始时间
session s = hibernateutil.currentsession();
long mid = system.currenttimemillis(); //初始化完毕的时间 (可能此时并没有初始化完毕^_^)
transaction tx = s.begintransaction();
/********************测试读取的代码************************/
person p = null;
for(int i = 1; i <= 100; i ++) {
p = (person) s.get(person.class, i);
system.out.println(p.getname());
}
system.out.println(p.getname());
/********************测试读取1次的代码************************/
person p = null;
p = (person) s.get(person.class, 1);
system.out.println(p.getname());
/*********************测试插入的代码*************************************/
/*
for (int i = 0; i < 100; i ++) {
person p = new person();
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[] - start time: " + start);
system.out.println("string[] - end time: " + end);
system.out.println("init time : " + (mid-start)); // 打印初始化用的时间
system.out.println("last time is :" +(end - mid) ); //打印 数据操作的时间
system.out.println("total time : " +(end - start)); //打印总时间
}
}
annotations 包中的person.java 如下
package test.hibernate.annotation;
import java.util.linkedlist;
import java.util.list;
import javax.persistence.accesstype;
import javax.persistence.basic;
import javax.persistence.entity;
import javax.persistence.generatortype;
import javax.persistence.id;
import javax.persistence.table;
import javax.persistence.transient;
/**
* person generated by hbm2java
*/
@suppresswarnings("serial")
@entity(access = accesstype.property)
@table
public class person implements java.io.serializable {
private integer id;
private string name;
private string sex;
private integer age;
private list list = new linkedlist();
// constructors
/** default constructor */
public person() {
}
/** constructor with id */
public person(integer id) {
this.id = id;
}
// property accessors
@id(generate=generatortype.auto)
public integer getid() {
return this.id;
}
public void setid(integer id) {
this.id = id;
}
@basic
public string getname() {
return this.name;
}
public void setname(string name) {
this.name = name;
}
@basic
public string getsex() {
return this.sex;
}
public void setsex(string sex) {
this.sex = sex;
}
@basic
public integer getage() {
return this.age;
}
public void setage(integer age) {
this.age = age;
}
@transient
public list getlist() {
return list;
}
public void setlist(list list) {
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 的优缺点和 性能上的对比.现在使用那个作为你持久化映射策略.我相信大家都会正确选择的.