這是我的一個綜合評分。總共分為12個單項。每一個單項最高5分。最低0分。
注意。評價僅僅包括這些軟件提供的標准功能,不包括第三方提供的功能,如代碼生成等。
開發效率
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方法。
系統啟動耗時
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#