论坛首页 Java企业应用论坛

一种用动态proxy自动实现dao接口的减少代码的方法

浏览 31218 次
该帖已经被评为精华帖
作者 正文
   发表时间:2007-05-13  
我搞不清楚对dao-zero感兴趣的人主要是看这个帖子,还是http://www.iteye.com/topic/20477
所以这里我重发一下(希望没违反发帖规则)


--------------------------------------------------------------------------------------------

刚发布daozero 0.5。过两天我就会把相关文档更新好,不过看下面这些也足够了。

主要的变化是:

1.允许为某个method手工指定它使用哪个iBatis SQL statement。当然原来的自动指定还是在的。
  这样就可以做到允许dao interface里有同名的method了。
  譬如说一个userDao bean,它的dao interface是
public interface UserDao {
    List findUsers( String address );
    List findUsers( String address, Date registerDate );
    List findUsers( User conditionBean );
}

  在0.5版之前,是不允许同一个interface里存在同名的(重载的)method的。现在,我给daozero.ibatis.Dao增加了一个叫methodMap的新属性,这是个map,map的key是method的声明(称为signature),map的value是iBatis SQL statement的名字。
  对这个map的最方便的用法是把interface里method的声明直接拷贝到spring xml里,不过也不是非得如此,我尽量把对signature的parser做得了“聪明”些:只要signature能和其它method区分开来,譬如省略掉参数名字,省略掉返回类型,甚至全省略掉只留下个逗号(如果它的参数个数可以用于和其它method区分开来的话),怎么样写都可以。所以,拿List findUsers( String address, Date registerDate )来说,下面这些都是可能被接受的:
	List findUsers( String address, Date registerDate )
	findUsers( String address, Date registerDate )
	findUsers( address, Date registerDate )
	findUsers( address, registerDate )
	findUsers( String, Date )
	findUsers( , Date )
	findUsers( String,  )
	findUsers( , );

  另外,里头加上exception声明也没问题(会被parser忽略)。
  不过即使这样,还是推荐大家写全了,也许以后可以用参数类型和参数名字做出其它新功能来,譬如说可以用来去除iBatis XML里的statement的参数顺序和method的形参顺序必须保持一致这个限制。
  这个功能的实现方式实际上也可以用annotation来做,我准备在接下来的一个版本里加上annotation,同时现在这个做法也能用来保持对jdk1.4的兼容,
  具体使用的spring xml的例子是:
	<bean id="userDao" class="daozero.ibatis.Dao">
		<property name="sqlMapClient" ....../>
		<property name="targetType" value="UserDao"/>
		<property name="methodMap">
			<map>
				<entry key="List findUsers( String address )" value="FIND_USERS_BY_ADDRESS"/>
				<entry key="findUsers( String, Date )" value="FIND_USERS_BY_ADDRESS_AND_REGISTER_DATE"/>
				<entry key="findUsers( User )" value="FIND_USERS"/>
			</map>
		</property>
	</bean>


2.heaven建议可以判断一下返回值,如果是数组的话可以把 queryforlist的结果转成强类型的数组,这个现在做进去了。这些是自动的,大家直接用就是,改接口方法的返回值类型就可以,不需要动spring xml。
我还把这种结果的自动转换扩充了些,现在可以做到把iBatis返回的list自动转成List的子类型、Set的子类型、Iterator、Enumeration。
queryForObject返回的Object是java bean的话也可以被自动转换为别的java bean,daozero会自动判断去做两个java bean间属性的拷贝,不过这个功能可能没太大用处,做进去只是觉得挺有趣的。

3.从heaven的建议触类旁通,我把类型自动转换的想法也用到了处理传入的参数上:现在,对于update/delete/insert方法,如果传入的参数的类型是Collection或Iterator或Enumeration或强类型的数组,那么里面的元素将被提取出来依次用来调用ibatis,而且,如果daozero的属性batchMode是true的话,会调用startBatchMode()启动批处理模式,可能这样性能会好些。

4.改掉了个bug: zhouxuanyi发现的daozero.ibatis.AutoProxy里的m_dao就是null的问题;

5.现在,如果把daozero bean的属性printMethodMap设成true(缺省是false的),那么会把每个method对应到哪个sql statement打印出来,方便大家调试跟踪。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics