作者:江南白衣
上次FB的吹水摘錄:
除JDBC外的數(shù)據(jù)訪問(wèn)技術(shù)包括EJB,Hibernate,JDO,iBatis等,但凡是ORM的總要面對(duì)相同的困境,如果透明持久化的,苦惱就更多 --Java數(shù)據(jù)訪問(wèn)技術(shù)依然在緩慢跨越鴻溝,.Net社區(qū)的同學(xué)用不著眼熱心跳:
1.查詢語(yǔ)言--紛紛重回原來(lái)極想擺脫的sql,但實(shí)現(xiàn)得又不如SQL成熟。
因?yàn)镼ueryObject,Criteria API的可讀性太差,最后所有技術(shù)方案都回到它們?cè)瓉?lái)一力想擺脫的SQL的路上。而且,因?yàn)槭侵匦聜}(cāng)促設(shè)計(jì),都不如sql 的成熟,總有很多做不到的地方。像剛開(kāi)始的EJB QL,幾乎什么都做不了,而hibernate 3.0 HQL把h2的代碼拋棄了重新實(shí)現(xiàn)才達(dá)到相對(duì)滿意的水平。
2.積極載入和懶惰載入--不能如sql般每次隨需定制
ORM與jdbc訪問(wèn)的區(qū)別,就是以包含關(guān)聯(lián)對(duì)象的對(duì)象,而不是以sql自由定制的ResultSet,作為數(shù)據(jù)載入的主體。
積極載入策略在載入訂單對(duì)象時(shí),會(huì)接著載入顧客對(duì)象、產(chǎn)品對(duì)象,而如果產(chǎn)品對(duì)象又包含類別對(duì)象時(shí).....整個(gè)數(shù)據(jù)庫(kù)被拖了一小半出來(lái)。即使不玩連連看,clob對(duì)象的胡亂載入就夠頭痛了。
與此對(duì)應(yīng)的就是懶惰載入策略,比如EJB的初始版本,據(jù)聞每個(gè)屬性查詢一次數(shù)據(jù)庫(kù),數(shù)據(jù)庫(kù)往返次數(shù)多得嚇人。
ORM方案會(huì)讓用戶自行定義這兩種策略來(lái)達(dá)到平衡。一般默認(rèn)采用積極載入,在一對(duì)多關(guān)聯(lián)上定義lazy load,還有統(tǒng)一定義積極載入的層數(shù)。到了hibernate 3,更可以在列級(jí)別上定義lazy load。
問(wèn)題是,上述的定義都在hbm文件,每種對(duì)象的載入策略只能定義一次。而不能像jdbc那樣,根據(jù)不同的情況select不同的結(jié)果列。
順帶一個(gè)問(wèn)題是那些信息不完全對(duì)象,比如產(chǎn)品只有序號(hào)和名字,不帶其他信息時(shí),在一個(gè)純面向?qū)ο蟓h(huán)境里不好表示,hibernate提供的component方案也不是太好。
3.透明持久化--對(duì)POJO的一些臨時(shí)操作也會(huì)被持久化
因?yàn)槌志没峭该鞯模苋菀拙蜁?huì)誤用,對(duì)POJO進(jìn)行的一些臨時(shí)操作,一不小心就被保存進(jìn)數(shù)據(jù)庫(kù)中。再加上Session,事務(wù)的混亂,遠(yuǎn)遠(yuǎn)沒(méi)有用jdbc跑DML語(yǔ)句那么容易搞清楚發(fā)生的事情。
而且,不是每個(gè)程序員都能習(xí)慣新的透明持久化環(huán)境,都對(duì)所用ORM系統(tǒng)的持久化策略理解深刻。何況這些策略以及整合它們的框架如Spring,還經(jīng)常毫無(wú)提示的在升級(jí)時(shí)發(fā)生改動(dòng)!!!
所以,每個(gè)使用ORM的團(tuán)隊(duì),在項(xiàng)目過(guò)程里總會(huì)有鬧鬼的幾天......
上次FB的吹水摘錄:
除JDBC外的數(shù)據(jù)訪問(wèn)技術(shù)包括EJB,Hibernate,JDO,iBatis等,但凡是ORM的總要面對(duì)相同的困境,如果透明持久化的,苦惱就更多 --Java數(shù)據(jù)訪問(wèn)技術(shù)依然在緩慢跨越鴻溝,.Net社區(qū)的同學(xué)用不著眼熱心跳:
1.查詢語(yǔ)言--紛紛重回原來(lái)極想擺脫的sql,但實(shí)現(xiàn)得又不如SQL成熟。
因?yàn)镼ueryObject,Criteria API的可讀性太差,最后所有技術(shù)方案都回到它們?cè)瓉?lái)一力想擺脫的SQL的路上。而且,因?yàn)槭侵匦聜}(cāng)促設(shè)計(jì),都不如sql 的成熟,總有很多做不到的地方。像剛開(kāi)始的EJB QL,幾乎什么都做不了,而hibernate 3.0 HQL把h2的代碼拋棄了重新實(shí)現(xiàn)才達(dá)到相對(duì)滿意的水平。
2.積極載入和懶惰載入--不能如sql般每次隨需定制
ORM與jdbc訪問(wèn)的區(qū)別,就是以包含關(guān)聯(lián)對(duì)象的對(duì)象,而不是以sql自由定制的ResultSet,作為數(shù)據(jù)載入的主體。
積極載入策略在載入訂單對(duì)象時(shí),會(huì)接著載入顧客對(duì)象、產(chǎn)品對(duì)象,而如果產(chǎn)品對(duì)象又包含類別對(duì)象時(shí).....整個(gè)數(shù)據(jù)庫(kù)被拖了一小半出來(lái)。即使不玩連連看,clob對(duì)象的胡亂載入就夠頭痛了。
與此對(duì)應(yīng)的就是懶惰載入策略,比如EJB的初始版本,據(jù)聞每個(gè)屬性查詢一次數(shù)據(jù)庫(kù),數(shù)據(jù)庫(kù)往返次數(shù)多得嚇人。
ORM方案會(huì)讓用戶自行定義這兩種策略來(lái)達(dá)到平衡。一般默認(rèn)采用積極載入,在一對(duì)多關(guān)聯(lián)上定義lazy load,還有統(tǒng)一定義積極載入的層數(shù)。到了hibernate 3,更可以在列級(jí)別上定義lazy load。
問(wèn)題是,上述的定義都在hbm文件,每種對(duì)象的載入策略只能定義一次。而不能像jdbc那樣,根據(jù)不同的情況select不同的結(jié)果列。
順帶一個(gè)問(wèn)題是那些信息不完全對(duì)象,比如產(chǎn)品只有序號(hào)和名字,不帶其他信息時(shí),在一個(gè)純面向?qū)ο蟓h(huán)境里不好表示,hibernate提供的component方案也不是太好。
3.透明持久化--對(duì)POJO的一些臨時(shí)操作也會(huì)被持久化
因?yàn)槌志没峭该鞯模苋菀拙蜁?huì)誤用,對(duì)POJO進(jìn)行的一些臨時(shí)操作,一不小心就被保存進(jìn)數(shù)據(jù)庫(kù)中。再加上Session,事務(wù)的混亂,遠(yuǎn)遠(yuǎn)沒(méi)有用jdbc跑DML語(yǔ)句那么容易搞清楚發(fā)生的事情。
而且,不是每個(gè)程序員都能習(xí)慣新的透明持久化環(huán)境,都對(duì)所用ORM系統(tǒng)的持久化策略理解深刻。何況這些策略以及整合它們的框架如Spring,還經(jīng)常毫無(wú)提示的在升級(jí)時(shí)發(fā)生改動(dòng)!!!
所以,每個(gè)使用ORM的團(tuán)隊(duì),在項(xiàng)目過(guò)程里總會(huì)有鬧鬼的幾天......
這句說(shuō)到點(diǎn)子上了
這句是鉆牛角尖了。
hql 的提出是為了更好的可讀性。
別扭是不言而喻的
只能說(shuō)這是歷史問(wèn)題
要徹底解決估計(jì)還是要靠對(duì)象數(shù)據(jù)庫(kù)
所以SQL還會(huì)有很長(zhǎng)一段時(shí)間的歷史重任
我還是喜歡用SQL解決問(wèn)題,沒(méi)必要為了做OO而OO吧
-DHH
現(xiàn)在的orm產(chǎn)品好象都比較天真,更多的是設(shè)計(jì)者和吹捧者比較天真。rails成功不僅僅在于他的高效設(shè)計(jì),更在于設(shè)計(jì)者的實(shí)際不脫離現(xiàn)實(shí)
好的性能和好的結(jié)構(gòu)是矛盾的;
時(shí)間和質(zhì)量是矛盾的;
... 各種各樣的矛盾充斥著軟件開(kāi)發(fā)過(guò)程. 看不到這些矛盾,或者當(dāng)他們不存在的設(shè)計(jì)都是幼稚的設(shè)計(jì).
所以沒(méi)有所謂的最好實(shí)踐: 當(dāng)我覺(jué)得ORM脫離我的控制, 我就用JDBC; 當(dāng)單純的SQL滿足不了要求我就用存儲(chǔ)過(guò)程;當(dāng)Java搞不定時(shí)我就用JNI.
JDBC是解決JAVA與DBMS的最原始接口,性能也是最高的!!!!
當(dāng)我們使用ORM替代JDBC時(shí),我們是要付出代價(jià)的,在我的項(xiàng)目不使用沒(méi)有100%深入了解的開(kāi)源組件
不要搞的面向?qū)ο罅恕?huì)很難用的,同時(shí)還要支持SQL的查詢,可以映射到自己的實(shí)體。