1. daozero是什么?它可以在哪方面帮助我?
*假设你具有使用spring的ibatis支持类作为持久层实现的实际编码经验(即时没有,学习spring和ibatis也应该不是件怎么难的事情)。
daozero是1个很小的spring java bean。可以到http://dao-zero.sourceforge.net下载。使用daozero可以减少基于 ibatis+spring的持久层代码数量,因为daozero会动态地替我们实现持久层接口。它不是1个spring中ibatis支持类的包装,而是用来直接替换掉我们手工编写的持久层实现代码的。使用daozero时,一旦我们完成了dao接口的定义(java interface),通常情况下,我们只需要再在spring context定义文件中声明类型(class)为daozero.ibatis.dao的bean,并且设置这些bean的targettype属性为已定义好的dao接口,然后这些daozero bean 就会在运行时为我们动态地生成实现了targettype的dao实现类,由这些实现类去调用ibatis api访问数据库。所以,不需要dao接口的实现代码了。
2. daozero的工作原理
daozero约定ibatis sql mapping xml文件中定义的statement的名字需要和dao接口(抽象类)的method的名字保持一致,而且,当前版本还要求statement的parameter的数量及首次出现顺序也必须要和dao接口(抽象类)的method的参数(形参)的数量及出现顺序保持一致,通过做出这些约定(应该不太难于遵守吧),daozero就可以确定如何把method被调用时传入的参数(实参)和statement的 parameter对应起来,于是就可以用这些传入的参数组成statement需要的parameter map,去调用ibatis api访问数据库。daozero是一个实现了org.springframework.beans.factory.factorybean 的bean,就是说它是可以产生bean的factory bean,而daozero factory bean产生的bean就是实现了dao接口的dao对象,这些dao对象负责调用spring的ibatis template的方法,例如queryforobject()、queryforlist()和update()等。这些dao对象也有足够“智能”,它们会依据method的返回类型推断出该调用queryforobject()还是queryforlist()(当前版本尚不支持queryformap)。 daozero factory bean是如何产生dao对象的呢?这要视其属性targettype是接口还是抽象类来定:如果targettype是接口,那么使用jdk标准的 proxy(java.lang.reflect.proxy)机制,由该proxy负责拦截下对该接口方法的调用;如果是抽象类,那么就使用cglib的enhancer.net.sf.cglib.proxy.enhancer)莱拦截下对该抽象类中抽象方法的调用,而将方法调用拦截下来后的处理则基本上一致。使用jdk proxy或cglib enhancer对性能的影响在数百纳秒(ns)这个数量级,因此对于大多数web应用来说相对于数据库sql执行是可以忽略不计的。
事实上daozero不得不hack了一些ibatis的代码,不得不把ibatis提供的一些接口强行转型(cast)到ibatis的内部实现类,原因在于ibatis似乎没有提供检索其statement元数据的方法,使得daozero不得不在代码中留下了一些坏味道。(所以,如果ibatis出现了大的版本改变,那么daozero这部分代码也不得不重新写。)
3. 用daozero代替原来的ibatis dao bean
假设我们有一个数据库表叫"account",表结构如下所示,
create table account (
userid varchar(80) not null,
email varchar(80) not null,
constraint pk_account primary key (userid)
);
public class account implements serializable {
private string userid;
private string email;
public string getuserid() { return this.userid; }
public void setuserid(string s) { this.userid=s; }
public string getemail() { return this.email; }
public void setemail(string s) { this.email=s; }
}public interface accountdao {
account getaccountbyuserid(string userid) throws dataaccessexception;
void updateaccount(account account) throws dataaccessexception;
list getusernamelist() throws dataaccessexception;
}import org.springframework.org.ibatis.support.sqlmapclientdaosupport;
public class accountdaoimpl extends sqlmapclientdaosupport implements accountdao {
public account getaccountbyuseridandemail(string userid, string email) throws dataaccessexception {
map params = new hashmap();
params.put( "userid", userid );
params.put( "email", email );
return gettemplate().queryforobject( "getaccountbyuseridandemail", params );
}
public int updateaccount(account account) throws dataaccessexception {
return gettemplate().update( "updateaccount", account );
}
public list getusernamelist() throws dataaccessexception;
return gettemplate().queryforlist( "getusernamelist", null );
}
<select id="getaccountbyuseridandemail" resultclass="account">
select * from account where userid=#userid# and email=#email#
</select>
<select id="getusernamelist" resultclass="java.lang.string">
select userid from account
</select>
<update id="updateaccount">
update account set email = #email# where userid=#userid#
</update>
<bean id="accountdao" class="accountdaoimpl">
<property name="sqlmapclient" ref="sqlmapclient"/>
</bean>
<bean id="accountdao" class="daozero.ibatis.dao">
<property name="sqlmapclient" ref="sqlmapclient"/>
<property name="targettype" value="accountdao" /> <!-- interface -->
</bean>
public abstract class accountdaoimpl implements accountdao {
public abstract int __updateaccount(account account) throws dataaccessexception;
public int updateaccount(account account) throws dataaccessexception {
// insert additional operation code here
return __updateaccount(account);
}
}<select id="getaccountbyuseridandemail" resultclass="account">
select * from account where userid=#userid# and email=#email#
</select>
<select id="getusernamelist" resultclass="java.lang.string">
select userid from account
</select>
<update id="__updateaccount">
update account set email = #email# where userid=#userid#
</update>
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器