搜索
首页Javajava教程MyBatis整体预览(一)

MyBatis整体预览(一)

Mar 02, 2017 am 11:19 AM

题记:最近在工作之余分析了一下MyBatis的源码,促使我阅读源码的原因是为了实现MyBatis在物理上的分页。我们知道,MyBatis是在逻辑上的分页,通过用户的查询,将结果缓存下来,在查看是否传递了RowBounds对象,在查看里面的offset和limit值,通过这两个值,从返回的结果集合中截取位于期间的值。但是这样并不是很好,可以想想,如果假设查询的数据量很大,但是有用的可以是前几条,这未免有点太浪费了。在之前,也在网上查了一下实现分页的方法,最常用的就是添加MyBatis插件,实现Interceptor接口,拦截StatementHandler接口中的prepare方法,后面会介绍为什么拦截这个接口的这个方法。在拦截ResultSetHandler接口的handlerResultSet方法,后面也会对其缘由进行介绍。但是这中方法虽然可以添加分页的SQL语句,但是并没有将分页的offset和limit的值让Mybatis动态的添加到SQL中去,有人会说,可以在拦截StatementHandler接口的时候我们将它们拼装上去。但是这样会容易出现SQL注入的问题。所以这样不得不使我进一步的了解MyBatis的内部原理。本文将就一下几个方面对MyBatis的内部实现进行分析

数据管家——Configuration:
    MyBatis在运行期的基本上所有的数据都会汇总到这个类。它的初始数据是来自开发人员配置在configuration的xml配置文件。通过用户配置的environments来获得系统运行的数据库环境,如事物管理以及数据源。下面给出了最基本的配置:
[html]
<configuration> 
<environments default="development"> 
<environment id="development"> 
<transactionManager type="JDBC" /> 
<dataSource type="POOLED"> 
<property name="driver" value="com.mysql.jdbc.Driver"/> 
<property name="url" value="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=GBK"/> 
<property name="username" value="root"/> 
<property name="password" value="root"/> 
</dataSource> 
</environment> 
</environments> 
<mappers> 
<mapper resource="com/bieber/mybatis/io/user-mapper.xml"/> 
</mappers> 
</configuration>
这些配置对于MyBatis需要做哪些工作呢?通过阅读Configuration的源码会发现,Mybatis其实为configuration标签下面的子标签都有一个对应的变量来进行存储,例如:
[java]
protected final TypeHandlerRegistry typeHandlerRegistry = new TypeHandlerRegistry();
则是存储<typeHandlers></typeHandlers>标签下面配置的所有信息。其他的也类似可以找到。负责创建Configuration对象的则是XMLConfigurationBuilder,这里将完成从配置的XML数据映射到Configuration对象的数据。通过一下方法完成数据的映射:
[java]
private void parseConfiguration(XNode root) { 
    try { 
    propertiesElement(root.evalNode("properties"));         typeAliasesElement(root.evalNode("typeAliases")); 
        pluginElement(root.evalNode("plugins")); 
        objectFactoryElement(root.evalNode("objectFactory")); 
                  objectWrapperFactoryElement(root.evalNode("objectWrapperFactory")); 
      settingsElement(root.evalNode("settings")); 
      environmentsElement(root.evalNode("environments")); 
      databaseIdProviderElement(root.evalNode("databaseIdProvider")); 
      typeHandlerElement(root.evalNode("typeHandlers")); 
      mapperElement(root.evalNode("mappers")); 
    } catch (Exception e) { 
      throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e); 
    } 
  }

可以到,它为每个元素都对应了一个处理方法,这些方法将负责解析我们配置的XML文件。这里面我主要跟踪了几个方法的执行 www.2cto.com
(mapperElement,typeHandlerElement,typeAliasesElement,environmentsElement)
mapperElement——ORM
       我们知道,MyBatis支持注解形式和XML形式的ORM配置。那么当然将会有两个类来处理这两种行为,它们分别是XMLMapperBuilder和MapperAnnotationBuilder,它们分别处理什么类型,我看我就不用说了。通过解析configuration/mappers元素来获得ORM配置信息。
1)XML方式的ORM配置和方式,当我们在mappers/mapper的属性中配置了url或者是resource信息的时候将触发MyBatis采用XML的方式进行处理,并读取你指定的mapper路径。在XMLMapperBuilder类中有如下方法:
[java]

private void configurationElement(XNode context) { 
 
    try { 
 
      String namespace = context.getStringAttribute("namespace"); 
 
      builderAssistant.setCurrentNamespace(namespace); 
 
      cacheRefElement(context.evalNode("cache-ref")); 
 
      cacheElement(context.evalNode("cache")); 
 
      parameterMapElement(context.evalNodes("/mapper/parameterMap")); 
 
      resultMapElements(context.evalNodes("/mapper/resultMap")); 
 
      sqlElement(context.evalNodes("/mapper/sql")); 
 
      buildStatementFromContext(context.evalNodes("select|insert|update|delete")); 
 
    } catch (Exception e) { 
 
      throw new RuntimeException("Error parsing Mapper XML. Cause: " + e, e); 
 
    } 
 
  }

这个方法便是读取你mapper文件中所有制的ORM信息。该方法将通过调用XMLMapperBuilder的parse()方法触发。
    2)注解方式配置ORM信息加载,当你配置了mappers/package或者在mapper里面配置了class属性的时候将触发信息的读取,具体的过程我就再描述了,基本和上面差不多,只是读取的是注解的信息。
   
注意:MyBatis优先处理的是注解形式的方式,并且在mapper配置中,当配置了多个属性时,resource属性优先处理。
    那么在这样处理后Configuration会得到怎样的数据呢?通过这些处理在Configuration里面将会获得几个主要的变量值:sqlFragments,resultMaps,mappedStatements。其中sqlFragments就是我们定义在mapper里面的sql标签或者注解的内容,而resultMaps也是定义在mapper里面或者注解的resultMap内容。最重要的是mappedStatements,这是ORM的最关键部分。它里面通过键值对的方式存储,key这是我们配置的id属性加上namespace,而value则是MappedStatement对象,这个对象这就对应了我们配置的select/update/delete/insert标签的值。
    MappedStatement对象包含这条slq语句的ID,执行的类型(Inser,update,delte,select),statementType(指定产生Statement的类型,如PreparedStatement),还有一个就是SqlSource接口的子类对象,在MyBatis中有两种SqlSource,一种是动态的,另一种是静态的。不用解释,应该都明白,一个是生成动态SQL用的,另一个这是简单静态的SQL。在SqlSource中,包括你定义的SQL语句,以及引入的外部SQL语句块。MappedStatement最后还要包括一个重要的信息,这就是ParameterMap,这直接关系你定义的SQL语句中通过#{propertyName}定义的动态填充值。如果你的是一个POJO对象,那么MyBatis将会通过反射获得这个对象的属性,并依次填入到对应的propertyName所在的位置。
    注意:此时的MappedStatement中的SQL语句还是带有#{propertyName}这样占位符的字符串,还并没有解析成待问号(?)的占位符。要执行该操作是在执行具体的数据库操作的时候才替换成(?),只是为了很好的找到这个propertyName所对应的值所在的位置。
以上就将整个SqlSession的初始化过程所做的操作进行了解剖。完成这些操作之后,那么就等待用户触发对数据库的操作了。
   后续将会给出,MyBatis是如何触发用户自定义的插件的过程以及开发自己的TypeHandler。MyBatis允许用户的插件可以拦截ParameterHandler,ResultSetHandler,StatementHandler,Executor接口,从而进行一些操作。
   本文到此继续,后续会有新的更新。如有严重不对的地方,还望各位能够及时提出,毕竟对MyBatis的接触也只有一个星期,未免有些地方不对,还望大家谅解。

 以上就是MyBatis整体预览(一)的内容,更多相关内容请关注PHP中文网(www.php.cn)!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
JVM性能与其他语言JVM性能与其他语言May 14, 2025 am 12:16 AM

JVM'SperformanceIsCompetitiveWithOtherRuntimes,operingabalanceOfspeed,安全性和生产性。1)JVMUSESJITCOMPILATIONFORDYNAMICOPTIMIZAIZATIONS.2)c提供NativePernativePerformanceButlanceButlactsjvm'ssafetyFeatures.3)

Java平台独立性:使用示例Java平台独立性:使用示例May 14, 2025 am 12:14 AM

JavaachievesPlatFormIndependencEthroughTheJavavIrtualMachine(JVM),允许CodeTorunonAnyPlatFormWithAjvm.1)codeisscompiledIntobytecode,notmachine-specificodificcode.2)bytecodeisisteredbytheybytheybytheybythejvm,enablingcross-platerssectectectectectross-eenablingcrossectectectectectection.2)

JVM架构:深入研究Java虚拟机JVM架构:深入研究Java虚拟机May 14, 2025 am 12:12 AM

TheJVMisanabstractcomputingmachinecrucialforrunningJavaprogramsduetoitsplatform-independentarchitecture.Itincludes:1)ClassLoaderforloadingclasses,2)RuntimeDataAreafordatastorage,3)ExecutionEnginewithInterpreter,JITCompiler,andGarbageCollectorforbytec

JVM:JVM与操作系统有关吗?JVM:JVM与操作系统有关吗?May 14, 2025 am 12:11 AM

JVMhasacloserelationshipwiththeOSasittranslatesJavabytecodeintomachine-specificinstructions,managesmemory,andhandlesgarbagecollection.ThisrelationshipallowsJavatorunonvariousOSenvironments,butitalsopresentschallengeslikedifferentJVMbehaviorsandOS-spe

Java:写一次,在任何地方跑步(WORA) - 深入了解平台独立性Java:写一次,在任何地方跑步(WORA) - 深入了解平台独立性May 14, 2025 am 12:05 AM

Java实现“一次编写,到处运行”通过编译成字节码并在Java虚拟机(JVM)上运行。1)编写Java代码并编译成字节码。2)字节码在任何安装了JVM的平台上运行。3)使用Java原生接口(JNI)处理平台特定功能。尽管存在挑战,如JVM一致性和平台特定库的使用,但WORA大大提高了开发效率和部署灵活性。

Java平台独立性:与不同的操作系统的兼容性Java平台独立性:与不同的操作系统的兼容性May 13, 2025 am 12:11 AM

JavaachievesPlatFormIndependencethroughTheJavavIrtualMachine(JVM),允许Codetorunondifferentoperatingsystemsswithoutmodification.thejvmcompilesjavacodeintoplatform-interploplatform-interpectentbybyteentbytybyteentbybytecode,whatittheninternterninterpretsandectectececutesoneonthepecificos,atrafficteyos,Afferctinginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginginging

什么功能使Java仍然强大什么功能使Java仍然强大May 13, 2025 am 12:05 AM

JavaispoperfulduetoitsplatFormitiondence,对象与偏见,RichstandardLibrary,PerformanceCapabilities和StrongsecurityFeatures.1)Platform-dimplighandependectionceallowsenceallowsenceallowsenceallowsencationSapplicationStornanyDevicesupportingJava.2)

顶级Java功能:开发人员的综合指南顶级Java功能:开发人员的综合指南May 13, 2025 am 12:04 AM

Java的顶级功能包括:1)面向对象编程,支持多态性,提升代码的灵活性和可维护性;2)异常处理机制,通过try-catch-finally块提高代码的鲁棒性;3)垃圾回收,简化内存管理;4)泛型,增强类型安全性;5)ambda表达式和函数式编程,使代码更简洁和表达性强;6)丰富的标准库,提供优化过的数据结构和算法。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

Dreamweaver Mac版

Dreamweaver Mac版

视觉化网页开发工具

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能