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#
相关文章
相关标签/搜索