In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly explains "how to understand Mybatis initialization". The content of the article is simple and clear, and it is easy to learn and understand. Please follow the editor's ideas to study and learn "how to understand Mybatis initialization".
Mybatis initialization is completed by SqlSessionFactoryBuilder, the main work is to parse the XML file, and encapsulate the parsed class content into the Configuration class, and finally encapsulate the Configuration class into SqlSessionFactory and return, since then the initialization is completed.
The parsing of the XML file is completed by three classes: XMLConfigBuilder, XMLMapperBuilder, and XMLStatementBuilder:
XMLConfigBuilder: responsible for parsing except mappers nodes in the global configuration file (mybatis-config.xml).
XMLMapperBuilder: responsible for parsing the cache-ref, cache, parameterMap, resultMap, sql nodes in the xxxMapper.xml mapping file; registering the dynamic proxy factory of the Mapper interface into MapperRegistry according to namespace.
XMLStatementBuilder: responsible for parsing SQL statement nodes in xxxMapper.xml mapping files, such as select, insert, update, delete.
XMLScriptBuilder: responsible for parsing the SQL script and then encapsulating it into SqlSource.
Mybatis initialization process SqlSessionFactoryBuilder
SqlSessionFactoryBuilder will delegate the parsing task to the XMLConfigBuilder class. The source code is as follows:
Public SqlSessionFactory build (InputStream inputStream, String environment, Properties properties) {try {/ / entrusts XMLConfigBuilder to parse the configuration file XMLConfigBuilder parser = new XMLConfigBuilder (inputStream, environment, properties); / / starts parsing return build (parser.parse ());}.} public SqlSessionFactory build (Configuration config) {return new DefaultSqlSessionFactory (config);} XMLConfigBuilder
Responsible for parsing except mappers nodes in the global configuration file (mybatis-config.xml). The parsing node delegates to the XMLMapperBuilder parser.
Private void parseConfiguration (XNode root) {try {/ / issue # 117 read properties first / / parsing node propertiesElement (root.evalNode ("properties")); / / parsing node Properties settings = settingsAsProperties (root.evalNode ("settings")); loadCustomVfs (settings); loadCustomLogImpl (settings); / / parsing node typeAliasesElement (root.evalNode ("typeAliases")); pluginElement (root.evalNode ("plugins")) ObjectFactoryElement (root.evalNode ("objectFactory")); objectWrapperFactoryElement (root.evalNode ("objectWrapperFactory")); reflectorFactoryElement (root.evalNode ("reflectorFactory")); settingsElement (settings); / / read it after objectFactory and objectWrapperFactory issue # 631 environmentsElement (root.evalNode ("environments")); databaseIdProviderElement (root.evalNode ("databaseIdProvider")); typeHandlerElement (root.evalNode ("typeHandlers")); / / parse node mapperElement (root.evalNode ("mappers")) } catch (Exception e) {throw new BuilderException ("Error parsing SQL Mapper Configuration. Cause: "+ e, e);}} private void mapperElement (XNode parent) throws Exception {if (parent! = null) {for (XNode child: parent.getChildren ()) {if (" package ".equals (child.getName () {String mapperPackage = child.getStringAttribute (" name "); configuration.addMappers (mapperPackage);} else {String resource = child.getStringAttribute (" resource ") String url = child.getStringAttribute ("url"); String mapperClass = child.getStringAttribute ("class"); if (resource! = null & & url = = null & & mapperClass = = null) {ErrorContext.instance (). Resource (resource); InputStream inputStream = Resources.getResourceAsStream (resource); / / delegate XMLMapperBuilder to parse the mapping file XMLMapperBuilder mapperParser = new XMLMapperBuilder (inputStream, configuration, resource, configuration.getSqlFragments ()) MapperParser.parse ();} else if (resource = = null & & url! = null & & mapperClass = = null) {ErrorContext.instance () .resource (url); InputStream inputStream = Resources.getUrlAsStream (url); / / delegate XMLMapperBuilder to parse the mapping file XMLMapperBuilder mapperParser = new XMLMapperBuilder (inputStream, configuration, url, configuration.getSqlFragments ()); mapperParser.parse () } else if (resource = = null & & url = = null & & mapperClass! = null) {Class mapperInterface = Resources.classForName (mapperClass); configuration.addMapper (mapperInterface);} else {throw new BuilderException ("A mapper element may only specify a url, resource or class, but not more than one.");} XMLMapperBuilder
Responsible for parsing the cache-ref, cache, parameterMap, resultMap, sql nodes in the xxxMapper.xml mapping file; registering the dynamic proxy factory (MapperProxyFactory) of the Mapper interface into the MapperRegistry according to namespace.
Public void parse () {/ / prevent repeated parsing of if (! configuration.isResourceLoaded (resource)) {/ / parsing the mapper node configurationElement (parser.evalNode ("/ mapper")) in the xxxMapper.xml mapping file; / / marking that configuration.addLoadedResource (resource) has been loaded; / / registering the dynamic proxy factory of the Mapper interface to MapperRegistry according to namespace bindMapperForNamespace ();} / / underside parsePendingResultMaps () ParsePendingCacheRefs (); parsePendingStatements ();} private void configurationElement (XNode context) {try {String namespace = context.getStringAttribute ("namespace"); if (namespace = = null | | namespace.equals (")) {throw new BuilderException (" Mapper's namespace cannot be empty ");} builderAssistant.setCurrentNamespace (namespace); / / parsing node cacheRefElement (context.evalNode (" cache-ref ")) / / parsing node cacheElement (context.evalNode ("cache")); / / parsing node parameterMapElement (context.evalNodes ("/ mapper/parameterMap")); / / parsing node resultMapElements (context.evalNodes ("/ mapper/resultMap")); sqlElement (context.evalNodes ("/ mapper/sql")); / / parsing node buildStatementFromContext (context.evalNodes ("select | insert | update | delete")) } catch (Exception e) {throw new BuilderException ("Error parsing Mapper XML. The XML location is'"+ resource +"'. Cause: "+ e, e);}} private void buildStatementFromContext (List list) {if (configuration.getDatabaseId ()! = null) {buildStatementFromContext (list, configuration.getDatabaseId ());} buildStatementFromContext (list, null);} private void buildStatementFromContext (List list, String requiredDatabaseId) {for (XNode context: list) {/ parse node to XMLStatementBuilder final XMLStatementBuilder statementParser = new XMLStatementBuilder (configuration, builderAssistant, context, requiredDatabaseId); try {statementParser.parseStatementNode () } catch (IncompleteElementException e) {configuration.addIncompleteStatement (statementParser);} XMLStatementBuilder
Responsible for parsing SQL statement nodes in xxxMapper.xml mapping files, such as select, insert, update, delete. The parsing node delegates to the XMLStatementBuilder parser.
Public void parseStatementNode () {String id = context.getStringAttribute ("id"); String databaseId = context.getStringAttribute ("databaseId"); if (! databaseIdMatchesCurrent (id, databaseId, this.requiredDatabaseId) {return;} / / determine the type of SQL statement based on the name of the node (select | insert | update | delete) String nodeName = context.getNode (). GetNodeName (); SqlCommandType sqlCommandType = SqlCommandType.valueOf (nodeName.toUpperCase (Locale.ENGLISH)); boolean isSelect = sqlCommandType = = SqlCommandType.SELECT Boolean flushCache = context.getBooleanAttribute ("flushCache",! isSelect); boolean useCache = context.getBooleanAttribute ("useCache", isSelect); boolean resultOrdered = context.getBooleanAttribute ("resultOrdered", false); / / Include Fragments before parsing / / parse node XMLIncludeTransformer includeParser = new XMLIncludeTransformer (configuration, builderAssistant); includeParser.applyIncludes (context.getNode ()); String parameterType = context.getStringAttribute ("parameterType"); Class parameterTypeClass = resolveClass (parameterType); String lang = context.getStringAttribute ("lang"); LanguageDriver langDriver = getLanguageDriver (lang) / / Parse selectKey after includes and remove them. / / parse the node and delete the node processSelectKeyNodes (id, parameterTypeClass, langDriver) in XML; / / Parse the SQL (pre: and were parsed and removed) KeyGenerator keyGenerator; String keyStatementId = id + SelectKeyGenerator.SELECT_KEY_SUFFIX; keyStatementId = builderAssistant.applyCurrentNamespace (keyStatementId, true); if (configuration.hasKeyGenerator (keyStatementId)) {keyGenerator = configuration.getKeyGenerator (keyStatementId) } else {keyGenerator = context.getBooleanAttribute ("useGeneratedKeys", configuration.isUseGeneratedKeys () & & SqlCommandType.INSERT.equals (sqlCommandType))? Jdbc3KeyGenerator.INSTANCE: NoKeyGenerator.INSTANCE;} / / parses the SQL statement and encapsulates it into SqlSource SqlSource sqlSource = langDriver.createSqlSource (configuration, context, parameterTypeClass); StatementType statementType = StatementType.valueOf (context.getStringAttribute ("statementType", StatementType.PREPARED.toString ()); Integer fetchSize = context.getIntAttribute ("fetchSize"); Integer timeout = context.getIntAttribute ("timeout"); String parameterMap = context.getStringAttribute ("parameterMap"); String resultType = context.getStringAttribute ("resultType"); Class resultTypeClass = resolveClass (resultType) String resultMap = context.getStringAttribute ("resultMap"); String resultSetType = context.getStringAttribute ("resultSetType"); ResultSetType resultSetTypeEnum = resolveResultSetType (resultSetType); if (resultSetTypeEnum = = null) {resultSetTypeEnum = configuration.getDefaultResultSetType ();} String keyProperty = context.getStringAttribute ("keyProperty"); String keyColumn = context.getStringAttribute ("keyColumn"); String resultSets = context.getStringAttribute ("resultSets") / use builder mode to build MappedStatement object builderAssistant.addMappedStatement (id, sqlSource, statementType, sqlCommandType, fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass, resultSetTypeEnum, flushCache, useCache, resultOrdered, keyGenerator, keyProperty, keyColumn, databaseId, langDriver, resultSets);} Mybatis initialization flowchart
Core data structure class Configuration
Configuration is actually the Java form of the XML configuration file. Configuration is a singleton, and the life cycle is application-level.
ResultMap
Corresponds to the resultMap node in the xxxMapper.xml mapping file. The child nodes in the node are encapsulated using ResultMapping, such as:, and so on.
MappedStatement
Corresponds to the, and nodes in the xxxMapper.xml mapping file.
SqlSource
Corresponding to the sql statement in the xxxMapper.xml mapping file, the statement contained in the parsed SqlSource only contains? Placeholder, which can be submitted directly to the database for execution
MapperRegistry
It is the registry of the Mapper interface dynamic proxy factory class. In MyBatis, the InvocationHandler interface is implemented through MapperProxy, and the instance object of dynamic agent is generated through MapperProxyFactory.
MyBatis Builder Class Diagram
The builder mode is used throughout the initialization process of Mybatis. The builder pattern is more suitable for generating complex objects, mainly focusing on the instantiation details of the objects.
Mybatis Source Code Chinese Notes
Https://github.com/xiaolyuh/mybatis
Thank you for your reading, the above is the content of "how to understand Mybatis initialization". After the study of this article, I believe you have a deeper understanding of how to understand Mybatis initialization, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.