General source code reading guide Mybatis source code detailed explanation: type package

There are as many as 55 classes in the

type package

type package. When encountering such a complicated situation, we must pay attention to the classification and summary. Z3z

classification summary is a very good way to read the source code. Often the larger the number of classes, the greater the number of methods, and the more regular the classification. These originally complicated classes and methods may become very organized after being classified. After sorting out

, we divide the classes in the type package into the following six groups.

· Type processor: 1 interface, 1 basic realization class, 1 auxiliary class, 43 realization classes.

-TypeHandler: type processor interface;

-BaseTypeHandler: basic implementation of type processor;

-TypeReference: type reference device;

-*TypeHandler: 43 type handlers.

· Type registration form : 3 pcs.

-SimpleTypeRegistry: basic type registry, internal use Set to maintain a collection of all Java basic data types;

-TypeAliasRegistry: type alias registry, internal use HashMap to maintain all types of aliases and type mapping relationships;

-TypeHandlerRegistry: Type processor registry, internally maintains the mapping relationship between all types and corresponding type processors.

· Annotation category: 3.

-Alias: Use this annotation to set aliases for the class. After setting, the mapping relationship between aliases and types will be stored in TypeAliasRegistry;

-MappedJdbcTypes: Sometimes we want to use our own processor to process certain JDBC types, just create Subclass of BaseTypeHandler, and then add the annotation on it to declare the JDBC type it needs to process;

-MappedTypes: Sometimes we want to use our own processor to process certain Java types, just create a subclass of BaseTypeHandler, Then add the annotation above to declare the Java type it needs to handle.

· Exception category: one.

-TypeException: Indicates an exception related to type handling.

· Tools: 1 piece.

-ByteArrayUtils: Provide tools and methods for array conversion.

· Enumeration class: one.

-JdbcType: All JDBC types are defined in Enum, and the types are derived from java.sql.Types. Among the above classes of

, the annotation class, exception class, tool class, and enumeration class are all very simple and will not be introduced separately. The following will focus on the type processor and type registry.

template mode

Speaking of templates, everyone should be familiar with it. In general, the general framework is specified in the template, leaving only some details for users to modify and improve. Different products made using the same template all have a consistent framework. The template mode in the design mode has the same concept as the above template. In template mode, you need to use a abstract class to define the overall steps (ie templates) of a set of operations, and the subclasses of the abstract class complete the concrete realization of each step. In this way, different subclasses of the abstract class follow the same set of templates.

For example, we define a set of cleaning templates, as shown in code 8-1. It defines four major steps for all cleaning and sanitation work: prepare, implement, windup, and report.

[code 8-1]

In this way, some specific cleaning tasks can be completed based on the template. For example, Code 8-2 and Code 8-3 show the implementation of glass cleaning and blackboard cleaning, respectively.

[Code 8-2]

[Code 8-3]

can see that although the specific behaviors are different, the templates followed by WipeGlass and WipeBlackboard are the same, and both are given by the Cleaning class. This is the role of the template pattern, that is, a framework for a set of operations is determined, and subclasses only need to define specific implementations on the basis of this framework. The base class and implementation class of

type processor

type processor

as an ORM framework, processing the mapping between Java objects and database relations is an important part of the work of MyBatis. However, there are various types of data such as Integer, String, and Data in Java, and various types of data such as varchar, longvarchar, and tinyint exist in the database. Different types of fields require different reading and writing methods, so corresponding processing methods need to be adopted for different types of fields.

For example, User has several attributes as shown in code 8-4.

[Code 8-4]

When reading and assigning the properties of the User object, you need to use Integer related processing methods to manipulate the id and sex properties, and String related processing methods to manipulate the name and schoolName properties. In the type package,

encapsulates the processing method corresponding to each type in the corresponding type handler TypeHandler. For example, IntegerTypeHandler is responsible for processing the Integer type. The

type package has a total of 43 type handlers, and the names of these type handlers also end with "TypeHandler". And TypeHandler and BaseTypeHandler are type processor interface and type processor base class respectively.

Figure 8-1 shows the class diagram related to the type processor in the type package.

Figure 8-1 Type processor class diagram

TypeHandler is an interface that defines several abstract methods for data processing operations. BaseTypeHandler inherits the TypeHandler interface and implements the interface in TypeHandler.

adopts the template pattern in the design of type processor related classes. BaseTypeHandler is the base class of all types of processors and defines the template framework. In each specific implementation class, specific details are implemented.

takes the getResult (ResultSet, String) method in the BaseTypeHandler shown in code 8-5 as an example. This method completes the unified work such as exception handling, while the getNullableResult (ResultSet, String) operation related to the specific type is handed over through the abstract method The specific type processor is implemented. This is the typical template pattern.

[Code 8-5]

BaseTypeHandler There are only four abstract methods handed over to concrete type handlers. Each type of processor needs to implement these four methods. · Void setNonNullParameter (PreparedStatement, int, T, JdbcType): write a non-null value to the specified variable position in the PreparedStatement object;

· T getNullableResult (ResultSet, String): read a possibility from the ResultSet according to the field name Data that is null;

·T getNullableResult (ResultSet, int): read a possible null data from the ResultSet according to the field number;

·T getNullableResult (CallableStatement, int): Read a possibly null data from the CallableStatement according to the field number.

Because the above abstract methods are related to specific types, there is a generic parameter T. In each type of processor, the value of the generic parameter is given. Take IntegerTypeHandler as an example, it sets the generic parameter value to Integer. The source code of the IntegerTypeHandler class is shown in code 8-6.

[Code 8-6] In code 8-6 of

, the type handled by IntegerTypeHandler is Integer, which indicates that the getNullableResult method gives an Integer result.

TypeReference class

43 type processors can process data of different Java types, and these type processors are all subclasses of the TypeHandler interface, so they can all be used as TypeHandlers.

Will there be a problem when MyBatis gets a TypeHandler, but I don’t know which Java type of processor it is used to handle?

In order to solve this problem, MyBatis defines a TypeReference class. It can determine the target type a TypeHandler is used to handle. And its judgment method is also very simple: take out the type of the generic parameter T in the TypeHandler implementation class, the type of this value is also the target type that the TypeHandler can handle. This function is implemented by the getSuperclassTypeParameter method, which can store the found target type in the rawType attribute of the class. The annotated source code of the getSuperclassTypeParameter method is shown in code 8-7.

[Code 8-7]

TypeReference class is the parent class of BaseTypeHandler, so all type processors inherit the function of TypeReference. This means that by calling the getSuperclassTypeParameter method on any type processor, you can get the target type used by the processor. After

type registry

defines a large number of type processors, MyBatis also needs to quickly find the type processor corresponding to the type of data when encountering a certain type of data. This process requires the help of various types of registry. There are three type registries in the

type package: SimpleTypeRegistry, TypeAliasRegistry and TypeHandlerRegistry.

SimpleTypeRegistry is a very simple registry that uses a SIMPLE_TYPE_SET variable to maintain all basic Java types. The assignment in SIMPLE_TYPE_SET is performed in the static code block, as shown in code 8-8. This shows that after the initialization of SimpleTypeRegistry, all basic Java types have been maintained in SIMPLE_TYPE_SET.

[Code 8-8]

TypeAliasRegistry is a type alias registry, which uses the typeAliases variable to maintain the correspondence between the type's alias and the type. With this registry, we can use type aliases to refer to specific types in many situations. TypeHandlerRegistry is the core of the three registry, and the correspondence between data types and related processors is maintained by it.

Before introducing it, let’s introduce Java data type and JDBC data type. Assuming that there is a "String name" attribute in an object, the data type of the name attribute in Java is String.

However, it may be char, varchar, tinytext, text and other types in the database. Therefore, Java data types and JDBC data types are not a one-to-one relationship, but a one-to-many relationship. After understanding this, we directly give the annotated properties of the TypeHandlerRegistry class in Code 8-9.

[Code 8-9]

After understanding the properties of TypeHandlerRegistry, you can also guess how to get a type processor, which is actually a two-mapping process.

· According to the incoming Java type, call the getJdbcHandlerMap sub-method to find the corresponding jdbcTypeHandlerMap and return. · Based on jdbcTypeHandlerMap, find the corresponding TypeHandler according to the JDBC type.

For example, given that the Java type is String and the JDBC type is varchar, a type processor can be uniquely determined. The getTypeHandler method completes this process, and the annotated source code of the method is shown in code 8-10.

[Code 8-10]

SimpleTypeRegistry, TypeAliasRegistry, TypeHandlerRegistry These three type registries exist, so that MyBatis can not only find its type processor according to the type, but also find the corresponding type processor according to the type alias.

This article explains the general source code reading guide mybatis source code detailed explanation: type package

  1. The next article explains the general source code reading guide mybatis source code detailed explanation: io package;
  2. friends who think the article is good can forward this article. Edited;
  3. thank you all for your support