09 January 2014

你有使用 JPA 或 Hibernate 嗎?從 Hibernate 出來後,我個人花了很多時間學習,也對它的設計感到讚嘆不已,ORM 讓你用物件導向的方式思考 domain 邏輯,而不是從資料的觀點倒推回去。不過,這個世界變了。

過去在使用 Server Page 時 (jsp, freemarker, wicket 之類的),針對單頁的 Request,Hibernate 可以開啟一個共用的 Session,從頭用到尾。網頁越複雜,這項特性越有用,因為共用 Session 可以減少相同物件的查詢與建立。當然 Hibernate 複雜的 Session 狀態也是常見的錯誤來源,但在當時優點還是大於缺點的。

那麼現在呢?Server Page 已退出流行,新一代的需求是 Mobile Client、是 Single Page Web App。新的 request 的型態跟以往不同,每個都是小小的 restful request,它只做單一一件事,它的量級也很大,而且很快。Hibernate 的 session 這時似乎笨重了起來,有點多餘。

而另一股勢力 NoSQL 在一兩年前也是氣焰囂張的不得了,這氣勢今日削弱些了,但是大家已經開始習慣 可以不用依賴 SQL 的日子了。像我們公司就已經有兩三年的 Cassandra 經驗,現在就是依需求而決定要用哪一邊的技術。NoSQL 的使用例通常都不需 ORM。而 SQL 的我們也繼續用,但這一次我去掉 Hibernate 這一層。

移除 Hibernate 減少學習門檻,減少不必要的間接層級

去掉 Hibernate 後,我選擇 Spring 單純的 JdbcTemplate,而不是引進其他小型的 framework 代替 (例如 MyBatis)。我想要降低開發的技術門檻,想要讓程式碼直覺單純。Hibernate 引進了 1st level、2nd level cache、HQL 轉譯 SQL、還有那個 CGlib 在背後偷改 byte code。這些 間接的層級 是帶來了很多便利,但也讓問題變的更複雜。沒有幾年的 Hibernate 經驗是搞不懂那些奇奇怪怪的錯誤現象的。

不過只用 JdbcTemplate,就回到有點蠻荒時期了,那些過去只要一個 annotation 就能搞定的,現在需要重覆的打字打字再打字。雖然做起來很繁鎖,但我知道這是為了未來程式好懂好客製而付出的代價。現在我們的 DAO 層很單純,而且貼近資料庫操作,能在資料庫做完的就直接做完了,讓效能更好。不過我們也只是做做 bulk operation,並不會在資料庫裡寫 domain 邏輯、寫 store procedure。

沒了 ORM,缺點是 domain 物件弱化了。但我發現其實真的會 model 好物件關係的開發者並不多,雖然資料被 Mapping 成物件,但還是當做是資料在用。除了能力之外,這跟過短的開發時程有關,當然這也受領域影響,常見的 web 開發的確沒有很複雜的邏輯,不需要特化的物件模型來解決。

從最早人手一份 JdbcUtils,到 Hibernate 沸沸騰騰的黃金時期,而現在返璞歸真,回到純 SQL。我很想念 Hibernate 帶來的便利與完整的物件模型,不過我不後悔。