ibatis源码简析.docx_第1页
ibatis源码简析.docx_第2页
ibatis源码简析.docx_第3页
ibatis源码简析.docx_第4页
ibatis源码简析.docx_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

ibatis3出来也很久了,但一直觉得不如旧版好用,发现spring对ibatis的支持相比hibernate也简单得多,于是简单分析了下ibatis的源码。我们知道应用程序里面使用ibatis 简单点就如下几句,com.ibatis.sqlmap.client.SqlMapClient sqlMap = null;java.io.Reader reader = mon.resources.Resources.getResourceAsReader(sql-config.xml);sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);我们从SqlMapClientBuilder.buildSqlMapClient着手,SqlMapClientBuilder中new了一个SqlMapConfigParser类来解析输入流信息,并最终实例化一个SqlMapClient返回public static SqlMapClient buildSqlMapClient(Reader reader) return new SqlMapConfigParser().parse(reader);1.SqlMapConfigParser类的解析废话不多,贴代码public class SqlMapConfigParser protected final NodeletParser parser = new NodeletParser(); private XmlParserState state = new XmlParserState(); private boolean usingStreams = false; public SqlMapConfigParser() addSqlMapConfigNodelets(); . . public SqlMapClient parse(Reader reader) try usingStreams = false; parser.parse(reader); return state.getConfig().getClient(); catch (Exception e) throw new RuntimeException(Error occurred. Cause: + e, e); . private void addSqlMapConfigNodelets() parser.addNodelet(/sqlMapConfig/end(), new Nodelet() public void process(Node node) throws Exception state.getConfig().finalizeSqlMapConfig(); ); 当调用parse时,主要执行了两步操作parser.parse(reader) 和return state.getConfig().getClient(),前者解析xml文档并将解析结果存储到state中,后者根据解析结果生成一个SqlMapClient实例返回.那NodeletParser和XmlParserState是怎么关联起来的呢?我们看到SqlMapConfigParser的构造函数中调用了一系列add*方法,这些方法主要向成员变量 NodeletParser parser中添加一些回调处理类, 当NodeletParser中解析完成后调用这些回调方法将结果存储到XmlParserState state以及state持有的config对象中.实际上XmlParserState持有一个SqlMapConfiguration config对象,并且此config早已生成好SqlMapClientImpl对象,最后将解析结果设置进去.SqlMapConfiguration对象生成了最主要两个类SqlMapExecutorDelegate和SqlMapClientImpl的实例.代码如下:public class SqlMapConfiguration private static final Probe PROBE = ProbeFactory.getProbe(); private ErrorContext errorContext; private SqlMapExecutorDelegate delegate; private TypeHandlerFactory typeHandlerFactory; private SqlMapClientImpl client; private Integer defaultStatementTimeout; public SqlMapConfiguration() errorContext = new ErrorContext(); delegate = new SqlMapExecutorDelegate(); typeHandlerFactory = delegate.getTypeHandlerFactory(); client = new SqlMapClientImpl(delegate); registerDefaultTypeAliases(); . 2.实现类SqlMapClientImpl SqlMapClientImpl对象一般系统只生成一个,那么此对象是怎么处理线程安全的呢? 首先我主要看一下源码中最主要的几个接口SqlMapSession,SqlMapClient,SqlMapExecutor,SqlMapTransactionManager, UML描述如下:SqlMapExecutor定义了CRUD等方法,SqlMapTransactionManager定义了跟事务相关的方法,SqlMapClient 接口和SqlMapSession接口都继承了SqlMapExecutor,SqlMapTransactionManager.只是SqlMapClient 增加了opensession等方法,SqlMapSession接口只增加了一个方法close(). 然后看实现类SqlMapClientImpl,我们看到此类此有一个委托类SqlMapExecutorDelegate和一个ThreadLocal对象 . public SqlMapExecutorDelegate delegate; protected ThreadLocal localSqlMapSession = new ThreadLocal(); public SqlMapClientImpl(SqlMapExecutorDelegate delegate) this.delegate = delegate; public Object insert(String id, Object param) throws SQLException return getLocalSqlMapSession().insert(id, param); . protected SqlMapSessionImpl getLocalSqlMapSession() SqlMapSessionImpl sqlMapSession = (SqlMapSessionImpl) localSqlMapSession.get(); if (sqlMapSession = null | sqlMapSession.isClosed() sqlMapSession = new SqlMapSessionImpl(this); localSqlMapSession.set(sqlMapSession); return sqlMapSession; . 显然ThreadLocal是存放各个线程的session,然后看SqlMapClientImpl的insert方法, 此方法实际上调用了session实现类SqlMapSessionImpl的insert方法.那么SqlMapSessionImpl类是怎么处理的呢? SqlMapSessionImpl实现了SqlMapSession,跟SqlMapClientImpl 有共同的实现接口SqlMapExecutor,SqlMapTransactionManager. 看源码可知此类与SqlMapClientImpl持有共同的委托对象SqlMapExecutorDelegate delegate.并且利用此委托对象实例化了一个sessionScope对象 ,然后对增删改查的调用均委托对象执行处理并传入这个跟线程绑定的sessionScope对象. public class SqlMapSessionImpl implements SqlMapSession protected SqlMapExecutorDelegate delegate; protected SessionScope sessionScope; protected boolean closed; public SqlMapSessionImpl(SqlMapClientImpl client) this.delegate = client.getDelegate(); this.sessionScope = this.delegate.beginSessionScope(); . public Object insert(String id, Object param) throws SQLException return delegate.insert(sessionScope, id, param); SessionScope类,由源码可知此类主要保存了了执行会话一些有关的东西 public class SessionScope private static long nextId; private long id; / Used by Any private SqlMapClient sqlMapClient; private SqlMapExecutor sqlMapExecutor; private SqlMapTransactionManager sqlMapTxMgr; private int requestStackDepth; / Used by TransactionManager private Transaction transaction; private TransactionState transactionState; / Used by SqlMapExecutorDelegate.setUserProvidedTransaction() private TransactionState savedTransactionState; / Used by StandardSqlMapClient and GeneralStatement private boolean inBatch; / Used by SqlExecutor private Object batch; private boolean commitRequired; private Map preparedStatements; . 3.委托类SqlMapExecutorDelegate 此类持有各种根据xml解析得来的sql信息(由前面介绍的SqlMapConfigParser中的回调类置入). 还持有一个事务管理器TransactionManager txManager和一个sql执行类SqlExecutor sqlExecutor,以及一些类型工厂 代码如下:public class SqlMapExecutorDelegate private static final Probe PROBE = ProbeFactory.getProbe(); private boolean lazyLoadingEnabled; private boolean cacheModelsEnabled; private boolean enhancementEnabled; private boolean useColumnLabel = true; private boolean forceMultipleResultSetSupport; private TransactionManager txManager; private HashMap mappedStatements; private HashMap cacheModels; private HashMap resultMaps; private HashMap parameterMaps; protected SqlExecutor sqlExecutor; private TypeHandlerFactory typeHandlerFactory; private DataExchangeFactory dataExchangeFactory; .public List queryForList(SessionScope sessionScope, String id, Object paramObject, int skip, int max) throws SQLException List list = null;/根据传入的id获取具体的MappedStatement对象,每个MappedStatement对象对应xml中的一个id,存放每个执行块的具体信息传入出参数和sql执行语句MappedStatement ms = getMappedStatement(id);/ 获得sessionScope中的事务对象 Transaction trans = getTransact

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论