Title: Recently, I analyzed the source code of MyBatis after work. The reason that prompted me to read the source code was to realize physical paging of MyBatis. We know that MyBatis is logically paging, caching the results through user queries, checking whether the RowBounds object is passed, and checking the offset and limit values in it. Through these two values, from the returned result set Intercepts the value within the period. But this is not very good. Think about it, if the amount of data queried is large, but the first few items are useful, this would be a bit wasteful. Before, I also checked the method of implementing paging on the Internet. The most commonly used method is to add the MyBatis plug-in, implement the Interceptor interface, and intercept the prepare method in the StatementHandler interface. I will introduce why this method of intercepting this interface is introduced later. The reason for intercepting the handlerResultSet method of the ResultSetHandler interface will be introduced later. However, although this method can add paging SQL statements, it does not allow Mybatis to dynamically add the paging offset and limit values to SQL. Some people will say that we can assemble them when intercepting the StatementHandler interface. But this will easily cause SQL injection problems. So this has to make me further understand the internal principles of MyBatis. This article will analyze the internal implementation of MyBatis from the following aspects
数据管家——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); } }
As you can see, it corresponds to a processing method for each element, and these methods will be responsible for parsing the XML file we configured. Here I mainly track the execution of several methods www.2cto.com
(mapperElement, typeHandlerElement, typeAliasesElement, environmentsElement)
mapperElement——ORM
We know that MyBatis supports ORM in annotation form and XML form configuration. Then of course there will be two classes to handle these two behaviors, they are XMLMapperBuilder and MapperAnnotationBuilder. I don't think I need to say what types they handle respectively. Obtain ORM configuration information by parsing the configuration/mappers element.
1) XML ORM configuration and method, when we configure the url or resource information in the mappers/mapper properties, MyBatis will be triggered to process it in XML and read the mapper path you specified. There are the following methods in the XMLMapperBuilder class:
[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)!

Start Spring using IntelliJIDEAUltimate version...

When using MyBatis-Plus or other ORM frameworks for database operations, it is often necessary to construct query conditions based on the attribute name of the entity class. If you manually every time...

Java...

How does the Redis caching solution realize the requirements of product ranking list? During the development process, we often need to deal with the requirements of rankings, such as displaying a...

Conversion of Java Objects and Arrays: In-depth discussion of the risks and correct methods of cast type conversion Many Java beginners will encounter the conversion of an object into an array...

Solutions to convert names to numbers to implement sorting In many application scenarios, users may need to sort in groups, especially in one...

Detailed explanation of the design of SKU and SPU tables on e-commerce platforms This article will discuss the database design issues of SKU and SPU in e-commerce platforms, especially how to deal with user-defined sales...

How to set the SpringBoot project default run configuration list in Idea using IntelliJ...


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

DVWA
Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

Zend Studio 13.0.1
Powerful PHP integrated development environment

SublimeText3 Mac version
God-level code editing software (SublimeText3)

mPDF
mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

PhpStorm Mac version
The latest (2018.2.1) professional PHP integrated development tool