突然發現園子里為EF和Dapper的事鬧翻了天。(學Java的同學大概就是Hibernate和MyBatis之爭了)
講到EF對Mysql的支持,我在一邊偷着樂:還好我用的是NHibernate,對Mysql的支持可好啦,哈哈……
咳咳,這樣做當然是不對的,應該批評。我檢討三秒鍾,先。
我看了文章,也看了評論(但沒看完)。老實講,我覺得三生石上只有一句話是站得住腳的:
真正出現問題的不是 Entity Framework,而是我們,好吧,就明說了吧:我們太想念 SQL 語句了!
其他的,嗯,已經有很多人說了很多了,我就不湊熱鬧了。
不知道大家還記不記得我以前說過:
雖然我們有C#這種面向對象的語言,但實際上我們很多開發人員仍然是“面向數據庫”編程。
為了避免引發更大的爭論,我必須首先聲明:
面向對象和面向數據庫並無優劣高下之分。
面向對象和面向數據庫並無優劣高下之分。
面向對象和面向數據庫並無優劣高下之分。
重要的事說三遍。
選擇Dapper,甚至ADO.NET拼SQL,本質上就是“面向數據庫”編程。什么意思呢?所有的開發過程是以數據庫為基礎的,整個系統的架構是以數據庫的庫表結構為依托的。當遇到一個業務邏輯的時候,首先想到的是這數據放在哪幾張表里的,用什么SQL語句把它們給取出來,然后才想着怎么把這些數據封裝成類……這就是我所謂的“面向數據庫”編程。
那么與之相對的,什么是“面向對象編程”呢?
忘掉數據庫,尤其是關系型數據庫,我以前講過,你可以想象成這數據最終是存放在XML文件里的、存放在NoSQL里的、存放在其他什么什么磁盤里面的。當然,最理想的,是有一個“對象數據庫”,所有的數據都是以對象形式存放的,數據與數據之間就是對象與對象的關系,有繼承有引用,都是Load出來.出來的。總之,SQL語句完全不管用。所以,遇到一個業務邏輯的時候,首先想到的就是這些數據存放在哪些對象里面,怎么加載這些對象……
明白了吧?這才是“面向對象”的思路!
哪里有什么表,哪里有什么SQL?我們眼里只有對象!萬物皆對象,阿彌陀佛……
但是,世上的事情啊,最怕就是這個但是!
沒有“對象數據庫”,只有“關系數據庫”啊?這是一個始終無法回避的問題:幾乎所有的企業級應用,都是以關系數據庫為存儲器的。這下就麻煩了,怎么辦呢?
面向對象的擁躉們,就推出了ORM(Object Relational Map),在“對象”和關系數據庫“表”之間做一個映射,希望能解決這個問題。大家一定要明白,ORM是O開頭的,其核心其要義,是把object映射成Relational的表,Object是第一位的。而不是很多同學那樣,把ORM當成一個SQL語句生成器或者SQL語言的封裝,其作用就是“不寫SQL”。不是這樣的,本末倒置了呀,同學!那么,從這個意義上講,Dapper就不算是一個ORM(不做定義上的爭論,大家理解意思就行),他就是一個理想的DBHelper而已。
相應的,EF作為一個沉重的ORM工具,就被嫌棄了。這是自然而然的,我不知道我說明白了沒有,當你的思維是“面向數據庫”的時候,ORM確實是一種負擔,不僅僅是因為它的“沉重”,更因為它遮蔽了SQL實現的細節:看不到SQL,我心里不踏實啊!還要特么的設個斷點查查log看看生成的SQL啥樣子的,這就憋屈了……
而且ORM在復雜對象映射、復雜查詢的時候,確實會出問題,現在這工具還不能說是完美。
那咋整呢?
我覺得這就是一個個人(或者團隊)的喜好問題了。
“面向數據庫”本身其實沒問題。基於數據庫基於表結構,CRUD,又怎么啦?回歸代碼的本質,也符合KISS(Keep It Stupid Simple)原則啊!不計其數的成功項目都這樣完成的,而且也一直良好運作。相反的,完全的“面向數據庫”設計架構的,崩了的項目也不少吧?
但是,我個人而言,更傾向於“面向對象”的思路和方向。主要有這么幾個原因:
- 不喜歡SQL。這恐怕是決定性的原因,尤其憎恨存儲過程,尤其尤其受不了那種幾百上千行的存儲過程,崩潰了一樣的感覺。“面向數據庫”的極致就是“存儲過程編程”,假如都走極端,相比較而言,“面向對象”的極致我覺得都能接受——就全部代碼見不着一行SQL嘛,沒啥。
- ORM在不斷的進步。EF我不熟,NHibernate5.0的很多新特性讓我真的是眼前一亮,最鼓舞人心的就是Colletion上進行Query() 可以生成SQL查詢而不用把整個collection加載進來。這是我期盼了不知多久的一個特性,太爽了!以前很多為了性能而做的walkaround就不需要了,代碼會非常的清晰。我相信,ORM工具以后會一直進步,直到無限接近於完美,或者誕生“對象數據庫”。“面向數據庫”就根本不需要BLL層。把數據從數據庫取出來,封裝成類,何必呢?多此一舉啊,完全是。就算要封裝,我覺得強類型的DataSet就完全夠用了。但DateSet這些已經涼了,說白了,“面向數據庫編程”已經就那個樣子了,能用,但沒啥發展了;但ORM,還有很多人很多公司在努力的完善,還有進步的空間。
- 太多太多的工具或手段是必須和“面向對象”配合的。比如說單元測試,我不知道其他人怎么玩的,反正我的單元測試是隔離了數據庫的,測試用的數據,直接new就OK了,又快又輕巧。混入了SQL語句或存儲過程,必須連着數據庫,這單元測試咋做?我還真不知道。另外的,領域驅動,“面向數據庫”也沒辦法玩,你和“領域專家”講表結構和SQL,人家會崩潰的。
- ORM保留了你在特殊情況下使用原生SQL的權利。實在不行的時候,還是可以自己寫SQL的呀!
差不多了,我覺得可以簡單總結一下,希望同學們:
- 能夠從戰略高度上理解“面向對象”和“面向數據庫”的區別;
- 明白ORM的不足,但要對ORM的發展抱有信心。
咳咳,這腔調越來越像老師了。是的,人人都是程序猿 已經開課很久了,今天是第18講,入門型普及型課程,有興趣的同學可以聽一聽,或者給周圍的新人宣傳宣傳,先謝了!