hibernate,mybatis,beetlsql 全面比較


這是我的一個綜合評分。總共分為12個單項。每一個單項最高5分。最低0分。

注意。評價僅僅包括這些軟件提供的標准功能,不包括第三方提供的功能,如代碼生成等。

QQ截圖20160217182303.png



開發效率

hibernate    能獲取數據庫metadata。因此簡單的sql操作。如插入。更新,刪除,翻頁等。都能夠自己主動完畢。但由於概念復雜,常常會導致開發者會寫sql,能寫java,但不會寫hibernate情況出現(關系配置或者hql)。導致開發效率反而減少。

 

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 本身使用不easy出錯,不像hibernate那樣概念復雜,easy使用錯誤。導致實際開發速度減少. 在寫sql文件的時候,基於MD+beetl的也比myabtis 的xml 要快非常多.  

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。 

維護性

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,不做不論什么校驗,啟動差點兒不消耗時間 

錯誤提示

hibernate  因為本生ORMapping的復雜性.所以提示也非常復雜。另外不管是xml配置還是annotation配置,假設有出錯提示,也非常難明確錯誤提示意思。HQL 也是這樣,錯誤提示也並不理想 
mybatis  : myabtis 錯誤提示最難搞懂,由於他基於xml解析和ognl 表達式都不是他自己的,所以我們會看到各種莫名其妙的提示。 

例如以下。本來應該是resultType,但寫成resultMap 
<select id="getGrantCount" resultMap="Integer"  parameterType="Map">

錯誤提示雖然能夠理解,但很不直觀。沒有告訴你哪行錯了。你僅僅能配置文件全部地方才干排查這個手誤 
Caused by: java.lang.IllegalArgumentException: Result Maps collection does not contain value for cn.xxx.IGiftStatisticCacheService.Integer


beetlsql : 基於beetl模板語言,哪個配置文件哪行錯了,錯誤原因是什么。提示的很清楚。並且是中文的 

例如以下一個sql配置,if語句多了一個d

?
1
2
3
4
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 : 非常easy。除了寫mapper文件。可能須要學一下怎么寫,但大概也就3-5天時間。myabtis作者當時的出發點也是寫一個“不要一本書來說明的dao工具”,他做到了,但做的還不夠好。 
beetlsql : API只在SQLManager里,一看就明確。sql文件採用md格式,去除了xml那種繁瑣,而且使用beetl作為模板語言,很easy,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更easy維護 
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#


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM