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的配置。