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

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

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

    blog.Toby

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      130 隨筆 :: 2 文章 :: 150 評論 :: 0 Trackbacks
    ?

    轉載:轉載請保留本信息,本文來自http://www.matrix.org.cn/resource/news/381_Hibernate.html

    magicgod 昨天在他的blog上發布了一篇關于Hibernate的特點思考的文章。

    原文:

    想了很長時間hibernate的一些弱點
    1.對象與數據庫的映射,關鍵在于對象關系的映射,但是沒做到很理想,配置過多,控制復雜,另外還會出錯。其實本質在于對象不夠自由。

    2.事務處理。這點上更容易出問題,相對于各種各樣的事務管理器,要兼容是一個大問題,總歸在各種應用服務器上有很多問題。其本質在于創建了一個自我數據存取小環境,必然面臨各種兼容問題。

    3.HQL語言。建立對象查詢語言,類SQL,但是不同于任何一種SQL,調試環境復雜。本質在于創建了一種語言,增加學習成本。

    減化hibernate,將其退化成一個sql生成器,既可以保留原有的主要功能,又可以兼容各種應用服務器和數據庫服務器,另外還不需要學習HQL語言。

    只需要一系列的功能函數,作一下包裝,再根據不同數據庫生成不同的SQL即可,連數據庫類型都不用指定,因為從Connection中可以獲得數據庫類型屬性。

    假想中的API:

    public Object ResultMapObject(ResultSet rs,String xml) //一行映射單個對象,可以用XML綁定,也可以不用。

    public List SQLMapObjects(Connection conn,String []sqls,String xml)??//將一堆SQL映射成一個對象樹,可以用xml來描述綁定,也可以不用,僅使用ror方式的約定。

    借助JDBC和SQL可以構建整個數據存取層。

    映射單個對象的代碼,將一行記錄映射成單個對象。sql可以是任意的。


    ????Connection conn=DriverManager.getConnection(url);
    ????PreparedStatement ps = conn.prepareStatement(sql);
    ????
    ????ResultSet rs = ps.executeQuery();
    ????while(rs.next())
    ????{
    ??????user=(Users)ResultMapObject(rs);
    ??????//TODO 可以使用user
    ????}



    映射對象樹。


    ????/*
    ????sale_orders銷售訂單表
    ????sale_order_details銷售訂單細表
    ????products商品表
    ????product_catalogs商品類別表
    ????從sql中就可以分析出
    ????id是主鍵
    ????sale_order_details.sale_order_id===>sale_orders.id
    ????sale_order_details.product_catalog_id==>product_catalogs.id
    ????sale_order_details.product_id==>products.id
    ???? */
    ????String []sqls=new String []{
    ????????" select id, total_sum, memo, state, modify_date, creator, checker from sale_orders ",
    ????????" select id, sale_order_id, product_id, product_name, product_catalog_id, model, product_unit, product_amount, product_price, product_sum, memo from sale_order_details ",
    ????????" select id, name, catalog, model, price, unit, memo, createtime, state, code, productno from products ",
    ????????" select id, name, memo from product_catalogs"
    ????};
    ????//不帶XML映射的,但是無法得知一對一還是一對多還是多對多的關系,所以一律建成多對多關系。
    ????List l=SQLMapObjects(conn,sqls);
    ????/*
    ????l的結構:
    ????sale_orders[]
    ????????|-----sale_order_details[](sale_order_details.sale_order_id===>sale_orders.id)
    ????????????????|-----products[](sale_order_details.product_id==>products.id)
    ????????????????|-----product_catalogs[](sale_order_details.product_catalog_id==>product_catalogs.id)????????????????
    ???? */



    ????/*
    ???? 帶xml
    ???? */


    ????/*
    ????sale_orders銷售訂單表
    ????sale_order_details銷售訂單細表
    ????products商品表
    ????product_catalogs商品類別表
    ????從sql中就可以分析出
    ????id是主鍵
    ????sale_order_details.sale_order_id===>sale_orders.id
    ????sale_order_details.product_catalog_id==>product_catalogs.id
    ????sale_order_details.product_id==>products.id
    ???? */
    ????String []sqls=new String []{
    ????????" select id, total_sum, memo, state, modify_date, creator, checker from sale_orders ",
    ????????" select id, sale_order_id, product_id, product_name, product_catalog_id, model, product_unit, product_amount, product_price, product_sum, memo from sale_order_details ",
    ????????" select id, name, catalog, model, price, unit, memo, createtime, state, code, productno from products ",
    ????????" select id, name, memo from product_catalogs"
    ????};

    ????/*
    <?xml version="1.0"?>
    <MapObject>
    <!--類似hibernate的映射,但是更容易理解,而且可以省略字段映射-->
    ????<Object tablename="sale_orders" class="org.test.pojo.SaleOrder">
    ????????<OneToMany tablename="sale_order_details" class="org.test.pojo.SaleOrderDetail">
    ????????<!--主細表映射-->
    ????????????<ParentKey>id</ParentKey>
    ????????????<ChildKey>id</ChildKey>
    ????????</OneToMany>
    ????????<!--字段映射可選,一般是相同或根據ROR規則-->
    ????????<FieldMap>可選...</FieldMap>
    ????</Object>
    ????<Object tablename="sale_order_details" class="org.test.pojo.SaleOrderDetail">
    ????????<!-- 附加代碼表映射1對1關系 -->
    ????????<OneToOne tablename="products" class="org.test.pojo.Product">
    ????????????<ParentKey tablename="sale_order_details">product_id</ParentKey>
    ????????????<ChildKey tablename="products">id</ChildKey>
    ????????</OneToMany>
    ????????<FieldMap>可選...</FieldMap>
    ????</Object>
    ????<Object tablename="sale_order_details" class="org.test.pojo.SaleOrderDetail">
    ????????<OneToOne tablename="product_catalogs" class="org.test.pojo.ProductCatalog">
    ????????????<ParentKey tablename="sale_order_details">product_catalog_id</ParentKey>
    ????????????<ChildKey tablename="product_catalogs">id</ChildKey>
    ????????</OneToMany>
    ????????<FieldMap>可選...</FieldMap>
    ????</Object>
    ????<Object tablename="product_catalogs" class="org.test.pojo.ProductCatalog">
    ????????<FieldMap>可選...</FieldMap>
    ????</Object>
    </MapObject>
    ???? */

    ????String xml="...";
    ????//帶xml映射
    ????List l=SQLMapObjects(conn,sqls,xml);
    ????/*
    ????l的結構:
    ????sale_orders[]
    ????????|-----sale_order_details[](sale_order_details.sale_order_id===>sale_orders.id)
    ????????????????|-----products[](sale_order_details.product_id==>products.id)
    ????????????????|-----product_catalogs[](sale_order_details.product_catalog_id==>product_catalogs.id)????????????????
    ???? */



    當然類要事先寫好,這里就不詳細寫了。

    保存問題更嚴重,取出來用sql映射已經可以很好地解決了,基本上一個函數、一群SQL,加上少少的XML就可以表達清楚了,但是這不能解決保存對象的問題。

    假想中的保存API。

    public void saveObject(Connection conn, Object obj,String xml);??//保存單個對象,簡單地將對象擴展成sql,允許xml映射,也可以不映射

    public void saveObjects(Connection conn, List objs, String xml);??//將對象樹保存到數據庫

    上一篇取出的List或人工組合的List可以用saveObjects來保存,這個函數的任務就比較重了,因為沒有狀態,所以要判斷修改過非常麻煩。

    一種思路是在對象是增加屬性,然后由開發者維護,比如界面上是否修改很有可能是有狀態位的,這個狀態位就可以用起來,然后函數根據這個狀態位來判斷是否去更新。

    一種思路是從Class本身中就得知對象是否被改過,類似AOP,在修改的時候記錄一下,然后函數來判斷是否改過,然后組成SQL來更新。

    至于批量修改是強項,直接用SQL即可,學習SQL比HQL的成本要低,畢竟這么多年了。

    外圍實用函數的思考:基本上都針對SQL的生成,或數據庫函數的替換

    public String generateInsertSQL(DBType type,Object obj);//生成insert語句

    public String generateUpdateSQL(DBType type,Object obj);//生成update語句

    public String generateSelectSQL(DBType type,Object obj);//生成select語句

    總之這個函數工具箱的思路有這幾條:

    1.使用函數,而不是使用環境來代替JDBC或應用服務器。

    2.使用成熟的SQL,而不是自創語言,最多增加SQL預處理器,將一些函數轉成數據庫相關,簡單的文本功能。

    3.保持對各種環境的兼容性。對象是干凈的,當然如果用AOP就很難說對象干不干凈了,不過基本上應該適用于所有的環境中。

    缺點:由于沒有了環境,保存對象有點麻煩,用SQL來解決批量更新和刪除,必要時增加幾個SQL語句生成器即可。保存對象樹是一個大缺點,沒有非常好的辦法能夠將對象樹整個保存下來而且效率非常高,只有上面提到的兩種不太完美的辦法,這都是因為JVM沒有提供對象狀態的原因。

    不過這樣用函數的方法來解決多繼承的問題還是比較干凈舒服的,既可以動態,又可以靜態,隨心所欲,靈活性、效率和兼容性兼得。

    關注:
    magicgod的Blog
    Hibernate論壇

    對此,你有何看法?

    posted on 2006-03-25 11:26 渠上月 閱讀(256) 評論(0)  編輯  收藏 所屬分類: java tips
    主站蜘蛛池模板: 亚洲免费闲人蜜桃| 免费av一区二区三区| 国拍在线精品视频免费观看| 亚洲va久久久噜噜噜久久男同| 黄桃AV无码免费一区二区三区| jlzzjlzz亚洲乱熟在线播放| 国产97视频人人做人人爱免费| 国产成人精品亚洲2020| 无码区日韩特区永久免费系列| 亚洲国产日韩在线成人蜜芽| 久九九精品免费视频| 亚洲综合色婷婷在线观看| 成人性生免费视频| 青娱乐在线视频免费观看| 亚洲人成电影网站国产精品| 三级毛片在线免费观看| 无码乱人伦一区二区亚洲| 亚洲一级毛片免费观看| 亚洲人成色77777在线观看 | 久久99热精品免费观看牛牛| 亚洲综合自拍成人| 成人免费视频一区二区三区| 国产亚洲精品第一综合| 亚洲精品字幕在线观看| 日本三级2019在线观看免费| 亚洲av中文无码字幕色不卡| 中文字幕亚洲电影| 4虎1515hh永久免费| 欧美激情综合亚洲一二区| 亚洲人成网站在线观看播放| h在线观看视频免费网站| 色窝窝亚洲AV网在线观看| 亚洲精品~无码抽插| 国产精品1024永久免费视频| 一区免费在线观看| 日韩亚洲AV无码一区二区不卡| 在线免费不卡视频| 免费一区二区无码东京热| 亚洲人成在久久综合网站| 亚洲精品网站在线观看不卡无广告| 国产99视频精品免费专区|