mybatis代码

来源:互联网 发布:erp系统网络架构图 编辑:程序博客网 时间:2024/06/06 09:40

http://my.oschina.net/zimingforever/blog/112591

mybatis的入门可以参考这里:http://my.oschina.net/zimingforever/blog/111907

之前把mybaits的源码简单的看了下,这篇博客主要会跟踪一下mybatis进行一次查询时的代码流。

1 先读取mybatis的配置文件,然后通过sqlsessionfactorybuider通过配置文件获取sqlsessionFactory


?
1
2
3
String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory =new SqlSessionFactoryBuilder().build(inputStream);
这是的sqlSessionFactory是一个DefaultSqlSessionFactory


2 defaultsqlSessionFactory调用了openSession()获得到一个Sqlsession


?
1
SqlSession session = sqlSessionFactory.openSession();
其中opensession方法如下:



?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public SqlSession openSession() {
    returnopenSessionFromDataSource(configuration.getDefaultExecutorType(),null, false);
}
 
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level,boolean autoCommit) {
    Transaction tx =null;
    try{
      finalEnvironment environment = configuration.getEnvironment();
      finalTransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
      tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
      finalExecutor executor = configuration.newExecutor(tx, execType, autoCommit);
      returnnew DefaultSqlSession(configuration, executor);
    }catch (Exception e) {
      closeTransaction(tx);// may have fetched a connection so lets call close()
      throwExceptionFactory.wrapException("Error opening session.  Cause: "+ e, e);
    }finally {
      ErrorContext.instance().reset();
    }
}

其中的configuration.getDefaultExecutorType()获取到的是simple,这里获取一个executor,这个executor是simpleExecutor

这里的sqlsession是DefaultSqlSession

3 调用sqlsession的selectOne方法


?
1
Blog blog = (Blog) session.selectOne("org.mybatis.example.BlogMapper.selectBlog",1);
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public <T> T selectOne(String statement, Object parameter) {
    // Popular vote was to return null on 0 results and throw exception on too many.
    List<T> list =this.<T>selectList(statement, parameter);
    if(list.size() == 1) {
      returnlist.get(0);
    }else if(list.size() > 1) {
      thrownew TooManyResultsException("Expected one result (or null) to be returned by selectOne(), but found: "+ list.size());
    }else {
      returnnull;
    }
  }
 
  public<E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
    try{
      MappedStatement ms = configuration.getMappedStatement(statement);
      List<E> result = executor.<E>query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
      returnresult;
    }catch (Exception e) {
      throwExceptionFactory.wrapException("Error querying database.  Cause: "+ e, e);
    }finally {
      ErrorContext.instance().reset();
    }
  }


其中selectone调用的是selectlist()方法,其中调用了executor的query方法,这里的executor是simpleExecutor其继承BaseExecutor

其中BaseExecuotr中又有如下方法:


?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)throws SQLException {
    ErrorContext.instance().resource(ms.getResource()).activity("executing a query").object(ms.getId());
    if(closed) throw new ExecutorException("Executor was closed.");
    if(queryStack == 0 && ms.isFlushCacheRequired()) {
      clearLocalCache();
    }
    List<E> list;
    try{
      queryStack++;
      list = resultHandler ==null ? (List<E>) localCache.getObject(key) :null;
      if(list != null) {
        handleLocallyCachedOutputParameters(ms, key, parameter, boundSql);
      }else {
        list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql);
      }
    }finally {
      queryStack--;
    }
    if(queryStack == 0) {
      for(DeferredLoad deferredLoad : deferredLoads) {
        deferredLoad.load();
      }
      deferredLoads.clear();// issue #601
      if(configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) {
        clearLocalCache();// issue #482
      }
    }
    returnlist;
  }
其中的 queryfromdatabase()实现如下:



?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)throws SQLException {
    List<E> list;
    localCache.putObject(key, EXECUTION_PLACEHOLDER);
    try{
      list = doQuery(ms, parameter, rowBounds, resultHandler, boundSql);
    }finally {
      localCache.removeObject(key);
    }
    localCache.putObject(key, list);
    if(ms.getStatementType() == StatementType.CALLABLE) {
      localOutputParameterCache.putObject(key, parameter);
    }
    returnlist;
  }



其中的doquery在simpleExecutor实现为:


?
1
2
3
4
5
6
7
8
9
10
11
public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql)throws SQLException {
    Statement stmt =null;
    try{
      Configuration configuration = ms.getConfiguration();
      StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, rowBounds, resultHandler, boundSql);
      stmt = prepareStatement(handler, ms.getStatementLog());
      returnhandler.<E>query(stmt, resultHandler);
    }finally {
      closeStatement(stmt);
    }
  }
?
1
2
3
4
5
6
7
private Statement prepareStatement(StatementHandler handler, Log statementLog) throwsSQLException {
    Statement stmt;
    Connection connection = getConnection(statementLog);
    stmt = handler.prepare(connection);
    handler.parameterize(stmt);
    returnstmt;
  }

其中的hander为preparedstatementHandler,其query方法实现为:、


?
1
2
3
4
5
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throwsSQLException {
    PreparedStatement ps = (PreparedStatement) statement;
    ps.execute();
    returnresultSetHandler.<E> handleResultSets(ps);
  }
其中的resultSetHandler为FastResultHandler



?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public List<Object> handleResultSets(Statement stmt) throwsSQLException {
    finalList<Object> multipleResults = newArrayList<Object>();
    finalList<ResultMap> resultMaps = mappedStatement.getResultMaps();
    intresultMapCount = resultMaps.size();
    intresultSetCount = 0;
    ResultSet rs = stmt.getResultSet();
 
    while(rs == null) {
      // move forward to get the first resultset in case the driver
      // doesn't return the resultset as the first result (HSQLDB 2.1)
      if(stmt.getMoreResults()) {
        rs = stmt.getResultSet();
      }else {
        if(stmt.getUpdateCount() == -1) {
          // no more results.  Must be no resultset
          break;
        }
      }
    }
 
    validateResultMapsCount(rs, resultMapCount);
    while(rs != null && resultMapCount > resultSetCount) {
      finalResultMap resultMap = resultMaps.get(resultSetCount);
      ResultColumnCache resultColumnCache =new ResultColumnCache(rs.getMetaData(), configuration);
      handleResultSet(rs, resultMap, multipleResults, resultColumnCache);
      rs = getNextResultSet(stmt);
      cleanUpAfterHandlingResultSet();
      resultSetCount++;
    }
    returncollapseSingleResultList(multipleResults);
  }
其中的handleResultSet实现如下:



?
1
2
3
4
5
6
7
8
9
10
11
12
13
protectedvoid handleResultSet(ResultSet rs, ResultMap resultMap, List<Object> multipleResults, ResultColumnCache resultColumnCache)throws SQLException {
    try{
      if(resultHandler == null) {
        DefaultResultHandler defaultResultHandler =new DefaultResultHandler(objectFactory);
        handleRowValues(rs, resultMap, defaultResultHandler, rowBounds, resultColumnCache);
        multipleResults.add(defaultResultHandler.getResultList());
      }else {
        handleRowValues(rs, resultMap, resultHandler, rowBounds, resultColumnCache);
      }
    }finally {
      closeResultSet(rs);// issue #228 (close resultsets)
    }
  }
其中的handleRowValues()实现方式为:



?
1
2
3
4
5
6
7
8
9
protectedvoid handleRowValues(ResultSet rs, ResultMap resultMap, ResultHandler resultHandler, RowBounds rowBounds, ResultColumnCache resultColumnCache)throws SQLException {
    finalDefaultResultContext resultContext = newDefaultResultContext();
    skipRows(rs, rowBounds);
    while(shouldProcessMoreRows(rs, resultContext, rowBounds)) {
      finalResultMap discriminatedResultMap = resolveDiscriminatedResultMap(rs, resultMap,null);
      Object rowValue = getRowValue(rs, discriminatedResultMap,null, resultColumnCache);
      callResultHandler(resultHandler, resultContext, rowValue);
    }
  }
其中的getValue实现方式为:



?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
protectedObject getRowValue(ResultSet rs, ResultMap resultMap, CacheKey rowKey, ResultColumnCache resultColumnCache)throws SQLException {
    finalResultLoaderMap lazyLoader = instantiateResultLoaderMap();
    Object resultObject = createResultObject(rs, resultMap, lazyLoader,null, resultColumnCache);
    if(resultObject != null&& !typeHandlerRegistry.hasTypeHandler(resultMap.getType())) {
      finalMetaObject metaObject = configuration.newMetaObject(resultObject);
      booleanfoundValues = resultMap.getConstructorResultMappings().size() >0;
      if(shouldApplyAutomaticMappings(resultMap, !AutoMappingBehavior.NONE.equals(configuration.getAutoMappingBehavior()))) {
        finalList<String> unmappedColumnNames = resultColumnCache.getUnmappedColumnNames(resultMap,null);
        foundValues = applyAutomaticMappings(rs, unmappedColumnNames, metaObject,null, resultColumnCache) || foundValues;
      }
      finalList<String> mappedColumnNames = resultColumnCache.getMappedColumnNames(resultMap,null);
      foundValues = applyPropertyMappings(rs, resultMap, mappedColumnNames, metaObject, lazyLoader,null) || foundValues;
      foundValues = (lazyLoader !=null && lazyLoader.size() >0) || foundValues;
      resultObject = foundValues ? resultObject :null;
      returnresultObject;
    }
    returnresultObject;
  }
其中的applyPropertyMap的实现如下:



?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
protectedboolean applyAutomaticMappings(ResultSet rs, List<String> unmappedColumnNames, MetaObject metaObject, String columnPrefix, ResultColumnCache resultColumnCache)throws SQLException {
    booleanfoundValues = false;
    for(String columnName : unmappedColumnNames) {
      String propertyName = columnName;
      if(columnPrefix != null&& columnPrefix.length() > 0) {
        // When columnPrefix is specified,
        // ignore columns without the prefix.
        if(columnName.startsWith(columnPrefix)) {
          propertyName = columnName.substring(columnPrefix.length());
        }else {
          continue;
        }
      }
      finalString property = metaObject.findProperty(propertyName, configuration.isMapUnderscoreToCamelCase());
      if(property != null) {
        finalClass<?> propertyType = metaObject.getSetterType(property);
        if(typeHandlerRegistry.hasTypeHandler(propertyType)) {
          finalTypeHandler<?> typeHandler = resultColumnCache.getTypeHandler(propertyType, columnName);
          finalObject value = typeHandler.getResult(rs, columnName);
          if(value != null || configuration.isCallSettersOnNulls()) { // issue #377, call setter on nulls
            metaObject.setValue(property, value);
            foundValues =true;
          }
        }
      }
    }
    returnfoundValues;
  }
总结一下:这篇博客主要记录了跟踪一个简单的mybatis应用的代码实现情况。主要是调用底层代码查询数据,并把数据根据bean反射成要查询的对象。
0 0
原创粉丝点击