该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2008-01-29
Hibernate一直说,他生成的sql比一般程序员的要好,可以减少很多问题。但是,我倒是认为用Hibernate反而因为对程序员的要求更高导致更多问题。而且我现在认为,SQL才是王道,至少目前是。 于是在新项目中启用Ibatis,这一年来的使用感觉很不错,全程使用细粒度的SQL语句,虽然多写了很多SQL语句,但是感觉到项目在自己的控制中 我只用了Ibatis 40%不到的功能,可能大家会觉得不可思议。我没有用cache,没有用关联,没有用resultMap,甚至,连JavaBean也没有用 在大家都在讨论PO,VO,DTO的时候,我的系统里面一个JavaBean都没有 首先我问问,JavaBean是用来做什么的,存储数据,每一个PO,其实就约等于一个表里面的一行数据 我举一个真实一点的例子,一个user表 public class User { private int id; private String name; // 省略getter/setter一大段 } 不知道大家有没有用eclipse生成JavaBean getter/setter的痛苦,至少非常枯燥。整个JavaBean实现了什么功能?完全没有 好了我开谜底了,我用的是HashMap 什么,HashMap?是不是听错了 没听错,请问有什么事情是上面那个那么普通的JavaBean能做到的,而HashMap不能做到的呢 用HashMap没有具体属性的类型啊,那不是变成动态语言一样了,而且我要在JavaBean里面加逻辑怎么办 好吧,这是我想到的两个问题(如果你也有别的问题可以留意提出来) 首先,现在不同以前了,动态语言的优势慢慢提高了,像动态语言有什么不好,我从ROR里面学了很多不错的思想 其次是要加逻辑怎么办,这个问题,之前在Javaeye讨论充血模型还是贫血模型不可开交,最后还是没什么结论,目前还是一片贫血的情况,你可以翻一下你的项目里面的JavaBean,至少大多数的Bean都是没有意义的getter/setter。BO跟PO混杂在一起也很多人不建议的。至于逻辑,大可以写在util包里面,我都把整个model包去掉了,强化一下util不成么,呵呵 再次,数据库的列,跟JavaBean的属性两者,本来就是冗余的,如果我们修改数据库结构,就还要修改相应的JavaBean,或者影射文件。当然我这种做法更依赖数据库。另外,ROR的名字转换功能可以令到代码中的调用名字更好看一些,我觉得也不是非常有必要的实现 直接使用HashMap不太方便,尤其是类型转换上,于是我实现了一个MapBean的类,其实这个类很简单,关键是用HashMap代替JavaBean的思想 public class MapBean extends HashMap<String, Object> { public MapBean() { } public MapBean(Object... args) { put(args); } public int getInt(Object key) { return getInt(key, 0); } public int getInt(Object key, int defaultInt) { Integer i = (Integer) get(key); return i == null ? defaultInt : i; } public String getString(Object key) { return (String) get(key); } public String getString(Object key, String defaultValue) { String value = (String) get(key); return value == null ? defaultValue : value; } public Timestamp getTimestamp(Object key) { return (Timestamp) get(key); } public void put(Object... args) { for (int i = 1; i < args.length; i += 2) { put(String.valueOf(args[i - 1]), args[i]); } } public JSONObject toJson() { return JSONObject.fromObject(this); } public JSONObject toJson(String... keys) { xxx } public String toJsonString() { return toJson().toString(); } } 这个类主要是方便做类型转换,加入了getInt,getString等方法,另外因为我的系统里面大量使用了JSON,也有一些HashMap向JSON转换的辅助方法,还有一个特别处理过的put方法和构造器,有什么用呢,看下面的例子 MapBean params = new MapBean("id",userId,"name",username,"sex",0,"online",true); 如果你直接用HashMap实现以上功能,要写五行代码,就这个差别而已,呵呵 当然如果你用JavaBean的话,你也可以写一个对应的构造函数 接下来,我们在sql-map-config.xml中加入 <typeAlias alias="mapbean" type="xxxxxxx.MapBean" /> 就可以用mapbean的别称来引用这个类了 例如具体的SQL xml是这样的 <select id="getWorkManagerSystemRole" resultClass="mapbean" parameterClass="mapbean"> select * from work_manager_system_role where system_id=#system_id# and user_id=#user_id# </select> 其实我已经把Ibatis当成SQL wrapper来用了,我曾经评估过Spring的JDBC Template,不过功能始终差少少,或许以后我把JDBC Template再强化一下来代替Ibatis吧 http://weavesky.com/2008/01/29/ibatis-with-mapbean/ 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-01-29
头一次听到“Hibernate被吹的最厉害就是那个分页”
|
|
返回顶楼 | |
发表时间:2008-01-29
我适用JDBCTemplate,也封装了一个类似MapBean的工具类,用起来挺方便的。
|
|
返回顶楼 | |
发表时间:2008-01-29
我对LZ对Hibernate的其中几点看法表示认同,这也是我一直坚持用iBatis的原因,特别是在大型数据库应用上,原生SQL更能掌控,DBA对于SQL层面的优化,比Hibernate来得更彻底和高效。
|
|
返回顶楼 | |
发表时间:2008-01-29
缓存怎么办?
|
|
返回顶楼 | |
发表时间:2008-01-30
cnpollux 写道 头一次听到“Hibernate被吹的最厉害就是那个分页”
我的意思是说“屏蔽了数据库的差异”这一部分,被吹的最厉害就是那个分页 |
|
返回顶楼 | |
发表时间:2008-01-30
引用 另一方面,性能问题,例如必须select才能update,必须select全部,必须update全部,cache带来的后遗症,javabean关联问题(一对多,多对一,多对多等), lazyload问题
有些朋友对我这句话质疑,我不是不懂hibernate,这篇文章不是说hibernate的不是,所以我稍微带过了 select也可以字段lazyload,不过需要先强化javabean update有两种部分update的方法,一个是配置文件打开动态update 另一个是直接用hibernate3引入的update语法 但是,这些能算有实用价值吗 lazyload可以独立来批判 动态update也是hibernate所不建议的,至少不具有通用性 update语法会引发first level cache问题 关于hibernate的问题,迟点我专门写一篇文章来跟大家讨论 |
|
返回顶楼 | |
发表时间:2008-01-30
vaja 写道 我适用JDBCTemplate,也封装了一个类似MapBean的工具类,用起来挺方便的。
我也用过一次 , 在Java程序里直接使用SQL语句,最后SQL语句动则10多行,几十行。而且要慢慢数'?',一不小心数错了那就费了,对Hibernate,虽然我最初学就是学的Hibernate但是一直没在项目中用过所以没有发言权 Ibaties,如果开发的系统始终在一种数据库中使用的话,使用Ibaties的确是最方便控制粒度最细的框架选择。 |
|
返回顶楼 | |
发表时间:2008-01-30
dingyuan 写道 缓存怎么办?
说实在话,hibernate的缓冲也是比较鸡肋性质的 只有read-only cache是最有效的 而read-write cache是基本废掉的 nostrict-read-write效果比较好,但是不知道expire的点在哪里 也有可能因为我不会用,又或者后来hibernate改进了很多,会用的朋友出来指点一下 我认为,对entity的cache意义不大,因为多数entity都是易变的,expire问题会成为一个大问题 但是我使用hibernate的时候,也是手工用ehcache在mvc那里cache service gen出来的数据 现在用ibatis,也是原用这种方案 呵呵,缓冲问题,也是可以独立讨论的 |
|
返回顶楼 | |
发表时间:2008-01-30
hibernate不是不好,只是当你的项目做到一定程度的时候,就会碰上这样或那样的问题,而当你去解决这些问题的时候,你就会觉得,hibernate的实现已经渐渐被你废掉了。当然hibernate在一些范围里面很有用,尤其是你们的team有个hibernate的熟手,我的意思不仅仅是说很会用hibernate,而是曾经在项目中遇过hibernate的不足
例如,我在招聘的时候,如果看见简历上面写着熟悉hibernate,我就会问他,hibernate有什么缺点(而不是优点),能够说出一个framework的缺点,才是真正了解它 这贴不是讨论hibernate和ibatis的比较,跑题了呵呵 |
|
返回顶楼 | |