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

What is the method to call the userMapper interface directly

2025-02-25 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

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

This article focuses on "what is the method of directly calling the userMapper interface". Interested friends may wish to have a look at it. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn "what is the method of calling the userMapper interface directly"?

The old rule, first on the case code, so that we can be more familiar with how to use, have seen the Mybatis series of small partners, this code can almost be memorized.

Haha, is it an exaggeration? No exaggeration, just this line of code.

Public class MybatisApplication {public static final String URL = "jdbc:mysql://localhost:3306/mblog"; public static final String USER = "root"; public static final String PASSWORD = "123456"; public static void main (String [] args) {String resource = "mybatis-config.xml"; InputStream inputStream = null; SqlSession sqlSession = null Try {inputStream = Resources.getResourceAsStream (resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder (). Build (inputStream); sqlSession = sqlSessionFactory.openSession (); / / Today's main line of code UserMapper userMapper = sqlSession.getMapper (UserMapper.class); System.out.println (userMapper.selectById (1)) Catch (Exception e) {e.printStackTrace ();} finally {try {inputStream.close ();} catch (IOException e) {e.printStackTrace ();} sqlSession.close () }}

What's the use of looking at the source code?

Through the study of the source code, we can harvest the core ideas and framework design of Mybatis, as well as the application of design patterns.

In the first two articles, we have parsed the Mybatis configuration file to get SqlSession, so let's analyze from SqlSession to userMapper:

UserMapper userMapper = sqlSession.getMapper (UserMapper.class)

As you already know in the previous article, sqlSession here uses the default implementation class DefaultSqlSession. So we go directly to the getMapper method of DefaultSqlSession.

/ / private final Configuration configuration; / / type=UserMapper.class @ Override public T getMapper (Class type) {return configuration.getMapper (type, this);} in DefaultSqlSession

Here are three questions:

What object does the question 1:getMapper return?

As you can see above, the getMapper method calls the getMapper method in Configuration. And then we go into Configuration.

/ / protected final MapperRegistry mapperRegistry = new MapperRegistry (this) in Configuration; / type=UserMapper.class public T getMapper (Class type, SqlSession sqlSession) {return mapperRegistry.getMapper (type, sqlSession);}

Nothing is done here, but continue to call getMapper in MapperRegistry:

/ / public class MapperRegistry {/ / mainly stores the mapping private final Map of configuration information private final Configuration config; / / MapperProxyFactory private final Map > knownMappers = new HashMap (); / / get the MapperProxy object / / type=UserMapper.class,session is the current session public T getMapper (Class type, SqlSession sqlSession) {/ / here is get, then there is add or put final MapperProxyFactory mapperProxyFactory = (MapperProxyFactory) knownMappers.get (type) If (mapperProxyFactory = = null) {throw new BindingException ("Type" + type + "is not known to the MapperRegistry.");} try {/ / create instance return mapperProxyFactory.newInstance (sqlSession);} catch (Exception e) {throw new BindingException ("Error getting mapper instance. Cause: "+ e, e);}} / / this method is called when parsing the configuration file, / / type=UserMapper.class public void addMapper (Class type) {/ / determines that the type must be an interface, that is, the Mapper interface. If (type.isInterface ()) {/ / has been added, then throw a BindingException exception if (hasMapper (type)) {throw new BindingException ("Type" + type + "is already known to the MapperRegistry.");} boolean loadCompleted = false; try {/ / add knownMappers.put (type, new MapperProxyFactory (type)) to knownMappers / / create a MapperAnnotationBuilder object and parse the annotation configuration of Mapper MapperAnnotationBuilder parser = new MapperAnnotationBuilder (config, type); parser.parse (); / / tag loading completed loadCompleted = true } finally {/ / if loading is not completed, remove if (! loadCompleted) {knownMappers.remove (type);} from knownMappers

The class object of the mapper interface is stored in the MapperProxyFactory object, which is a normal class with no logic.

Two design patterns are used in the MapperProxyFactory class:

Hongmeng official Strategic Cooperation to build HarmonyOS Technology Community

Singleton mode methodCache (registered singleton mode).

Factory mode getMapper ().

Continue to look at the newInstance method in MapperProxyFactory.

Public class MapperProxyFactory {private final Class mapperInterface; private final Map methodCache = new ConcurrentHashMap (); public MapperProxyFactory (Class mapperInterface) {this.mapperInterface = mapperInterface;} public T newInstance (SqlSession sqlSession) {/ / create MapperProxy object final MapperProxy mapperProxy = new MapperProxy (sqlSession, mapperInterface, methodCache); return newInstance (mapperProxy) } / / finally create the object with JDK dynamic proxy and return protected T newInstance (MapperProxy mapperProxy) {return (T) Proxy.newProxyInstance (mapperInterface.getClassLoader (), new Class [] {mapperInterface}, mapperProxy);}}

As you can see from the code, it is still stably implemented based on JDK Proxy, and the InvocationHandler parameter is a MapperProxy object.

/ / UserMapper's classloader / / interface is UserMapper / / h is a mapperProxy object public static Object newProxyInstance (ClassLoader loader, Class [] interfaces, InvocationHandler h) {}

Question2: why can his method be called?

The MapperProxy object is created when the newInstance method is called above, and is the third parameter as newProxyInstance, so the MapperProxy class must implement InvocationHandler.

Enter the MapperProxy class:

/ / sure enough, the InvocationHandler interface public class MapperProxy implements InvocationHandler is implemented, Serializable {private static final long serialVersionUID =-6424540398559729838L; private final SqlSession sqlSession; private final Class mapperInterface; private final Map methodCache; public MapperProxy (SqlSession sqlSession, Class mapperInterface, Map methodCache) {this.sqlSession = sqlSession; this.mapperInterface = mapperInterface; this.methodCache = methodCache } / / calling userMapper.selectById () is essentially a call to the invoke method @ Override public Object invoke (Object proxy, Method method, Object [] args) throws Throwable {try {/ / if it is Object's methods toString (), hashCode (), etc., if (Object.class.equals (method.getDeclaringClass () {return method.invoke (this, args) } else if (method.isDefault ()) {/ / the default implementation method for later interfaces return invokeDefaultMethod (proxy, method, args);}} catch (Throwable t) {throw ExceptionUtil.unwrapThrowable (t);} / / create MapperMethod object final MapperMethod mapperMethod = cachedMapperMethod (method) / / talk about return mapperMethod.execute (sqlSession, args) in the next article;}}

That is, the getMapper method returns a JDK dynamic proxy object (type $Proxy+ number). This proxy object inherits the Proxy class and implements the proxied interface UserMpper, which holds a trigger management class of type MapperProxy.

When we call the method of UserMpper, we essentially call the invoke method of MapperProxy.

UserMapper=$Proxy6@2355 .

Why save a factory class in MapperRegistry?

It turns out that it is used to create and return proxy classes. Here is a very classic application of the agent model.

How does MapperProxy implement proxying for interfaces?

JDK dynamic agent

As we know, the JDK dynamic agent has three core roles:

Proxied class (that is, the implementation class)

Interface

Implement the trigger management class of InvocationHanndler, which is used to generate proxy objects.

The proxied class must implement the interface because the method is to be obtained through the interface, and the proxy class also implements this interface.

However, there is no Mapper interface implementation class in Mybatis, so how can it be proxied? It ignores the implementation class and proxies the Mapper interface directly.

MyBatis dynamic proxy:

In Mybatis, why don't JDK dynamic proxies need to implement classes?

Our purpose here is to find the statement ID in Mapper.xml directly according to an executable method to facilitate the call.

The userMapper returned is the proxy object created by MapperProxyFactory, and then this object contains the MapperProxy object

Question3: how on earth did you find Mapper.xml based on Mapper.java?

Finally, we call userMapper.selectUserById (), which essentially calls the invoke () method of MapperProxy.

Please look at the picture below:

If the Statement ID is found according to (interface + method name), this logic can be done in the InvocationHandler subclass (MapperProxy class), and there is no need to use the implementation class.

At this point, I believe you have a deeper understanding of "what is the method of directly calling the userMapper interface". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!

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