In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
How to analyze SqlSessionFactory and SqlSession in MyBatis, I believe many inexperienced people don't know what to do about it. Therefore, this paper summarizes the causes and solutions of the problem. Through this article, I hope you can solve this problem.
[1] SqlSessionFactoryBuilder
This class can be initialized, used, and discarded, and if you've already created a SqlSessionFactory, you don't have to keep it.
Therefore, the best scope of SqlSessionFactoryBuilder is in the method body.
For example, define a method variable. You can reuse SqlSessionFactoryBuilder to generate multiple SqlSessionFactory instances, but it's best not to force it, because XML's parsing resources are used for other more important things.
In the mybatis3.4.1 version, obtaining SqlSessionFactory instances in SqlSessionFactoryBuilder is as follows (each allows you to create a SqlSessionFactory instance from different resources):
SqlSessionFactory build (Reader reader) SqlSessionFactory build (Reader reader, String environment) SqlSessionFactory build (Reader reader, Properties properties) SqlSessionFactory build (Reader reader, String environment, Properties properties) SqlSessionFactory build (InputStream inputStream) SqlSessionFactory build (InputStream inputStream, String environment) SqlSessionFactory build (InputStream inputStream, Properties properties) SqlSessionFactory build (InputStream inputStream, String environment, Properties properties) SqlSessionFactory build (Configuration config)
SqlSessionFactoryBuilder complete source code
Package org.apache.ibatis.session;import java.io.IOException;import java.io.InputStream;import java.io.Reader;import java.util.Properties;import org.apache.ibatis.builder.xml.XMLConfigBuilder;import org.apache.ibatis.exceptions.ExceptionFactory;import org.apache.ibatis.executor.ErrorContext;import org.apache.ibatis.session.defaults.DefaultSqlSessionFactory;/** * Builds {@ link SqlSession} instances. * * @ author Clinton Begin * / public class SqlSessionFactoryBuilder {public SqlSessionFactory build (Reader reader) {return build (reader, null, null);} public SqlSessionFactory build (Reader reader, String environment) {return build (reader, environment, null);} public SqlSessionFactory build (Reader reader, Properties properties) {return build (reader, null, properties) } / / Core method-public SqlSessionFactory build (Reader reader, String environment, Properties properties) {try {/ / it is very important here to parse the relevant configuration of mybatis, as well as the nodes in XXXMapper.xml and the annotations in xxxxMapper.java XMLConfigBuilder parser = new XMLConfigBuilder (reader, environment, properties); return build (parser.parse ());} catch (Exception e) {throw ExceptionFactory.wrapException ("Error building SqlSession.", e) } finally {ErrorContext.instance (). Reset (); try {reader.close ();} catch (IOException e) {/ / Intentionally ignore. Prefer previous error. }} public SqlSessionFactory build (InputStream inputStream) {return build (inputStream, null, null);} public SqlSessionFactory build (InputStream inputStream, String environment) {return build (inputStream, environment, null);} public SqlSessionFactory build (InputStream inputStream, Properties properties) {return build (inputStream, null, properties);} / / Core method II public SqlSessionFactory build (InputStream inputStream, String environment, Properties properties) {try {XMLConfigBuilder parser = new XMLConfigBuilder (inputStream, environment, properties) Return build (parser.parse ());} catch (Exception e) {throw ExceptionFactory.wrapException ("Error building SqlSession.", e);} finally {ErrorContext.instance (). Reset (); try {inputStream.close ();} catch (IOException e) {/ / Intentionally ignore. Prefer previous error. Core method 3, create a default DefaultSqlSessionFactory public SqlSessionFactory build (Configuration config) {return new DefaultSqlSessionFactory (config) based on the parsed Configuration;}}
There are two core methods for creating DefaultSqlSessionFactory, providing a number of overloaded methods, and finally calling core method 3 to get a default DefaultSqlSessionFactory instance.
[2] SqlSessionFactory
Once SqlSessionFactory is created, SqlSessionFactory will always exist throughout the application process. So there is no reason to destroy and recreate it, and it is not recommended to create a SqlSessionFactory multiple times when an application is running.
So the best scope for SqlSessionFactory is Application.
There are many ways to do this, and the easiest way is singleton mode or static singleton mode. However, this is not widely approved and useful. Instead, it is better to use Google Guice or Spring for dependency reflection. These frameworks allow you to generate managers to manage the singleton life cycle of SqlSessionFactory.
SqlSessionFactory API source code package org.apache.ibatis.session;import java.sql.Connection;/** creates a sqlsession instance based on a database connection or data source. Based on what creates * Creates an {@ link SqlSession} out of a connection or a DataSource * @ author Clinton Begin * / public interface SqlSessionFactory {SqlSession openSession (); SqlSession openSession (boolean autoCommit); SqlSession openSession (Connection connection); SqlSession openSession (TransactionIsolationLevel level); SqlSession openSession (ExecutorType execType) SqlSession openSession (ExecutorType execType, boolean autoCommit); SqlSession openSession (ExecutorType execType, TransactionIsolationLevel level); SqlSession openSession (ExecutorType execType, Connection connection); Configuration getConfiguration ();}
Its default implementation class is DefaultSqlSessionFactory.
There are six ways for SqlSessionFactory to create SqlSession instances
SqlSessionFactory has six ways to create SqlSession instances. Generally speaking, when you choose one of these methods, you need to consider the following points:
Transaction processing: do you want to use transaction scope in session scope or use autocommit (auto-commit)? (for many database and / or JDBC drivers, it is tantamount to turning off transaction support)
Database connection: do you want MyBatis to help you get a connection from a configured data source, or do you want to use your own connection?
Statement execution: do you want MyBatis to reuse PreparedStatement and / or batch update statements (including insert and delete statements)?
Based on the above requirements, the following overloaded openSession () methods are available.
SqlSession openSession () SqlSession openSession (boolean autoCommit) SqlSession openSession (Connection connection) SqlSession openSession (TransactionIsolationLevel level) SqlSession openSession (ExecutorType execType) SqlSession openSession (ExecutorType execType, boolean autoCommit) SqlSession openSession (ExecutorType execType,TransactionIsolationLevel level) SqlSession openSession (ExecutorType execType, Connection connection) Configuration getConfiguration
The default openSession () method has no parameters, and it creates a SqlSession with the following characteristics:
The transaction scope will be opened (that is, it will not commit automatically).
The Connection object will be obtained from the DataSource instance configured by the current environment.
The transaction isolation level will use the default settings of the driver or data source.
Preprocessing statements are not reused and updates are not processed in batches.
I believe you can already know the difference between these methods from the method signature. The autocommit function is enabled by passing the true value to the autoCommit optional parameter. To use your own Connection instance, pass a Connection instance to the connection parameter. Note that we do not provide a method to set both Connection and autoCommit because MyBatis decides whether or not to enable autoCommit based on the Connection passed in. For transaction isolation levels, MyBatis uses a Java enumeration wrapper called TransactionIsolationLevel, which supports five isolation levels of JDBC (NONE, READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, and SERIALIZABLE) and behaves as expected.
You may be unfamiliar with the ExecutorType parameters. This enumeration type defines three values:
ExecutorType.SIMPLE: this type of actuator has no special behavior. It creates a new preprocessing statement for the execution of each statement.
ExecutorType.REUSE: this type of executor reuses preprocessing statements.
ExecutorType.BATCH: this type of executor executes all update statements in batches, and if SELECT executes among multiple updates, it will separate multiple update statements if necessary for ease of understanding.
Batch operations are executed by sending sql statements to the database after session.commit (). If we want it to be executed in advance to facilitate subsequent query operations to obtain data, we can use the sqlSession.flushStatements () method to flush it directly to the database for execution.
Note that there is another method we haven't mentioned in SqlSessionFactory, which is getConfiguration (). This method returns an instance of Configuration, which you can use at run time to check the configuration of MyBatis.
Tip: if you have used an older version of MyBatis, you may remember that session, transactions, and batch operations are independent of each other. This is not the case in the new version. All three mentioned above are included in the session domain. You don't have to handle transactions or batch operations separately to get all the results you want.
The default openSession () method has no parameters, and it creates a
Starts a transaction (that is, does not commit automatically)
The connection object is obtained from the data source instance configured by the active environment.
The transaction isolation level will use the default settings of the driver or data source.
Preprocessing statements are not reused and updates are not processed in batches.
[3] non-thread-safe SqlSession
The main Java interface that uses MyBatis is SqlSession. You can use this interface to execute commands, get mapper instances, and manage transactions.
Each thread has its own SqlSession instance, and SqlSession instances cannot be shared and are not thread safe. Therefore, it is best to use the request scope or the method body scope.
Do not use a static variable of a class to refer to an instance of SqlSession, or even an instance variable of a class. Otherwise, there will be thread safety issues.
Never reference SqlSession in a managed domain
For example, in HttpSession in Servlet. If you are using the WEB framework, you should let SqlSession follow the similar scope of HTTP requests. That is, after receiving a HTTP request, open SqlSession and turn off the SqlSession as soon as a response is returned. It is very important to turn off SqlSession, and you must make sure that SqlSession closes properly in the body of the finally method.
SqlSession can directly call the id of the method for database operation, but we generally recommend using SqlSession to obtain the proxy class of the Dao interface and execute the method of the proxy object, so that the type checking operation can be carried out more safely.
As shown in the following code, the method ID is called for database operation:
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory (); SqlSession openSession = sqlSessionFactory.openSession (); try {Employee employee = openSession.selectOne ("com.mybatis.EmployeeMapper.selectEmp", 1); System.out.println (employee);} finally {openSession.close ();}
As mentioned earlier, SqlSession is a very powerful class in MyBatis. It contains all methods for executing statements, committing or rolling back transactions, and getting mapper instances.
There are more than 20 methods in the SqlSession class, and for ease of understanding, we divide them into several groups.
Statement execution method
These methods are used to execute SELECT, INSERT, UPDATE, and DELETE statements defined in the SQL mapping XML file. You can quickly understand their function by name, and each method accepts the ID of the statement as well as parameter objects, which can be primitive types (support for auto-boxing or wrapper classes), JavaBean, POJO, or Map.
T selectOne (String statement, Object parameter) List selectList (String statement, Object parameter) Cursor selectCursor (String statement, Object parameter) Map selectMap (String statement, Object parameter, String mapKey) int insert (String statement, Object parameter) int update (String statement, Object parameter) int delete (String statement, Object parameter)
The only difference between selectOne and selectList is that selectOne must return an object or null value. If more than one value is returned, an exception is thrown. If you don't know how many objects will be returned, use selectList. If you need to see if an object exists, the best way is to query a count value (0 or 1). SelectMap is slightly special in that it takes one of the properties of the returned object as the key value and the object as the value value, thus converting multiple result sets to Map type values. Because not all statements require parameters, these methods have an overloaded form that does not require parameters.
Cursors (Cursor) and lists (List) return the same results, except that cursors lazily load data with the help of iterators.
The values returned by the try (Cursor entities = session.selectCursor (statement, param)) {for (MyEntity entity:entities) {/ / processing a single entity}} insert, update, and delete methods represent the number of rows affected by the statement. T selectOne (String statement) List selectList (String statement) Cursor selectCursor (String statement) Map selectMap (String statement, String mapKey) int insert (String statement) int update (String statement) int delete (String statement)
Finally, there are three advanced versions of the select method that allow you to limit the number of rows returned or provide custom result processing logic, usually used in situations where the dataset is very large.
List selectList (String statement, Object parameter, RowBounds rowBounds) Cursor selectCursor (String statement, Object parameter, RowBounds rowBounds) Map selectMap (String statement, Object parameter, String mapKey, RowBounds rowbounds) void select (String statement, Object parameter, ResultHandler handler) void select (String statement, Object parameter, RowBounds rowBounds, ResultHandler handler)
The RowBounds parameter tells MyBatis to skip the specified number of records and limits the number of results returned. The offset and limit values of the RowBounds class can only be passed in when the constructor is constructed, and cannot be modified at other times.
Int offset = 100int itself limit = 25th rows rowBounds = new RowBounds (offset, limit)
The database driver determines the query efficiency when skipping records. For best performance, it is recommended that you set the ResultSet type to SCROLL_SENSITIVE or SCROLL_INSENSITIVE (in other words: do not use FORWARD_ONLY).
The ResultHandler parameter allows you to customize the processing of the results of each row. You can add it to List, create Map and Set, or even discard each return value, leaving only the calculated statistics. You can do a lot of things with ResultHandler, which is actually the internal implementation of MyBatis to build a list of results.
Starting with version 3.4.6, ResultHandler passes the CALLABLE statement used in the REFCURSOR output parameters of the stored procedure.
Its interface is simple:
Package org.apache.ibatis.session;public interface ResultHandler {void handleResult (ResultContext
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.