首页 > 技术文章 > iBatis核心框架浅析

icanth 2013-12-28 17:43 原文

1.1 iBatis配置与运行

1.dal 层的dao接口实现类通常会继承SqlMapClientDaoSupport。spring容器在初始化一个dao bean实例时,通常会注入两块信息DataSource(数据源)和sqlMapClient(主要是sql语句),这两块信息会封装到SqlMapClientTemplate。

2. 其中数据源的实例通常采用apache的开源项目dbcp。代码配置如下:

3. sqlMapClient

接下来就到了数据持久层的代码调用,所有的数据库DML操作(增、删、改、查)都是借助于SqlMapClientTemplate来实现。

1.2 SQL MAP引擎实现&数据库框架

1、SqlMapClient,仅是层SqlMapSessionImpl浅浅的薄纱。在SqlMapSessionImpl中以实现update为例:

会调用TransactionManager的doInTransaction方法:

2、TransactionManager通过JDBCTransactionConfig采用Bridge模式构建出JDBCTransaction

Java事务类型分成三类:JDBC事务、JTA(Java Transaction API)、和容器事务,JDBC事务通过java.sql.Connection实现。batis中transaction.getExcutor()返回依赖transaction的执行对象。在Excutor中调用JDBCTransaction.getConnection()返回的即是java.sql.Connection()。

3、Excutor

Excutor采用命令模式、依赖transaction对象,负责将Connection和MappedStatement组装到handler中执行insert、update等语句,SimpleExcutor、BatchExcutor等继承自该接口。

4、JdbcTrasaction中DataSource

DataSource,是Connection的工厂类,用于维护一个连接池。ibatis中有几种类型:SimpleDataSource,C3P0。

SimpleDataSource实现中包含两个代理线程池:idleConnectionsPool和activeConnectionsPool,并利用Proxy模式实现Connection访问远程数据库,通过popConnection和pushConnection

来申请和释放一个Proxy。申请时,对于ideal为空、active已满的情况,循环判断是否有栈底的Proxy已超过checkNum,超过设置阈值则执行autoCommit()、或rollback()并释放资源。同时注意检查Proxy链接状态。Proxy类为PooledConnection,利用InvocationHandler实现代理:

 1 class PooledConnection implements InvocationHandler {
 2 
 3  public Object invoke(Object proxy, Method method, Object[] args)
 4 
 5      throws Throwable {
 6 
 7    String methodName = method.getName();
 8 
 9    if (CLOSE.hashCode() == methodName.hashCode() && CLOSE.equals(methodName)) {
10 
11      dataSource.pushConnection(this);
12 
13      return null;
14 
15    } else {
16 
17        if (method.getDeclaringClass() != Object.class) {
18 
19          // throw an SQLException instead of a Runtime
20 
21          checkConnection();
22 
23        }
24 
25        return method.invoke(realConnection, args);
26 
27    } // else
28 
29  } // invoke
30 
31 } // class

另外,C3P0是一个高效的开源JDBC连接池。Ibatis可以支持C3P0的配置。

推荐阅读