Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to understand the hardest API of Mybatis

2025-01-15 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article introduces the relevant knowledge of "how to understand the hardest API of Mybatis". In the operation of practical cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

1. Mybatis architecture and core API

If nothing happens, in the follow-up source code analysis related articles, we will conduct a big sweep of the Mybatis source code, together to dig every knowledge point worthy of your in-depth understanding / memory. In this article, we first spread out the architecture / hierarchy of Mybatis, overlook the overall design of Mybatis architecture, and then digest several hard-core API in detail.

The overall sequence, I hope you have something to look forward to.

Let's first briefly uncover the mysterious source package of Mybatis.

Take a look at the general directory structure of Ta:

Look, the source code packages of Mybatis are neatly arranged under the org.apache.ibatis directory. I simply sort out the basic design uses into the above figure to facilitate your intuitive understanding. Of course, if you only look at the directory structure of the source code package, it will inevitably look boring, so let's take another look. In fact, the function of the source code package of Mybatis can be divided like this:

The figure above gives us an abstract understanding of the architecture of Mybatis.

However, in fact, what kind of process will be presented for the specific division of functions and the scenario application of the core API?

Take a look at the functional architecture design below, maybe you can understand it better.

According to the Mybatis functional architecture, we are divided into three layers:

Interface layer: this layer provides a series of interfaces for users to directly participate in use, including information configuration and actual data operation calls. Configuration methods include: XML-based configuration mode and Java API-based configuration mode. Users can also initiate requests for database operations such as additions, deletions, changes and queries through the interface layer API. The API in this layer will hand over the received call requests to the components of the data processing layer for processing.

Data processing layer: this layer is the core layer of Mybatis, which is responsible for data processing, including SQL parameter mapping analysis, actual execution of SQL statements, mapping processing of execution result sets, and so on.

Framework support layer: this layer belongs to the logistics support layer of Mybatis, including database connection management, transaction control management, configuration loading and cache processing, log processing, exception handling and so on.

We know that the Mybatis framework allows users to only provide configuration information and focus on the writing of SQL, for connection management database / transaction, or the actual SQL parameter mapping / statement execution / result set mapping and other operations, as users do not need to worry and participate.

However, curiously, we actually want to know, how does the data processing of the core part of Mybatis support user requests in the overall process? At the same time, how do the various components interact with each other?

Coincidentally, I have a picture here that shows the overall process:

Explain according to the above framework flow chart:

Create configuration and call API: this step takes place on the application side, which is a two-step operation performed by developers in the actual application. The first step is to create the core configuration file Configuration.xml and the mapping file mapper.xml (the above two configurations can also be created through annotations), and after the basic configuration and SQL statements are ready; the second step is to directly call the database operation interface in the Mybatis framework.

Load configuration and initialize: according to the contents of the core configuration file and SQL mapping file provided by the application side, the Mybatis framework uses the resource helper class Resources to read the configuration file into an input stream, then parses and encapsulates it into Configuration object and MappedStatement object through the corresponding parser, and finally stores the object in memory.

Create a session and receive requests: after the Mybatis framework loads the configuration and initializes the configuration object, the session factory builder SqlSessionFactoryBuilder also creates a session factory SqlSessionFactory, which creates a session SqlSession based on the request of the application side so that the application side can interact with the database.

Processing request: after receiving the request, SqlSession does not actually process it, but forwards the request to the executor Executor, which is then dispatched to the statement processor StatementHandler, which combines the parameter processor ParameterHandler to perform database operations (the underlying JDBC Statement operation is encapsulated).

Return processing result: after each statement processor StatementHandler completes the database operation, it will map and encapsulate the result set returned by the underlying JDBC in cooperation with ResultSetHandler and type processor TypeHandler, and finally return the encapsulated object.

For these hard-core API involved in the above overall framework process, we will introduce them one by one, but we will not analyze the source code and principle in detail, including the construction details, because we will analyze them in detail in the following source code analysis chapters.

2. Configuration-Global configuration object

For Mybatis's global configuration object Configuration, I believe that both beginners and experienced players are no stranger. The whole universe of Mybatis revolves around Configuration. The structure of the Configuration object is almost the same as the content of the config.xml configuration file, covering properties (properties), settings (settings), typeAliases (type aliases), typeHandlers (type handler), objectFactory (object factory), mappers (mapper) and so on. Before that, we had a special article to introduce it in detail, and interested friends went up to the directory list. Find a detailed taste of the article "complete solution of Mybatis Series (4): the most complete of the whole network! full picture of Mybatis configuration file XML".

The configuration object Configuration is parsed through the parser XMLConfigBuilder, and all the configuration information in the global configuration file Config.xml and mapper configuration file Mapper.xml is built into a complete Configuration object. Later, when we analyze the source code, we analyze the whole process in detail.

3. Resources-Resource Helper Class

We know that configuration information like Configuration and Mapper is stored in XML files, Mybatis framework in the construction of configuration objects, must first load the XML file information into a stream, and then do subsequent parsing encapsulation, and Resources as an auxiliary class of resources, exactly do this job, whether by loading local resources or loading remote resources, eventually through the class loader to access resource files and output file stream.

/ / load the core configuration file InputStream resourceAsStream = Resources.getResourceAsStream ("Config.xml")

Resources actually provides a series of ways to solve your file read and load problems minute by minute:

4. SqlSessionFactoryBuilder-session factory builder

As soon as we encounter xxxBuilder, we can roughly know that it is the builder of some kind of object, and so is SqlSessionFactoryBuilder, which is a session factory builder in Mybatis. After the resource helper class Resources reads the file flow information, it is responsible for parsing the file flow information and building the session factory SqlSessionFactory. (the parsed configuration file contains: global configuration Configuration and mapper Mapper)

On the application side, we typically use SqlSessionFactoryBuilder to build session factories directly:

/ / get the sqlSession factory object SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder () .build (resourceAsStream)

Of course, if you integrate the Spring framework project, you do not need to manually build the session factory, you can specify it directly in the Spring configuration file, for example, specify a bean object, id is sqlSessionFactory, and the class class specifies org.mybatis.spring.SqlSessionFactoryBean.

SqlSessionFactoryBuilder parses the file stream through the parser XMLConfigBuilder, encapsulates it into a configuration object Configuration, and then passes the Configuration object and builds the instance.

Public SqlSessionFactory build (InputStream inputStream, String environment, Properties properties) {/ / configure the parser to resolve XMLConfigBuilder parser = new XMLConfigBuilder (inputStream,environment, properties); / / final instance session factory return build (parser.parse ());}

The final instance session factory, in fact, the default implementation of Mybatis is to new a DefaultSqlSessionFactory instance.

/ / final instance session factory public SqlSessionFactory build (Configuration config) {return new DefaultSqlSessionFactory (config);}

Session factory builder SqlSessionFactoryBuilder applies the builder pattern, the main purpose is to build SqlSessionFactory objects for subsequent production of SqlSession objects, this constructor is basically the entry builder of the Mybatis framework, it provides a series of polymorphic methods build (), allowing users to use XML configuration files or Java API (Properties) to build session factory SqlSessionFactory instances.

SqlSessionFactoryBuilder's life is only to achieve SqlSessionFactory, once the SqlSessionFactory instance, SqlSessionFactoryBuilder mission is completed, it can be wiped out, can be discarded.

Therefore, the best scope of an SqlSessionFactoryBuilder instance is the method scope (that is, local method variables). You can reuse SqlSessionFactoryBuilder to create multiple SqlSessionFactory instances, but it's best not to keep it all the time to ensure that all XML parsing resources can be released to more important things.

A series of interfaces for flexibly building session factories in SqlSessionFactoryBuilder:

5. SqlSessionFactory-session Factory

The session factory SqlSessionFactory is an interface that serves as the production database session object SqlSession, with two implementation classes:

* * DefaultSqlSessionFactory * * (default implementation)

* * SqlSessionManager * * (only one more Sqlsession interface has been implemented and deprecated)

When introducing the session factory builder SqlSessionFactoryBuilder, we learned that the builder creates an DefaultSqlSessionFactory instance by default, and that the session factory itself binds an important property Configuration object, and eventually passes and sets the Configuration configuration object to the session SqlSession during the production session.

The session factory can simply create an SqlSession instance:

/ / create SqlSession instance SqlSession session = sqlSessionFactory.openSession ()

When the session factory creates the SqlSession, it binds the data source, transaction processing, executor, and so on. The default session factory implementation class DefaultSqlSessionFactory will eventually call the openSessionFromDataSource method when creating the session object, which is implemented like this:

/ / every openSession will eventually call here private SqlSession openSessionFromDataSource (ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {/ / Environment configuration final Environment environment = configuration.getEnvironment (); / / transaction factory final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment (environment) / / transaction Transaction tx = transactionFactory.newTransaction (environment.getDataSource (), level, autoCommit); / / Actuator final Executor executor = configuration.newExecutor (tx, execType); / / final generation session return new DefaultSqlSession (configuration, executor, autoCommit);}

In addition, the session factory actually provides a series of interfaces to flexibly produce session SqlSession, which you can specify:

Transaction processing: do you want to use / open transaction scope in session scope (that is, do not commit transactions automatically), or use autocommit (auto-commit). SqlSession does not commit transactions by default, and you need to commit transactions manually for addition, deletion and modification operations.

Database connection: you want MyBatis to help you get a connection from a configured data source, or you can create a data source object Connection dynamically using a self-provided connection.

Actuator type: you want to specify a certain type of actuator to create / execute / preprocess statements, which can be a common actuator (SimpleExecutor), or a multiplex actuator (ReuserExecutor), or a batch executor (BatchExecutor), etc., which will be described in more detail below.

Transaction isolation level support: supports five isolation levels of JDBC (NONE, READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ and SERIALIZABLE). For transaction-related content, we will talk about it in detail in the following "spring Series complete solution". Here, it is briefly stated that the transaction isolation level is mainly to solve problems such as dirty reading, non-repeatable reading, phantom reading and so on. Using different transaction isolation levels will inevitably lead to different database execution efficiency. So we have different requirements for isolation levels in different systems / functions.

Once SqlSessionFactory is created, it should always exist while the application is running, and there is no reason to discard it or recreate another instance. The best practice for using SqlSessionFactory is not to create it repeatedly while the application is running, and rebuilding SqlSessionFactory multiple times is considered a code "bad habit". Therefore, the best scope of SqlSessionFactory is the application scope. The simplest thing is to use singleton mode or static singleton mode.

Remember, create a SqlSessionFactory just once!

Each database corresponds to one SqlSessionFactory instance. Once SqlSessionFactory is created, its life cycle should be the same as the life cycle of the application. So, if you want to connect to two databases, you need to create two SqlSessionFactory instances, one for each database; for three databases, you need three instances, and so on.

6. SqlSession-session

SqlSession is an interface with two implementation classes:

DefaultSqlSession (default implementation)

SqlSessionManager (deprecated)

To put it simply, after the SqlSession instance is built through the session factory, we can add, delete, modify and query it. The default instance DefaultSqlSession provides so many methods for users to use, and there are more than 30:

In addition to CURD, the sqlSession method also provides control over transactions such as commit / close / rollback, provides access to configuration objects such as getConfiguration (), provides execution updates for batch statements such as flushStatements (), provides cache cleanup such as clearCache (), provides the use of getMapper () for mappers, and so on.

For the client application level, API that is familiar with sqlSession can basically manipulate the database at will, but we would like to know more about how sql is executed inside sqlSession. In fact, sqlSession is the top-level class used to interact with the database in Mybatis. It is usually bound to the local thread ThreadLocal, a session uses a SqlSession, and is closed after use.

The reason why SqlSession is called the top-level class of data interaction is that it does not actually complete the actual database operation. According to the previous architecture design process, we already know clearly that the operations of SqlSession on the database will be forwarded to the specific executor Executor to complete; of course, the executor is also the shopkeeper, and the executor Executor will be assigned to the statement processor StatementHandler, and the statement processor will work together with the parameter processor ParameterHandler to complete the final database processing operation (the underlying JDBC Statement operation is still encapsulated). After each statement processor StatementHandler completes the database operation, the result set returned by the underlying JDBC is mapped and encapsulated by the result knot processor ResultSetHandler and the type processor TypeHandler, and finally the expected encapsulation object is returned.

Pay attention to the following illustration of the red highlight of the sqlSession, which describes in detail the actual execution path of the session:

SqlSession can be understood as a database session, in which you can execute sql once or batch multiple times, but once the session is closed and you want to execute sql again, you must recreate the session.

Each thread should have its own instance of SqlSession, and the instance of SqlSession is not thread-safe and therefore cannot be shared, so its best scope is the request or method scope. Never place a reference to an SqlSession instance in the static domain of a class, not even an instance variable of a class. Nor should references to SqlSession instances be placed in any type of managed scope, such as HttpSession in the Servlet framework. If you are currently using a Web framework, consider putting SqlSession in a scope similar to HTTP requests. In other words, every time you receive a HTTP request, you can open a SqlSession, and when a response is returned, close it. This close operation is very important, to ensure that the close operation can be performed every time, you should put this close operation in the finally block.

This is the end of "how to understand the hardest API of Mybatis". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!

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.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report