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 MyBatis automatically modifies its business primary key and time

2025-04-01 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

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

What this article shares with you is about how MyBatis automatically modifies its own business key and time. The editor thinks it is very practical, so I share it with you to learn. I hope you can get something after reading this article.

I. Preface

I have been curious about how the company scaffolding automatically changes the modification time, creation time, and how to generate business primary keys when inserting or modifying the database. Today, I took a closer look at the source code of mybatis and the source code of the company. Now the experience will be summarized as follows.

Second, the plug-in mechanism of MyBatis

MyBatis uses the dynamic proxy mechanism of JavaSDK to dynamically proxy Executor, StatementHandler, PameterHandler and ResultSetHandler objects. Specifically, it uses the interceptorChain.pluginAll (executor) method to generate proxy objects.

Public Object pluginAll (Object target) {for (Interceptor interceptor: interceptors) {target = interceptor.plugin (target);} return target;}

This class, InterceptorChain, holds all the Intercpetor interceptors, which is the class we need to implement next. This plugin method is the returned proxy class object, and we often return the generated proxy class directly through the Plugin.wrap (target, this) method provided by Mybatis, which encapsulates the process of generating the proxy class. To make it easier to understand, let's look at the source code of Plugin.wrap:

Public static Object wrap (Object target, Interceptor interceptor) {Map type = target.getClass (); Class [] interfaces = getAllInterfaces (type, signatureMap); if (interfaces.length > 0) {return Proxy.newProxyInstance (type.getClassLoader (), interfaces, new Plugin (target, interceptor, signatureMap);} return target;}

I won't take a closer look at the first few lines here, which probably means to get the parameters in the @ Signature annotation on the interceptor we implemented (we may not know what the @ Signature annotation of the interceptor is, which will be explained later), get the interfaces that the proxy class needs to implement, and then there is the standard way to generate the dynamic proxy class. By the way, explain the parameters of newProxyInstance:

The first parameter represents the class loader of the dynamically generated proxy class.

The dynamically generated proxy class represented by the second parameter needs to implement the interface, and the methods of these interfaces are all handled by calling the invoke method of InvocationHander in the dynamic proxy class.

The third parameter is the implementation of InvocationHander, where Plugin is a class specifically implemented by Mybatis.

By the way: what the proxy class generated dynamically in JavaSDK actually does is initialize all the Method objects of the real class as member variables, and then implement all the interfaces of the proxy class. The logic of the interface method is very simple, that is, the corresponding Method object, as well as the above parameters of the implementation method, and the invoke method of the InvocationHander instance passed in by Proxy.newProxyInstance are handled.

Let's take a look at the invoke method of the Plugin class again:

Public Object invoke (Object proxy, Method method, Object [] args) throws Throwable {try {Set methods = signatureMap.get (method.getDeclaringClass ()); if (methods! = null & & methods.contains (method)) {return interceptor.intercept (target, method, args);} return method.invoke (target, args);} catch (Exception e) {throw ExceptionUtil.unwrapThrowable (e);}}

The general meaning is to execute the intercept method of our own interceptor according to the @ Signature annotated information flag method on the interceptor just fetched. What is passed into the intecepter method is an Invocation encapsulated by Mybatis itself, which wraps the dynamic proxy class instance, the executed method, and the method parameters. There is a proceed method that actually executes the proxied method through reflection.

From the above, we can see that we only need to create an Interceptor interface to implement the plug-in, and then Mybatis will automatically proxy the target to be proxied layer by layer. Other source code such as how to execute insert,update, how the above four objects exist in Mybatis in the end, I did not delve into, the source code is too complex. Let's directly look at how to intercept the update method of Executor, modify the incoming parameters, and then automatically update your business primary key and time.

3. Implement the plug-in / * * @ author chenzhicong * @ time 22:11 * @ description * first we must know that we are intercepting the update method of Executor, which has two parameters, one is MappedStatement, * it maintains the encapsulation of a node in xml, and the other is the parameter corresponding to the parameterType of this node. * what we implement here is that if this parameter is slightly modified by the entity we define, add the modification time and business Code * Note: * 1.Signature Note parameters explain: * Type: the class to be intercepted can be the four major objects Executor, StatementHandler, ParameterHandler and ResultSetHandler. * Method: name of the method to be intercepted * Args: what are the parameters of the method to be intercepted * the int update (MappedStatement ms, Object parameter) method of 2.Executor is the method entry for handling all insert and update * / @ Component@Log4j2@Intercepts ({@ Signature (type = Executor.class, method = "update", args = {MappedStatement.class) Object.class})}) public class MyInterceptor implements Interceptor {@ Override public Object intercept (Invocation invocation) throws Throwable {MappedStatement mappedStatement = (MappedStatement) invocation.getArgs () [0] / / only deal with the case where the parameter is MyEntity subclass Object param = invocation.getArgs () [1]; if (param = = null | |! MyEntity.class.isAssignableFrom (param.getClass () {return invocation.proceed ();} MyEntity myEntity = (MyEntity) param; / / get Sql execution type SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType () Switch (sqlCommandType) {case INSERT: if (myEntity.getCreateTime () = = null) {myEntity.setCreateTime (LocalDateTime.now ());} if (myEntity.getUpdateTime () = = null) {myEntity.setUpdateTime (LocalDateTime.now ()) } if (StringUtils.isEmpty (myEntity.getCode () {/ / the small demo here is fine with uuid, depending on the business. / / the globally unique key myEntity.setCode (UUID.randomUUID (). ToString ()) generated by the redis we use for production;} break Case UPDATE: if (myEntity.getUpdateTime () = = null) {myEntity.setUpdateTime (LocalDateTime.now ());} break;} return invocation.proceed ();} @ Override public Object plugin (Object target) {/ / return proxy class return Plugin.wrap (target, this) directly with the Plugin.wrap provided to us by MyBatis } / * this method is used to specify some properties in the Mybatis configuration file. * I don't know much about the details, so let's forget it here * / @ Override public void setProperties (Properties properties) {}}

The above is our custom plug-in, let's test it:

@ Test public void test2 () {UserJpaTest userJpaTest = new UserJpaTest (); userJpaTest.setNickName ("123"); userJpaTestMapper.insert (userJpaTest);}

Take a look at the database effect:

It shows that our custom plug-in has taken effect, and there are many additions based on this plug-in. For example, if the insert is a collection of entities, the input parameter is DefaultSqlSession.StrictMap (when StrictMap Mybatis handles the parameters for the collection or array, in which there are three keys divided into collection,list,array), and the updateByExampleSelective method encapsulated by TkMybatis, the input parameter of this method becomes the MapperMethod.ParamMap class (I don't know much about this either. When the key is record or param1, it may be our incoming record entity), these are handled in our scaffolding, because it is the company's code, it is not easy to release.

Based on the plug-in function of Mybatis, we can implement many rich and easy-to-use plug-ins, such as our commonly used PageHelper is based on this.

This is how MyBatis automatically modifies its business key and time. The editor believes that there are some knowledge points that we may see or use in our daily work. I hope you can learn more from this article. For more details, please follow the industry information channel.

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

Internet Technology

Wechat

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

12
Report