hibernate,mybatis,beetlsql 全面比較

這是個人一個綜合評分,總共分爲12個單項,每一個單項最高5分,最低0分。注意,評價只包含這些軟件提供的標準功能,不包含第三方提供的功能,如代碼生成等。java

 

開發效率

hibernate  能獲取數據庫metadata,所以簡單的sql操做,如插入,更新,刪除,翻頁等,均可以自動完成。但由於概念複雜,常常會致使開發人員會寫sql,能寫java,但不會寫hibernate狀況出現(關係配置或者hql),致使開發效率反而下降。web

 

 

 

session.save(user);
String hql= "from bank.Person person where person.id.country = 'AU' "
Query query = sessin.createQuery(hql);



mybatis  必須手工寫sql,效率較低,有第三方工具能自動生成才勉強提升了開發效率

beetlsq l 一樣具備hibernate 的功能,但不要求配置或者annotation。因此認爲開發效率比hibernate高,是由於beetlsql 自己使用不容易出錯,不像hibernate那樣概念複雜,容易使用錯誤,致使實際開發速度下降. 在寫sql文件的時候,基於MD+beetl的也比myabtis 的xml 要快不少. spring

 

sqlManager.save(user);
List<User> list = sqlManager.select("user.queryMaxAgeUser",User.class,paras);
//or UserDao是一個開發者定義的接口,經過代理實現DAO
UserDao dao = sqlManager.getMapper(UserDao.class);
List<User> list  dao.queryMaxAgeUser(paras)

 

 

跨多種數據庫

hibernate  支持幾乎全部數據庫,經過自動生成的sql(插入,刪除,翻頁等),hql,來完成跨數據庫操做,但對於數據庫之間確實不一樣地方,hibernate無力處理,因此只有4分
mybatis  幾乎沒有考慮過跨數據庫功能,配置文件裏能夠經過if標籤來作判斷,但這種技術雞肋的很。
beetlsql ,目前支持Oracle,Mysql,Postgres,SQLServer,SQLLite,H2。一樣提供了自動生成sql完成插入,刪除,翻頁等跨數據庫的功能,beetl腳原本完成一些跨數據庫操做。另外,beetlsql獨立管理sql文件,sql放在根目錄下,特定數據庫sql放在以數據庫命名的子目錄下。若是數據庫sql確實有同樣地方,能夠用特定數據庫sql覆蓋默認的sql。sql

 

 

 

 

維護性

hibernate  : hibernate本生複雜性致使了維護比較難。對於一些簡單的重構,hibernate代碼不須要改動。對於複雜的sql(hql)改動,hibernate比較費勁
mybatis  :能夠適應複雜的sql改動,但表重構等,必須修改mapper 配置文件裏的sql。
beetlsql : 同時具有hibernate 和 myabtis 在維護性方面的優勢。支持重構,支持代碼外維護sql。 beetlsql的md格式使得維護sql像讀文檔同樣。同myabtis同樣,支持將sql文件的sql語句自動映射成dao方法。數據庫

 

 

 

QQ截圖20160217182303.png

 

 

系統啓動耗時

hibernate  :啓動須要加載數據庫的metadata,加載pojo,加載配置文件,而後校驗等操做,啓動很耗時
mybatis  : 須要作一個基本的配置文件加載,以及各個mapper文件加載,系統第一次訪問的時候會慢
beetlsql :只簡單的加載了數據庫的metadata,不作任何校驗,啓動幾乎不消耗時間api

 

 

 

 

錯誤提示

hibernate  因爲本生ORMapping的複雜性.因此提示也很複雜。另外不管是xml配置仍是annotation配置,若是有出錯提示,也很難明白錯誤提示意思。HQL 也是這樣,錯誤提示也並不理想
mybatis  : myabtis 錯誤提示最難搞懂,由於他基於xml解析和ognl 表達式都不是他本身的,因此咱們會看到各類莫名其妙的提示。

以下,原本應該是resultType,但寫成resultMapsession

 

 

 

<select id="getGrantCount" resultMap="Integer"  parameterType="Map">


錯誤提示儘管能夠理解,但很是不直觀,沒有告訴你哪行錯了,你只能配置文件全部地方纔能排查這個手誤mybatis

 

Caused by: java.lang.IllegalArgumentException: Result Maps collection does not contain value for cn.xxx.IGiftStatisticCacheService.Integer



beetlsql : 基於beetl模板語言,哪一個配置文件哪行錯了,錯誤緣由是什麼,提示的很是清楚,並且是中文的app

 

 

以下一個sql配置,if語句多了一個d框架

 

 

 

select * from User where 1 =1  
@if(isNotEmpty(age)d){
and age = #age#
@}

 

 

 

錯誤提示以下

 

>>11:14:10:缺乏符號(PARSER_MISS_ERROR):d 位於2行 資源:user.queryUser_page
多餘輸入 'd' 指望 RIGHT_PAR
1|select * from User where 1 =1
2|@if(isNotEmpty(age)d){
3|and age = #age#
4|@} 

 

 

模型支持

hibernate ,只支持pojo,並且因爲有關係約束,致使開發不夠快捷
mybatis  :pojo和map都支持,map支持能夠快速支持一些小的功能開發
beetlsql :pojo和map都支持,另外混合模型,使用較少的pojo完成大量的查詢操做而無需爲模型添額外的屬性,所以模型支持比myabtis要好。

 

 

 

List<User> list = sqlManager.select("user.queryXXX",User.class,paras);
List<Map> list = sqlManager.select("user.queryXXX",Map.class,paras);
//若是user繼承了Tail接口,支持混合模型.以下例子能夠經過user.get("roleName ") 訪問角色名,這對於web項目來講,很好用
List<User> list = sqlManager.excute("select u.*,r.name  roleName from user u,role r ... ",User.class,paras);

 

 

學習曲線

hibernate  毫無疑問最難掌握的是hibernate,這是公認的,他的彆扭之處是明明就是個sql 操做,非要讓開發人員先轉成對象,而後再轉成sql(實際上,sql語言已經屏蔽了操做數據庫的複雜性了),看看hibernate有多少書和文檔就知道他的複雜性
myabtis : 很簡單,除了寫mapper文件,可能須要學一下怎麼寫,但大概也就3-5天時間。myabtis做者當時的出發點也是寫一個「不要一本書來講明的dao工具」,他作到了,但作的還不夠好。
beetlsql : API僅僅在SQLManager裏,一看就明白。sql文件採用md格式,去除了xml那種繁瑣,而且使用beetl做爲模板語言,很是簡單,1天就能徹底掌握。 對於數據庫這種訪問技術來講,本不該該出現所謂的「磚家」,但hibernate有,這是不正常的。因此,hiberante評分最低,beetlsql最高。

 

 

 

 

對DBA友好

hibernate  : 此工具是仇視DBA的,天然DBA也不喜歡hibernate。在這就不談了。
myabtis :sql文件單獨管理,採用xml方式,相對友好,但xml方式過於繁瑣了,像常見的"<" 符號,myabtis不得不專門處理
beetlsql : sql 既能夠出如今代碼裏,也能夠在sql文件裏,因爲採用md+beetl 格式,比myabtis更好,DBA看beetlsql的sql文件,就像閱讀文檔同樣

 

 

 

 

與其餘工具友好

hibernate  :因爲是採用容器管理bean,所以在容器裏使用第三方工具,和容器外使用第三方工具,效果不同,好比hibenate獨有的Open Session In View 問題,還有 Session Has Closed ...
myabtis :無容器管理,因此怎麼用都順手
beetlsql :同myabtis,對其餘工具很友善

 

 

 

 

性能

沒有具體比較過,但考慮三者工具都涉及到sql模板解析,MetaData 獲取和分析,ResutlSet 的Mapping操做,java反射等,所以,性能差很少。我將在之後給出具體性能對比。再考慮到數據庫操做,dao基本上能夠忽略不計,因此性能都給予5分

 

 

 

 

數據庫主從支持

hibernate  : 不支持,須要藉助第三方路由中間件
myabtis : 支持,但須要作一些簡單的編碼,以切換數據源
beetlsql :支持數據庫主從配置,無需開發人員編碼。beetlsql默認根據sql是查詢仍是更新決定去主從庫,也能夠根據事務決定數據庫主從,如只讀事務就去從庫。beetlsql 既能適合一個初創項目,也適合項目飛速發展的巨大用戶量狀況。固然,超大用戶量,這就超出了beetlsql的功能了。

 

 

 

 

OR Mapping

hibernate  : 實體,關係都經過配置完成OR Mapping,包含了一對多,多對多,繼承等各類關係的實現。但正如我在一篇文章裏吐槽過OR Mapping那樣,儘管hibernate此項作的很是好,但沒什麼用。
myabtis : 實體,關係也經過配置來完成,但由於這是後期加的功能,因此用的並很差
beetlsql :支持實體映射,不支持關係映射,但支持關係映射查詢,支持一對一,一對多,多對多的查詢和懶加載

 

 

 

 

BeetlSQL一分鐘介紹

因爲beetlsql 是個新工具,因此簡單用一個例子說明beetlsql

//初始化部分,經過跟框架結合,如經過spring ioc直接注入SqlManager

 

 

 

MySqlStyle style = new MySqlStyle();
MySqlConnectoinSource cs = new MySqlConnectoinSource();
SQLLoader loader = new ClasspathLoader("/org/beetl/sql/test");
SQLManager sql = new SQLManager(style,loader,cs,new DefaultNameConversion(), new Interceptor[]{new DebugInterceptor()});

 

//直接使用sqlmanager 的api操做
User user = ....;
sql.insert(user);
User query = new User();
query.setStatus(1);
List<User> list = sql.template(User.class,query);
// 查詢user.sql 文件的mySelect sql模板
List<User> list = sql.select("user.mySelect",User.class,query) ;



beetlsql 也封裝了SqlManager,提供了dao 接口

 

 

 

public interface UserDao extends BaseMapper<User> {

public User findById(@Param("id") Integer id);
public int getCount();
public void setUserStatus(User user);
public Integer setAge(@Param("id") Integer id,@Param("age") Integer age);

 

}

而後,在業務邏輯裏能夠這麼使用,使得dao更容易維護

 

 

UserDao dao = sql.getMapper(UserDao.class);
dao.insert(user);  //使用BaseMapper 內置的方法
dao.setAge(12, 18); // 調用user.sql文件裏的 setAge sql模板



user.sql 是一個md格式文件

 

setAge
===
* 更改用戶年紀
update user set age = #age# where id=#id#
相關文章
相關標籤/搜索