hibernate,mybatis,beetlsql 全面比較
这是我的一个综合评分。总共分为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#
posted on 2017-07-27 20:53 cynchanpin 阅读(4706) 评论(0) 编辑 收藏 举报