`

Ibatis原理分析

 
阅读更多

 ibatis是什么?ibatis是一个基于Java的"半自动化"的持久框架,"半自动化"是指ibatis并不会在运行期自动生成sql语句执行,而是具体的sql需要通过配置文件进行编写,并将所需的参数,以及返回的结果字段映射到指定的POJO.

      ibatis的核心类图


      SqlMapClient类是ibatis的门面,通过ibatis完成的持久化操作都是通过调用SqlMapClient类完成的,SqlMapClient将所有的操作都转给类SqlMapExecutorDelegate类,SqlMapExecutorDelegate类存放解析配置文件生成的类,比如数据源,parameterMap,resultMap, MappedStatement(对增删改查语句的封装)等,SqlExecutor是最终执行sql语句的地方.MappedStatement类包含对参数数组进行包装的ParameterMapping[]数组,对执行结果进行包装的ResultMapping[]数组,还有对各种不同的sql的包装类Sql

     比如对于一个插入语句,传进来的是一个对象,ibatis就会根据参数的数组包装类ParameterMapping[]将参数赋值.这个赋值是通过DataExchange类完成的,代码如下:

      public Object[] getProperties(Object object) {

Java代码  收藏代码
  1.     int i = 0;  
  2.   Object[] values = new Object[propertyNames.length];  
  3.   try {  
  4.     for (i = 0; i < propertyNames.length; i++) {  
  5.       try {  
  6.         values[i] = getters[i].invoke(object, NO_ARGUMENTS);  
  7.       } catch (Throwable t) {  
  8.         throw ClassInfo.unwrapThrowable(t);  
  9.       }  
  10.     }  
  11.   } catch (Throwable t) {  
  12.     throw new RuntimeException("Error getting property '" + getters[i].getName() + "' of '" + object + "'.  Cause: " + t, t);  
  13.   }  
  14.   return values;  
  15. }  

其中object是传进来的要插入的对象,propertyNames就是ParameterMapping[]的参数数组,getters是object类的所有get方法的Method方法数组

       对于一个查询语句,对执行结果的处理,是通过对ResultMapping[]进行循环处理的,核心代码如下:

 

 

Java代码  收藏代码
  1. for (int i = 0; i < getResultMappings().length; i++) {  
  2.      ResultMapping mapping = (ResultMapping) getResultMappings()[i];  
  3.      errorContext.setMoreInfo(mapping.getErrorString());  
  4.      if (mapping.getStatementName() != null) {  
  5.        if (resultClass == null) {  
  6.          throw new SqlMapException("The result class was null when trying to get results for ResultMap named " + getId() + ".");  
  7.        } else if (Map.class.isAssignableFrom(resultClass)) {  
  8.          Class javaType = mapping.getJavaType();  
  9.          if (javaType == null) {  
  10.            javaType = Object.class;  
  11.          }  
  12.          columnValues[i] = getNestedSelectMappingValue(statementScope, rs, mapping, javaType);  
  13.        } else if (DomTypeMarker.class.isAssignableFrom(resultClass)) {  
  14.          Class javaType = mapping.getJavaType();  
  15.          if (javaType == null) {  
  16.            javaType = DomTypeMarker.class;  
  17.          }  
  18.          columnValues[i] = getNestedSelectMappingValue(statementScope, rs, mapping, javaType);  
  19.        } else {  
  20.          Probe p = ProbeFactory.getProbe(resultClass);  
  21.          Class type = p.getPropertyTypeForSetter(resultClass, mapping.getPropertyName());  
  22.          columnValues[i] = getNestedSelectMappingValue(statementScope, rs, mapping, type);  
  23.        }  
  24.        foundData = foundData || columnValues[i] != null;  
  25.      } else if (mapping.getNestedResultMapName() == null) {  
  26.        columnValues[i] = getPrimitiveResultMappingValue(rs, mapping);  
  27.        if (columnValues[i] == null) {  
  28.          columnValues[i] = doNullMapping(columnValues[i], mapping);  
  29.        } else {  
  30.          foundData = true;  
  31.        }  
  32.      }  
  33.    }  

         其中,type为参数的java类型,   Probe p = ProbeFactory.getProbe(resultClass),Class type = p.getPropertyTypeForSetter(resultClass, mapping.getPropertyName())是通过反射获取java类型的

    getNestedSelectMappingValue(statementScope, rs, mapping, type)调用了prepareBeanParameterObject(StatementScope statementScope, ResultSet rs, ResultMapping mapping, Class parameterType)方法,方法如下:

 

      private Object prepareBeanParameterObject(StatementScope statementScope, ResultSet rs, ResultMapping mapping, Class parameterType)

Java代码  收藏代码
  1.   throws InstantiationException, IllegalAccessException, SQLException {  
  2. TypeHandlerFactory typeHandlerFactory = getDelegate().getTypeHandlerFactory();  
  3.   
  4. Object parameterObject;  
  5. if (parameterType == null) {  
  6.   parameterObject = new HashMap();  
  7. else {  
  8.   parameterObject = ResultObjectFactoryUtil.createObjectThroughFactory(parameterType);  
  9. }  
  10. String complexName = mapping.getColumnName();  
  11.   
  12. if (complexName.indexOf('=') > -1  
  13.     || complexName.indexOf(',') > -1) {  
  14.   StringTokenizer parser = new StringTokenizer(complexName, "{}=, "false);  
  15.   while (parser.hasMoreTokens()) {  
  16.     String propName = parser.nextToken();  
  17.     String colName = parser.nextToken();  
  18.     Class propType = PROBE.getPropertyTypeForSetter(parameterObject, propName);  
  19.     TypeHandler propTypeHandler = typeHandlerFactory.getTypeHandler(propType);  
  20.     Object propValue = propTypeHandler.getResult(rs, colName);  
  21.     PROBE.setObject(parameterObject, propName, propValue);  
  22.   }  
  23. else {  
  24.   // single param  
  25.   TypeHandler propTypeHandler = typeHandlerFactory.getTypeHandler(parameterType);  
  26.   if (propTypeHandler == null) {  
  27.     propTypeHandler = typeHandlerFactory.getUnkownTypeHandler();  
  28.   }  
  29.   parameterObject = propTypeHandler.getResult(rs, complexName);  
  30. }  
  31.   
  32. return parameterObject;  

 typeHandlerFactory根据参数parameterType的类型决定采用哪个handler处理ResultSet的结果,以

StringTypeHandler为例,其getResult(ResultSet rs, String columnName)方法如下:

 

Java代码  收藏代码
  1. public Object getResult(ResultSet rs, String columnName)  
  2.     throws SQLException {  
  3.   Object s = rs.getString(columnName);  
  4.   if (rs.wasNull()) {  
  5.     return null;  
  6.   } else {  
  7.     return s;  
  8.   }  
  9. }  
分享到:
评论

相关推荐

    深入分析 iBATIS 框架之系统架构与映射原理

    深入分析 iBATIS 框架之系统架构与映射原理深入分析 iBATIS 框架之系统架构与映射原理深入分析 iBATIS 框架之系统架构与映射原理深入分析 iBATIS 框架之系统架构与映射原理

    pojo+xDoclet生成ibatis映射文件

    XDoclet实现基本原理是,通过在Java代码加入特定的JavaDoc tag,从而为其添加特定的附加语义,之后通过XDoclet工具对代码中JavaDoc Tag进行分析,自动生成与代码对应的配置文件,

    ibatis 学习教程

    很实用的教程 例子简单易懂 深入浅出的分析了其运用的原理

    深入分析Java Web技术内幕高清PDF版.zip

    《深入分析Java Web技术内幕》围绕JavaWeb相关技术从三方面全面深入地进行阐述...最后介绍Java服务端技术,主要包括Servlet、Session与Cookie、Tomcat与Jetty服务器、Spring容器、Ibatis框架和Velocity框架等原理介绍。

    深入分析Java Web技术内幕 修订版.pdf

    主要围绕Java Web 相关技术从三方面...最后介绍了Java 服务端技术,主要包括Servlet、Session 与Cookie、Tomcat 与Jetty服务器、Spring 容器、iBatis 框架和Velocity 框架等原理介绍,并介绍了服务端的一些优化技术。

    深入分析Java Web技术内幕 修订版

    最后介绍了Java 服务端技术,主要包括Servlet、Session 与Cookie、Tomcat 与Jetty服务器、Spring 容器、iBatis 框架和Velocity 框架等原理介绍,并介绍了服务端的一些优化技术。 《深入分析Java Web技术内幕(修订版...

    JAVA WEB典型模块与项目实战大全

    3.1 spring框架与其他框架的集成原理  3.2 实现ssh三种框架环境集成  3.3 实现spring与struts 2.x集成  3.4 实现spring、struts2.x和hibernate框架集成  3.5 小结  第2篇 典型模块开发  第4章 在线...

    最新Java面试题视频网盘,Java面试题84集、java面试专属及面试必问课程

    ├─面试必问-webservice原理分析 │ webservice原理分析.mp4 │ ├─面试必问-使用Springboot快速搭建SSM框架 │ 使用SpringBoot快速搭建SSM框架.mp4 │ ├─面试必问-双十一系统架构之Mysql索引技术剖析 │ 双...

    JSP网络编程学习笔记源代码 part2

    第四篇为“数据库访问技术”,主要讲述JDBC技术及JSP和Servlet如何通过JDBC访问数据库,以及如何改进数据库的访问和目前流行的Hibernate、iBATIS及Spring集成访问的支持;第五篇为“标签语言和表达式语言”,主要...

    软件开发中动态表单的解决方案 (2010年)

    通过分析动态表单的实现原理和运行机制,采用MVC架构,运用Struts,Spring和iBATIS整合的轻量级J2EE的多层软件架构和模块化思想,结合Fckeditor在线编辑器和FreeMarker组件,设计并实现了一个B/S结构的、可视化的动态表单...

Global site tag (gtag.js) - Google Analytics