<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Vincent

    Vicent's blog
    隨筆 - 74, 文章 - 0, 評(píng)論 - 5, 引用 - 0
    數(shù)據(jù)加載中……

    Hibernate Annotations 實(shí)戰(zhàn)(二)

    -- hbm.xml 與 Annotations 性能比較

    任何獲得Matrix授權(quán)的網(wǎng)站,轉(zhuǎn)載請(qǐng)保留以下作者信息和鏈接:
    作者:icess(作者的blog:http://blog.matrix.org.cn/page/icess)
    關(guān)鍵字:Hibernate Validator

    我在前面一篇文章<Hibernate Annotations 實(shí)戰(zhàn)-- 從 hbm.xml 到 Annotations>:

    中,有很多開(kāi)發(fā)者在談?wù)撝刑岬?有沒(méi)有必要從 hbm.xml 往 Annotations 上轉(zhuǎn)移. 那么在這篇文章中我們就來(lái)討論一下 hbm.xml 與 Annotations的優(yōu)缺點(diǎn),看看那種情況最適合你.

    首先,討論一下 xml 配置文件的優(yōu)點(diǎn), 個(gè)人認(rèn)為主要優(yōu)點(diǎn)就是當(dāng)你改變底層配置時(shí) 不需要改變和重新編譯代碼,只需要在xml 中更改就可以了,例如 Hibernate.cfg.xml 當(dāng)你要更改底層數(shù)據(jù)庫(kù)時(shí), 只要更改配置文件就可以了.Hibernate會(huì)為你做好別的事情.

    那么xml的缺點(diǎn)呢,個(gè)人認(rèn)為有以下幾點(diǎn):

    • 描述符多,不容易記憶,掌握 要深入了解還有看DTD文件

    • 無(wú)法做自動(dòng)校驗(yàn),需要人工查找

    • 讀取和解析xml配置要消耗一定時(shí)間,導(dǎo)致應(yīng)用啟動(dòng)慢,不便于測(cè)試和維護(hù)

    • 當(dāng)系統(tǒng)很大時(shí),大量的xml文件難以管理

    • 運(yùn)行中保存xml配置需要消耗額外的內(nèi)存

    • 在O/R Mapping的時(shí)候需要在java文件和xml配置文件之間交替,增大了工作量

    其中第一 二點(diǎn) 借助于先進(jìn)的IDE 可能不是什么問(wèn)題. 但是對(duì)初學(xué)者還是個(gè)問(wèn)題 ^_^.

     

    下面我們看看 Annotations的 特性吧! 可以解決xml遇到的問(wèn)題,有以下優(yōu)點(diǎn)

    • 描述符減少。以前在xml配置中往往需要描述java屬性的類(lèi)型,關(guān)系等等。而元數(shù)據(jù)本身就是java語(yǔ)言,從而省略了大量的描述符

    • 編譯期校驗(yàn)。錯(cuò)誤的批注在編譯期間就會(huì)報(bào)錯(cuò)。

    • 元數(shù)據(jù)批注在java代碼中,避免了額外的文件維護(hù)工作

    • 元數(shù)據(jù)被編譯成java bytecode,消耗的內(nèi)存少,讀取也很快,利于測(cè)試和維護(hù)

    關(guān)于 映射文件是使用 hbm.xml 文件還是使用 Annotations 我們來(lái)看看2者的性能吧. 先聲明一下,個(gè)人認(rèn)為映射文件一旦配置好就不會(huì)在很大程度上改變了.所以使用xml文件并不會(huì)帶來(lái)很大的好處.如果你認(rèn)為 映射文件在你的項(xiàng)目中也經(jīng)常變化,比如一列String數(shù)據(jù) ,今天你使用 length="16" 明天你認(rèn)為 該數(shù)據(jù)的長(zhǎng)度應(yīng)該更長(zhǎng)才能滿足業(yè)務(wù)需求 于是改為length="128" 等等類(lèi)似的問(wèn)題 . 如果你經(jīng)常有這方面的變動(dòng)的話,下面的比較你可以不用看了 , 你應(yīng)該使用 xml文件 因?yàn)锳nnotations 無(wú)法很好的滿足你的要求.

    現(xiàn)在讓我們就來(lái)看看2者的性能比較吧.

    (說(shuō)明: 這里只是比較查找 插入 的時(shí)間快慢,沒(méi)有比較除運(yùn)行時(shí)間以外的其他性能,如 內(nèi)存占用量 等等)

    先來(lái)看看測(cè)試程序和配置.

    首先在 Hibernate.cfg.xml 文件中去掉了

    <property name="hibernate.hbm2ddl.auto">update</property>

    這一行, 因?yàn)樵谇懊娴膶?shí)驗(yàn)中以及建立了數(shù)據(jù)庫(kù)表了 不再需要更新了.如果你是第一次運(yùn)行該例子 還是要該行的.

    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();??//程序開(kāi)始時(shí)間
    ????
    ????Session?s?=?HibernateUtil.currentSession();
    ????long?mid?=??System.currentTimeMillis();??//初始化完畢的時(shí)間 (可能此時(shí)并沒(méi)有初始化完畢^(qū)_^)
    ????
    ????Transaction?tx?=?s.beginTransaction();????
    ????/********************測(cè)試讀取的代碼************************/
    ????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());

    ??? /********************測(cè)試讀取1次的代碼************************/
    ????Person?p?=?null;
    ????p?=?(Person)?s.get(Person.class,?1);
    ????System.out.println(p.getName());
    ????/*********************測(cè)試插入的代碼*************************************/
    ????/*
    ????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();?//測(cè)試結(jié)束時(shí)間
    ????System.out.println("String[]?-?start?time:?"?+?start);
    ????System.out.println("String[]?-?end?time:?"?+?end);
    ????System.out.println("Init?time?:?"?+?(mid-start)); // 打印初始化用的時(shí)間
    ????System.out.println("Last?time?is?:"?+(end?-?mid)?); //打印 數(shù)據(jù)操作的時(shí)間
    ????System.out.println("Total?time?:?"?+(end?-?start)); //打印總時(shí)間
    ?
    ?}
    }

    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;
    ??}

    }

    其他的代碼幾乎沒(méi)有改變:

    下面的每種類(lèi)型的測(cè)試都測(cè)試了3次以上, 取中間的測(cè)試時(shí)間.

    測(cè)試機(jī)器配置:

    CPU:? AMD Athlon (xp) 2000+

    內(nèi)存: 784880KB

    硬盤(pán): 三星 SP0812N

    讀取一次??的比較:(單位: 毫秒)

    使用Annotations 的測(cè)試數(shù)據(jù)使用Xml文件的測(cè)試數(shù)據(jù)簡(jiǎn)要說(shuō)明
    Init time : 2444Init time : 2431測(cè)試前我認(rèn)為該項(xiàng)結(jié)果xml應(yīng)該比較大,要讀取映射文件啊,實(shí)際情況不是這樣,不知道為什么?
    Last time is :62Last time is :85相差比較大不知道為什么?
    Total time : 2506Total time : 2516xml文件總體上慢了一點(diǎn)

    ?? 讀取100次的比較:

    使用Annotations 的測(cè)試數(shù)據(jù)使用Xml文件的測(cè)試數(shù)據(jù)簡(jiǎn)要說(shuō)明
    Init time : 2437Init time : 2422和前面初始化差不多
    Last time is :438Last time is :484有時(shí)間差
    Total time : 2875Total time : 2906也是xml文件總體上慢了一點(diǎn)

    插入100次的比較:

    使用Annotations 的測(cè)試數(shù)據(jù)使用Xml文件的測(cè)試數(shù)據(jù)簡(jiǎn)要說(shuō)明
    Init time : 2453Init time : 2469和前面初始化差不多
    Last time is :469Last time is :656有時(shí)間差
    Total time : 2922Total time : 3125也是xml文件總體上慢了一點(diǎn)

    從上面的三次對(duì)比中大家可以看到 初始化的部分幾乎兩者是一樣的, 在數(shù)據(jù)操作上面 使用xml文件 總是比使用Annotations 慢一點(diǎn).在我們只操縱一個(gè)只有幾個(gè)屬性的小持久化類(lèi)的操作中就有 幾十毫秒的差距. 幾十毫秒在計(jì)算機(jī)中算不算很大 大家應(yīng)該都知道,我就不在多說(shuō)了.

    總結(jié): 經(jīng)過(guò) xml 文件 和Annotations 的優(yōu)缺點(diǎn)和 性能上的對(duì)比.現(xiàn)在使用那個(gè)作為你持久化映射策略.我相信大家都會(huì)正確選擇的.

    測(cè)試后記: 經(jīng)過(guò)多次測(cè)試 感覺(jué)有時(shí)候很不穩(wěn)定 ,有的時(shí)候很穩(wěn)定不知道是測(cè)試有問(wèn)題還是別的問(wèn)題.大家可以自己測(cè)試一下. 有什么新的發(fā)現(xiàn) 請(qǐng)大家討論討論.

    posted on 2006-09-01 14:04 Binary 閱讀(349) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): Hibernate

    主站蜘蛛池模板: 亚洲av日韩av高潮潮喷无码 | 亚洲欧洲国产视频| 免费国产污网站在线观看| 亚洲欧洲一区二区三区| 农村寡妇一级毛片免费看视频| 四虎影视在线永久免费看黄| 羞羞网站免费观看| 免费v片视频在线观看视频| 国产大陆亚洲精品国产| 亚洲阿v天堂在线2017免费| 亚洲视频在线免费| 亚洲国产精品久久久天堂| 无码A级毛片免费视频内谢| 亚洲午夜在线电影| 三年片在线观看免费大全| 亚洲人成色4444在线观看| 麻豆国产入口在线观看免费| 日韩亚洲综合精品国产| 亚洲熟女乱综合一区二区| 免费一级毛片无毒不卡| 亚洲bt加勒比一区二区| 成人福利免费视频| 亚洲av乱码一区二区三区按摩| 免费女人18毛片a级毛片视频| 中文在线免费看视频| 亚洲国产一区二区a毛片| 手机在线免费视频| 午夜在线免费视频| 91亚洲va在线天线va天堂va国产| 最近中文字幕免费mv视频8| 特级毛片爽www免费版| 亚洲国产精品久久66| 免费人成视频在线| 男女拍拍拍免费视频网站| 亚洲蜜芽在线精品一区| 国产做床爱无遮挡免费视频| 伊人久久大香线蕉免费视频| 亚洲三级在线视频| 亚洲中文字幕无码一区二区三区| 5g影院5g天天爽永久免费影院| 亚洲av纯肉无码精品动漫|