`
zgd
  • 浏览: 8638 次
  • 性别: Icon_minigender_1
  • 来自: 广州
最近访客 更多访客>>
社区版块
存档分类
最新评论

[原创]Ibatis with MapBean

阅读更多
用了两年的Hibernate之后,对ORM深有感触。一方面,ORM可以令到我们从OO角度来思考数据,屏蔽了数据库的差异(其实 Hibernate被吹的最厉害就是那个分页,其实分页没什么技术含量,而且ROR都把分页从核心抽离了)。另一方面,性能问题,例如必须select才能update,必须select全部,必须update全部,cache带来的后遗症,javabean关联问题(一对多,多对一,多对多等), lazyload问题

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/
分享到:
评论
29 楼 yunsong 2008-02-02  
zgd 写道
用了两年的Hibernate之后,对ORM深有感触。一方面,ORM可以令到我们从OO角度来思考数据,屏蔽了数据库的差异(其实 Hibernate被吹的最厉害就是那个分页,其实分页没什么技术含量,而且ROR都把分页从核心抽离了)。另一方面,性能问题,例如必须select才能update,必须select全部,必须update全部,cache带来的后遗症,javabean关联问题(一对多,多对一,多对多等), lazyload问题

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/

有同感啊,我也在一个中型项目用了hibernate,但是在维护的时候不知不觉地好多地方都改成nateve sql 了,现在我们公司新的框架都用Ibatis 了,自己写sql,都在自己的掌握之中。
28 楼 freeman983 2008-02-02  
neptune 写道
hashmap用在复杂查询,查询结果比较乱的情况下比较好。但一般情况下最好还是使用pojo好一些.



hibernate在进行复杂查询的情况下一样可以直接得到一个Map的list:

select new Map(a.id as id,a.name as name,b.type as type) from A a,B b where

a.id=b.aId;
...
List mapList=query.list();
....

在jsp页面可以和使用普通的JavaBean一样的方式输出

<c:forEach items="${mapList}" var="m">
<tr>
<td>
     <c:out value="${m.id}"/>
</td>
<td>
     <c:out value="${m.name}"/>
</td>
<td>
     <c:out value="${m.type}"/>
</td>
</tr>
</c:forEach>
这样的处理也是很简洁的
27 楼 neptune 2008-02-02  
hashmap用在复杂查询,查询结果比较乱的情况下比较好。但一般情况下最好还是使用pojo好一些.
26 楼 freeman983 2008-02-02  
使用javaBean可以更直观的体现业务逻辑中的对象模型,使用HashMap可能会提升开发效率,但它无法直观的表现实际业务中对象模型,而且维护起来也不是那么容易了.
25 楼 laiseeme 2008-01-31  
好像sql2005就有rowcount这样的东西,hibernate的分页估计会好些
24 楼 laiseeme 2008-01-31  
现在试用hibernate,分页在sql2000里头的效率貌似不咋地
23 楼 ak478288 2008-01-31  
LZ跟我以前用的方式,思想一样啊
22 楼 galaxystar 2008-01-31  
不能具体抽象为POJO的,才使用HashMap!!!
21 楼 mingo 2008-01-31  
我们公司用iBatis,照样用到了POJO,很转啊,一堆setter和getter也没什么啊,搞个代码生成器就是了。相反用了HashMap,会增加很多手工劳动。
20 楼 liucjj 2008-01-30  
处理复杂的数据库关系,hibernate确实有点差,但可以从设计做些调整
19 楼 lggege 2008-01-30  
dingyuan 写道
所有的对象都为mapbean,怎么区分不同的对象?是user对象还是role对象?在域模型上也不能体现一对多,多对一的关系.


这个说的很在理.
LZ将所有理应展示的业务关系都去掉了,那代码可读性又在哪? 最终都变成了一个Map. 天,OO从何而谈.


引用
MapBean params = new MapBean("id",userId,"name",username,"sex",0,"online",true);


难道你写这么多"id", "name","sex","online" 这么易错的代码,你能称之为最佳实践吗?

iBatis的书写SQL功能还是很实用的.
当系统上线了,才知道,最容易错的只是SQL,这个时候的Patch Jar 是如此的简单,不用重编译,只要用WinRar将Map文件拿出来,修改好,放进去就可以发到前线.特别是一个系统多个版本时候,才知道这个有多便捷.

18 楼 hantsy 2008-01-30  
hibernate同样可以使用Map,它支持三种POJO, Map, DOM4J模型,一般都是用pojo
17 楼 dingyuan 2008-01-30  
所有的对象都为mapbean,怎么区分不同的对象?是user对象还是role对象?在域模型上也不能体现一对多,多对一的关系,通过一个对象获得它关联对象的id,通过id作为缓存的key去缓存里面查找,这种设计的确有利于sql的灵活性,但却失去了做缓存,将对象整体转载入缓存的意义
16 楼 剑事 2008-01-30  
这个方法起步的时候方便   以后就不方便了
15 楼 abcx 2008-01-30  
但是如果要做产品开发,我觉得用IBATIS就不好,比如主键生成,分页这些问题解决起来就麻烦。能做产品开发的一般都是精细设计,用一种ORM更适合,现在正在看JPA(toplink essential实现),还是不打算用Hibernate,它把简单的事情搞复杂了。
14 楼 abcx 2008-01-30  
IBATIS用了几个月,确实也不错,能够适应各种恶劣的环境,不管数据库设计得怎样,IBATIS都能胜任。用起来也很简单,会写SQL就行,没有什么诀窍。把SQL写在XML里面,很容易维护,肯定比把查询语句写在Java代码里面好。对于行业应用来说,一般情况下数据库都是确定的,就用Oracle,不考虑跨数据库的问题,所以可以用很多数据库提供的功能,IBATIS恰好可以使开发人员完全利用数据库。
13 楼 lgx522 2008-01-30  
曾经,我们以复杂为荣。
复杂意味着高努力、高智力、高薪水、高价格。

但其实我们面对的90%都是简单问题。于是复杂的技术与方案必将成为挥之不去的沉重负担,最终把我们压垮。
最后我们会发现,其实我们需要的也很简单,一如我们的客户。

有了Spring和Hibernate,大家免不了要声讨EJB;有了ActiveRecord,Hibernate也少不了挨批;甚至某些特定场景,我们会想起SQL,这下AR也变成鸡肋。

过于复杂的技术早晚都免不了被淘汰的。
12 楼 zgd 2008-01-30  
1314520ln 写道
看来你还没真正了解hibernate

一句话,也能证明你了解hibernate吗?呵呵

大家是来讨论的,不是撂一句话就走
11 楼 zgd 2008-01-30  
allenBen 写道
vaja 写道
我适用JDBCTemplate,也封装了一个类似MapBean的工具类,用起来挺方便的。

我也用过一次 , 在Java程序里直接使用SQL语句,最后SQL语句动则10多行,几十行。而且要慢慢数'?',一不小心数错了那就费了,对Hibernate,虽然我最初学就是学的Hibernate但是一直没在项目中用过所以没有发言权
Ibaties,如果开发的系统始终在一种数据库中使用的话,使用Ibaties的确是最方便控制粒度最细的框架选择。

这也是我没有使用JDBC Template的其中一个原因,要在sql里面写大量的问号
当然spring有提供NamedParameterJdbcTemplate

但是,JdbcTemplate、NamedParameterJdbcTemplate、SimpleJdbcTemplate之间完全不通用,也没有继承关系,后两者的实现远远没有前者完整,这令我非常烦躁
10 楼 1314520ln 2008-01-30  
看来你还没真正了解hibernate

相关推荐

    ibatis自动生成bean

    只需在配置文件ibatorConfig.xml 更改tableName="你的表名"即可自动生成全部。 记住更改jdbc路径和mysql-connector-java-5.1.6-bin.jar的路径。

    ibatis_with_memcached

    本项目"ibatis_with_memcached"就是关于如何将Ibatis与Memcached集成,实现高效的数据库缓存策略的实例。 Ibatis是一个基于Java的SQL映射框架,它允许开发者编写SQL语句并与Java对象进行绑定,从而避免了传统的JDBC...

    基于iBatis SQL Map的数据持久层实现应用研究.pdf

    在本文中,作者以物流系统开发为实例,介绍了基于iBatis SQL Map实现数据持久层的主要内容,这包括映射关系的建立、SQL Map配置文件的编写,以及SQL Map API的使用。 iBatis SQL Map的核心是基于XML配置文件的映射...

    ibatis SQL Map PPt

    **Ibatis SQL Map PPT 知识点详解** Ibatis,作为一个轻量级的Java持久层框架,以其灵活、易用的特点,在企业级应用中得到了广泛的应用。它将SQL语句与Java代码分离,提供了更直观的数据访问方式,极大地提高了开发...

    ibatis的sql-map dtd

    在Ibatis中,`sql-map`和`sql-map-config`是两个重要的XML配置文件,它们使用DTD(Document Type Definition)来定义其结构和规则。 DTD是XML文档类型定义,它定义了XML文档的合法构建块,包括元素、属性、实体等,...

    Spring与iBATIS的集成

    他们也阐明了怎样取得你已编写的SQL语句及把他们映射给iBATIS使用的Bean。最后,还讨论了iBATIS的优缺点,及为什么是这样的一种方式,即所谓的“在完全OR与JDBC之间的一个幽雅的折衷。” &lt;br&gt;就象Developer's ...

    ibatis中iterate的例子

    在iBatis中,`&lt;iterate&gt;`标签是一个非常实用的功能,它允许我们处理集合数据,如数组、List或Map等,进行循环遍历并生成动态SQL语句。下面我们将详细探讨`&lt;iterate&gt;`标签的用法及其示例。 `&lt;iterate&gt;`标签的主要...

    ibatis总结 ibatis ibatis ibatis ibatis

    - `applicationContext.xml`是Spring的主配置文件,它定义了Spring容器中的bean,包括对Struts、Ibatis等其他框架的配置,实现各组件间的依赖注入。 - `codelist.xml`则可能包含了全局共享的bean,如`...

    iBATIS框架源码剖析

    资源名称:iBATIS框架源码剖析内容简介:iBATIS是一种比较流行的ORM框架,本书全面介绍其结构体系和分析其源程序代码,该框架的核心包括两个组件,一个是iBATIS DAO,另一个是iBATIS SQL Map。本书分为三个部分,第...

    ibatis demo,ibatis例子,ibatis示例

    5. **参数映射**:Ibatis支持多种方式传递参数,如Map、POJO对象、注解等。例如,使用`@Param`注解可以指定参数名,或者在XML中使用`#{paramName}`来引用参数。 6. **结果映射**:结果映射允许我们将查询结果自动...

    ibatis电子书

    关于本文 本文讨论了iBATIS SQL Map最重要的特性。本文中没有提及的其他特性,可能以后不再支持或不久将会修改,并且修改时不作通告,因此最好不要使用它们。本文将随着iBatis SQL Map的修改而变更。如

    ibatis plugin用户指南

    1. **代码生成**:基于预设的Bean Template和SQL Map Template,插件可以自动生成Bean和SQL Map文件,大大提高了开发效率。 2. **自动完成**:在sqlMap Config文件中,插件能自动完成properties和sqlMap文件的编写...

    基于iBatis SQL Map的数据持久层实现应用研究 (2008年)

    介绍了iBatis SQL Map建立ORM机制的原理和特点,结合某物流系统的开发,给出了SQL Map建立ORM的主要内容,包括映射关系、SQL Map配置文件和SQL Map API等.实践表明,iBatis SQL Map的ORM实现技术非常方便、灵活,并较好地...

    ibatis源码,ibatis源码 ibatis源码 ibatis源码

    《深入解析iBatis源码》 iBatis,一个优秀的Java持久层框架,以其轻量级、灵活的特性在众多ORM(Object-Relational Mapping)框架中独树一帜。iBatis的核心在于它的SQL映射机制,它将数据库操作与业务逻辑解耦,...

    ibatis2.3.4.rar

    6. 参数映射和结果映射:Ibatis通过Map、POJO(Plain Old Java Object)等方式进行参数映射,将Java对象转换为SQL参数;结果映射则是将查询结果转换为Java对象,方便后续处理。 在实例中,你可以尝试以下几个步骤来...

    Spring MVC Ibatis Bean 根据mysql数据表——代码生成工具

    Spring MVC、Ibatis 和 Bean 是Java Web开发中的关键组件,它们构建了强大的后端架构。在实际项目中,为了提高开发效率,开发者通常会利用代码生成工具,将MySQL数据库中的数据表自动生成对应的Spring MVC ...

    iBATIS-DAO-2.3.4.726.rar_com.ibatis.dao_iBATIS dao 2_iBatis DAO_

    例如,`DynamicSqlMapClient`类支持动态SQL Map的执行,它可以根据传入的参数动态修改SQL语句,避免了大量的条件分支代码。 此外,iBATIS还提供了一些辅助工具,如`ParameterMap`用于管理SQL语句的输入参数,`...

    Spring+ibatis 保留ibatis事务的配置

    配置了JNDI数据源之后,接下来就是配置ibatis的`SqlMapClient` Bean,这个Bean负责读取ibatis的配置文件,建立与ibatis之间的桥梁。 ```xml &lt;bean id="sqlMapClient" class="org.springframework.orm.ibatis....

    iBATIS SQL Maps 开发指南

    SQL Map使用简单的XML配置文件将Java Bean映射成SQL语句,对比其他的数据库持续层和ORM框架(如JDO的实现,Hibernate等),SQL Map最大的优点在于它简单易学。要使用SQL Map,只要熟悉Java Bean,XML和SQL,就能使您...

Global site tag (gtag.js) - Google Analytics