比如考虑在iBatis: SQL Maps中的应用例子。这是一个Struts应用答应对一个关系表执行SELECT, INSERT, UPDATE和DELETE的SQL请求。在这个应用中,使用SQL Maps做持续性框架。现在我们要修改这个应用,将这个关系表储存在一个XML文件中而不是存在关系数据库中,或者使用Hibernate来实现SELECT请求,而用SQL Map来执行其他请求,因为Hibernate提供了对高速缓存更好的支持。这样的修改很难实现,或者即使我们能修改而实现了这个功能,也会是很混乱的解决方案。
对于这类问题更好的解决方法是建立一个ContactDAO接口,在这个接口中定义处理SELECT, INSERT, UPDATE, 和DELETE 请求的事务方法。然后根据不同的事务逻辑建立不同的类实现各个方法。所以可能会有一个类处理使用SQL Maps同关系表进行交互的情况,而另外一个类处理用XML文件存放关系表而不是关系数据库的情况,等等。在项目中,根据实际的需要从不同的ContactDAO中选择相应的实现。这种关系见图1:
图1. ContactDAO 接口及实现
iBatis DAO是由Apache主持的开源框架项目,主要目标是为了解决这类问题。它答应在工程中以DAO模式为基础建立应用。这就意味着可以建立一个XML文件,并声明XMLContactDAO.Java是ContactDAO的实现类,这个类知道如何从XML文件中读写数据。SQLMapContactDAO则知道如何用SQL Maps作为持续化框架与关系表进行交互。在工程中,假如向DAO框架提交一个需要XML的ContactDAO请求,框架则会返回一个XMLContactDAO对象。同样的DAO框架提供了唯一的接口处理事务治理,这个接口能实现与数据的存储方式无关。它同样考虑了底层连接治理细节和初始化存储框架。
这篇文章是关于如何一步一步的在项目中应用iBatis DAO框架的基础指导。我们将由如何把SQL Maps一文中的应用实例改为应用DAO框架入手。然后,我们要讨论DAO框架的构造。再下一步,我们关注事务治理是如何在DAO框架中得到支持的。最后一部分是关于如何建立自己的事务治理模块。
示例应用
首先,我们将SQL Maps一文中的例子改为应用DAO框架。
1. 将ibatis-dao-2.jar文件复制到WEB-INF/lib目录下。
2. 在Java源程序的目录里新建一个如下的DAOMap.xml文件
清单1:
"com.sample.contact.dao.sqlmap.SQLMapContactDAO"/
DAOMap.xml是发布iBatis DAO框架的配置文件。
3. 建立ContactDAO.java,如下:
单2:
public interface ContactDAO extends DAO {
public int insertContact(Contact contact);
public int updateContact(Contact contact);
public Contact selectContact(int contactId);
public int deleteContact(int contactId);
}
ContactDAO.java定义了用户和一个关系表进行交互所需要用到的所有事务处理方法。请注重到ContactDAO.java中的所有方法都将一个Contact对象作为参数,这是一个用来携带数据的数据传递对象。
4. 建立一个SQLMapContactDAO.java文件,如下
清单3:
public class SQLMapContactDAO extends
SqlMapDaoTemplate implements ContactDAO {
public SQLMapContactDAO(DaoManager arg0) {
super(arg0);
}
public int deleteContact(int contactId) {
return super.delete("deleteContact",
new Integer(contactId));
}
public int insertContact(Contact contact) {
Integer contactId =(Integer)super.insert
("insertContact",contact);
return contact.getContactId();
}
public Contact selectContact(int contactId) {
return (Contact)super.queryForObject("getContact",
new Integer(contactId));
}
public int updateContact(Contact contact) {
return super.update("updateContact",contact);
}
}
SQLMapContactDAO是ContactDAO接口的具体实现,它用SQL Maps作为存储治理机制。注重到我们并没有写任何代码来或者初始化SQL Maps,或得到一个连接,或者在类中标注一个事务的界限。相反,我们继续SqlMapDaoTemplate.java类,它帮我们处理下层的、反复的操作。我们在SQLMapContactDAO类中需要考虑的唯一的事情就是事务处理逻辑。
5. 修改ContactSelectAction.java类中的execute()方法,如下:
清单4:
Contact contactForm = (Contact) form;
Reader reader=
Resources.getResourceAsReader("DAOMap.xml");
DaoManager daoManager =
DaoManagerBuilder.buildDaoManager(reader);
ContactDAO contactDAO =
(ContactDAO) daoManager.getDao(
ContactDAO.class,"sqlmap");
request.setAttribute("contactDetail",
contactDAO.selectContact(
contactForm.getContactId()));
最后一步是修改ContactSelectAction类中的execute()方法,使它使用DAO框架。为了初始化DAO框架,我们需要一个为DAOMap.xml 预备一个Reader对象。iBatis框架为我们提供了方法Resources.getResourceAsReader()来读取资源。一旦有了Reader对象来读取DAOMap.xml,就能将它们读取至DAOManagerBuilder.buildDaoManager(),返回一个DaoManager实例,将来用于与DAO框架进行交互。从理论上来说,应该在项目启动的时候初始化DAO框架,在我们这个程序中,可以将这个模块放入Struts插件中,但是为了简化这个例子,我们将初始化模块放入execute方法中。
有了DaoManager实例后,可以调用相应的接口和存储实现类(在