Understanding MyBatis @MapKey Annotation: Usage, Example, and Internal Mechanism
This article explains how to use the MyBatis @MapKey annotation to map query results into a Java Map, provides a concrete code example, and delves into the internal processing steps—including MapperProxy, MapperMethod, MethodSignature, and DefaultMapResultHandler—that enable this functionality.
When developing with MyBatis, you may need to extract a specific record from a large data set. Common approaches include adding WHERE clauses in SQL, iterating over all results in Java, or using the @MapKey annotation to store results directly in a Map keyed by a chosen field.
Among these, the @MapKey method is the focus of this article. It allows MyBatis to map query results into a Map where the key is a property of the result object (e.g., id) and the value is the full object.
Prerequisite
In MyBatis, @MapKey is used when you want the result of a query to be a Map. The annotation tells MyBatis which property of the result object should be used as the map key.
Example Usage of @MapKey
Assume a User class with fields id, age, and name. To retrieve all users and map them by id, you can define a mapper interface as follows:
@Mapper
public interface EmployeeMapper {
@Select("SELECT id, name, age FROM test_user")
@MapKey("id")
Map<Integer, User> getAllUser();
}Calling getAllUser() returns a Map where each entry's key is the user's id and the value is the corresponding User object.
The annotation simplifies the transformation of a result set into a map without manual iteration.
Underlying Principle of @MapKey
MyBatis parses the @MapKey annotation during the configuration phase. The parsing is delegated to the MethodSignature class, which extracts the key attribute and stores it in a private field mapKey. When the mapper method is invoked, the following chain occurs:
MyBatis uses MapperProxy to intercept the method call.
The proxy creates a MapperMethod instance that determines the SQL statement, parameters, and return type. MapperMethod invokes MyBatis's execution layer, which runs the SQL and obtains a ResultSet.
The result set is processed by DefaultMapResultHandler, whose handleResult method extracts the value of the configured mapKey from each row and puts the row object into the resulting Map as value.
public void handleResult(ResultContext<? extends V> context) {
final V value = context.getResultObject();
final MetaObject mo = MetaObject.forObject(value, objectFactory, objectWrapperFactory, reflectorFactory);
final K key = (K) mo.getValue(mapKey);
mappedResults.put(key, value);
}Thus, the annotation drives two main steps: (1) parsing the key field during configuration, and (2) using that field to populate the map while iterating over the result set.
Summary
The @MapKey annotation in MyBatis provides a concise way to transform query results into a Map keyed by a chosen property. Its implementation relies on standard MyBatis components such as MapperProxy, MapperMethod, MethodSignature, and DefaultMapResultHandler, making it a straightforward yet powerful feature for backend developers.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
