this is a extra element for clear the floated element
J2EE核心:iBatisDAO入门与进阶二
  • 12/31
  • 2008
J2ee核心 | Java 1951 次查看
  

DAO框架架构

  



  

由于有了一个可以运行的示例,让我们得以粗略了解DAO框架是如何运作的。在图2表示的顺序图中演示了DAO的工作方式:

  



  



  



  

  

2. DAO顺序图

  



  

在开始时,调用DaoManagerBuilder.buildDaoManager()并传入DAOMap.xml来初始化DAO框架。在这个方法中DAO框架会读取DAOMap.xml并且由此生成相应的DAOManager对象。这个对象包括了对支持的数据存储机制的描述。哪个接口会被实现,哪个是接口和存储机制结合的实现类?基本上这是和DAOMap.xml文件相等的 Java对象。

  



  

当有了DAOManager对象,可以从中得到ContactDAO接口的SQL Map实例。DAO框架会返回一个包装了实现类的DaoProxy对象。在本例子中将给SQLMapContactDAO返回一个DaoProxy对象。这个DaoProxy对象允许DAO框架截获调用商业方法。本例中,当调用 contactDAO.selectContact()时,DAO框架会截获这个调用并检查事务处理是否已经开始执行,如果没有,它将调用事务管理器中的startTransaction()创建一个新的事务处理调用。如果处理已经开始,DaoProxy对象会调用事务中的SQLMapContactDAO中的selectContact()方法。当selectContact()调用返回的时候,DaoProxy对象截获返回并提交给事务。

  



  

如果不希望事务在方法层上可见,或者希望在一个事务中调用多个不同的方法,则可在调用ContactDAO中的商业方法前调用daoManager.startTransaction(),然后在daoManager.startTransaction()执行完以后再提交商业方法。

  



  

那么现在剩下要关心的事情就是那个模块负责存储机制的初始化并传递控制给存储机制。在这个例子中,就意味着由哪个模块负责将SqlMapConfig.xml的路径传递给SQL Map框架并给它初始化。同样意味着哪个模块负责和SQL Maps框架进行实际的交互。DAO框架为每种存储提供了Template类,在工程中,可以从这个Template类中继承实例类,并只要自己的方法中编写商业事务逻辑。然后将控制传递给这个模板类,它将负责和存储机制的交互。在我们的例子中调用super.queryForObject("getContact",new Integer(contactId)),意味着SqlMapDaoTemplate将负责SQL Maps的初始化和与之交互。

  



  

初始化存储机制需要相关的一些信息,在例子中初始化需要SqlMapConfig.xml的路径,这个文件中包含驱动类的名字、JDBC URL、登陆信息之类的信息。这些特定的事务管理器需要的信息将会在DaoMap.xml文件中作为一个属性元素传递给管理器。下一节,我们将讨论DAO框架支持哪些事务管理器,每个管理器需要哪些初始化信息。

  



  

支持的存储管理机制



  

DAO框架提供了内置的对一些存储管理机制的支持。为了使用其中的一个内置的transactionManagers,需要做两件事情:

  



  

1.DAOMap.xml中增加一个元素来声明对存储管理机制的支持。

  

2.在生成DAO实现类的时候为transactionManager继承适当的Template类。

  



  

下面我们要研究内置transactionManagers并找出在应用程序中使用如何使用它们。

  



  

JDBC

  



  

如果不想使用任何存储框架,不想自己写JDBC代码,那么JDBC事务管理器是很好的选择。如果使用JDBC作为存储机制,则可以使用以下三种连接管理之一:

  



  

SIMPLE:如果要使用iBatis'自己的连接池实例,可以把SIMPLE作为DataSource元素的值。将通常的JDBC属性(DriverManager类, JDBC URL,等等)传入作为Properties。在iBatis在线文档中查看更多的连接属性。

  



  

清单5

  



  



  

  
  value="com.ibm.db2j.jdbc.DB2jDriver"/>

  
  value="jdbc:db2j:D:\cloudscape\wpsdb"/>

  
  value="db2admin"/>

  
  value="db2admin"/>

  
  value="true" />

  



  



  

DBCP:使用Apache DBCP作为连接管理。请查看DAO在线指导获得如何配置DBCP连接池的信息。

  



  

JNDI:当要使用应用服务器的连接池,那么要做的是提供连接池的JNDI名,DAO框架则使用这个名称获得一个连接。

  



  

清单6

  



  



  



  

  
  value="java:comp/env/jdbc/MyDataSource"/>

  



  



  

然后要建立一个类继承JdbcDaoTemplate.java来实现事务方法借口。在示例中,我们建立了JDBCContactDAO.java。在事务方法中,可以调用getConnection()向父类请求连接。因为我们没有使用任何存储框架,所以我们只能建立并执行我们自己的SQL请求。

  



  

清单7

  



  



  

public int updateContact(Contact contact) {

  try {

  Connection conn = getConnection();

  PreparedStatement updateStmt =

   conn.prepareStatement("UPDATE DB2ADMIN.CONTACT

  SET FIRSTNAME=?,LASTNAME=? WHERE CONTACTID=?");

  updateStmt.setString(1, contact.getFirstName());

  updateStmt.setString(2, contact.getLastName());

  updateStmt.setInt(3, contact.getContactId());

  return updateStmt.executeUpdate();

  } catch (SQLException ex) {

  throw new DaoException(ex);

  }

  }



  



  

使用JDBC transactionManager的时候,DAO框架会调用Connection 对象中的commitrollback方法来控制事务处理。所以事务会在Connection层被处理,而不参与全局事务处理。

  



  

JTA

  



  

如果项目是J2EE应用,那么使用应用服务器提供的连接池会更有利,因为它将比SIMPLE 或者DBCP 连接池有更好的性能。同样的,使用J2EE应用,RDBMS是唯一的处理源,除了RDBMS还需要包含JCAMQ Server等功能。因为不能在连接层开始和处理事务,而要特别的在全局事务处理时在一个UserTransaction对象中调用begin()commit()方法。所以对于这类请求,可以使用JTA 作为transctionManager,既可以向JNDI URL提供数据源连接池,也可以在里面包含UserTransaction对象。

  



  

清单8

  



  



  



  
  value="java:comp/env/jdbc/MyDataSource"/>

  
  value="java:comp/env/UserTransaction"/>

  



  



  

Hibernate

  



  

因为Hibernate是很常见的存储框架,iBatis DAO也提供了对它的支持。为了在项目中使用Hibernate,像下面那样在DAOMap.xml增加元素:

  



  

清单9

  



  



  



  
  value="net.sf.hibernate.dialect.Cloudscape"/>

  
  value="com.ibm.db2j.jdbc.DB2jDriver"/>

  
  value="jdbc:db2j:D:\cloudscape\wpsdb"/>

  
  value="db2admin/>

  
  value="db2admin"/>

  
  value="com.sample.contact.Contact"/>

  



  



  

同样的,需要建立一个DAO类继承HibernateDaoTemplate。在这个DAO内,可以通过调用getSession()方法来获得Hibernate Session对象的入口。

  



  

SQL MAP

  



  

请查看示例(在资源小节中)了解如何在项目中使用SQL Map存储框架的细节。

  



  

外部管理

  



  

外部的事务管理器允许事务处理在外部被DAO框架控制。这种行为有利于处理和非关系数据库数据源的交互。下一节,我们将讨论如何用DAO框架处理以XML文件作为数据源的情况。

  



  

部署xml事务Map

  



  

你可能也经常遇到这种情况:需要从xml中读取数据,而不是从RDBMS中读取,假想你正在从事一个银行项目,你并不能够直接接触到银行的数据库,所有的用户信息暂时都会通过一个XML文件传输给你,你必须使用这个XML文件进行开发,开发完毕再部署到真正的使用RDBMS的环境中,

  

这样的话,你需要做一下改变:

  



  1. DAOMap.xml 中增加对外部的transactionManager 的支持。

  



  

2. 新建一个XMLContactDAO.java文件:

  



  

清单10

  



  

public class XMLContactDAO implements ContactDAO {

  public static final String

  CONTACTXMLNAME = "c:\\Contact.xml";

  public XMLContactDAO(DaoManager manager) {

  super(manager);

  }

  public int insertContact(Contact contact) {

  HashMap contactMap = loadChanges();

  if (contactMap.get(new Integer

  (contact.getContactId())) == null)

   contactMap.put(new

  Integer(contact.getContactId()), contact);

  saveChanges(contactMap);

  return contact.getContactId();

  }

  public Contact selectContact(int contactId) {

  HashMap contactMap = loadChanges();

  return (Contact) contactMap.get(

   new Integer(contactId));

  }

  public HashMap loadChanges() {

  HashMap contactMap = null;

  try {

   XStream xstream = new XStream(new DomDriver());

   xstream.alias("contact", Contact.class);

   contactMap =

  (HashMap) xstream.fromXML(

   new FileReader(CONTACTXMLNAME),HashMap.class);

  } catch (FileNotFoundException e) {

  e.printStackTrace();

  return new HashMap();

  }

  return contactMap;

  }

  public void saveChanges(HashMap contactMap) {

  try {

   XStream xstream = new XStream();

   xstream.alias("contact", Contact.class);

   xstream.toXML(contactMap,

  new FileWriter(CONTACTXMLNAME));

   } catch (IOException e) {

   e.printStackTrace();

  }

  }

  }



  



  

这个例子中,XMLContactDAO实现了ContactDAO事务接口。因为我们使用了一个EXTERNAL事务管理器,所以不能使用任何已经存在的Template类。在我们的类中,我们使用XStream框架新建了两个简单的方法――loadChanges()saveChanges()――实现对XML文件的读写。XStream是一个开源框架,实现将一个XML文件看作一个对象来读取,将对象保存为XML文件的功能。

  



  

结论

  



  

当今,有很多新的存储框架出现。这对于一个程序员既有好处也有坏处。好处是有更多的选择余地。坏处是因为你必须作出一个选择,更糟糕的是不得不在项目开始的时候就选择一种框架,这就意味着你可能不能完全清楚的了解项目的需求,或者不能完全确信这种框架是否能完全满足项目的需求。DAO是一种容易使用并且功能强大的框架能够处理存储机制的改变。你在前期作出了付出,但是它肯定会在最后对你有帮助的。