SoFunction
Updated on 2025-05-22

Implementation of MyBatis Mapper Mapper Mapping File Configuration

Common attribute tags

The role of namespace

In MyBatis, the namespace in Mapper is used to bind Dao interface, that is, interface-oriented programming. The value of the namespace attribute must be consistent with the fully qualified name of the corresponding Mapper interface.

The advantage of namespace is that when namespace is used, you can implement the class without writing interfaces. The business logic will directly find the corresponding SQL statement through this binding for corresponding data processing.

Common label introduction

  • insert – map insert statement
  • update – map update statement
  • delete – map delete statement
  • select – Mapping query statement
  • sql - Reusable statement blocks that can be referenced by other statements
  • resultMap - determines the correspondence between entity class attributes and fields in the table

parametetType property

exist<insert>,<update>,<select>,<delete>In the tag, you can passparameterTypeSpecify the type of input parameter, the type can bePackaging types of simple types, hashmap, pojo

parameterTypeThe attribute isCan be omittedof,MyBatis frameworkCan be based onSqlSessionParameters of the method in the interface to determine the actual data type of the input parameters.

resultType property

  • The resultType property has a tag. It is responsible for mapping the query results.
  • The resultType property can specify a primitive type or an entity class type.
  • The resultType property cannot be used withresultMap propertyAppears at the same time.

resultMap

In the MyBatis framework, attributes with the same name are positioned based on the field names in the table to the entity class. If the entity class attribute name is inconsistent with the field names in the table, it cannot be automatically corresponded. At this time, resultMap can be used to re-establish the corresponding relationship between the entity class and the field name.

&lt;!--mybatis-configFile configuration,Aliases can be defined for some classes--&gt;
&lt;!--&lt;typeAliases&gt;
    &lt;typeAlias type="" alias="emp"&gt;&lt;/typeAlias&gt;
&lt;/typeAliases&gt;--&gt;
&lt;!-- typeUse alias in the attribute without using the full path --&gt;
&lt;resultMap  type="emp"&gt;
    &lt;id property="empId" column="emp_id"&gt;&lt;/id&gt;
    &lt;result property="empName" column="emp_name"&gt;&lt;/result&gt;
    &lt;result property="empSalary" column="emp_salary"&gt;&lt;/result&gt;
&lt;/resultMap&gt;
&lt;select  resultMap="empMapper"&gt;
    select * from t_emp
&lt;/select&gt;

sql

  • sql:A common SQL code can be written in it to extract duplicate code. Use tags when using this code
  • id:For the extracted SQL code, take an id to identify it
&lt;!-- Public code --&gt;
&lt;sql &gt;
    &lt;!-- select * from t_emp --&gt;
    select emp_id empId,emp_name empName,emp_salary empSalary from t_emp
&lt;/sql&gt;
    
&lt;!--selectTagsidCorrespond to the method name of the interface,resultTypeand return result encapsulationBeanConsistent--&gt;
&lt;select  resultType=""&gt;
    &lt;!-- include:Used to load and extract publicsqlStatement,and&lt;sql&gt;Tag correspondence
           refid:fill in&lt;sql&gt;In the tagidproperty--&gt;
    &lt;include ref&gt;&lt;/include&gt;
    where emp_id=#{empId}
&lt;/select&gt;
    
&lt;select  parameterType="Emp" resultType="emp"&gt;
    &lt;!-- 引入Public code --&gt;
    &lt;include ref&gt;&lt;/include&gt;
    &lt;!-- whereLabel:onewhere条件Statement,Usually and&lt;if&gt;Label混合使用 --&gt;
    &lt;where&gt;
        &lt;!-- ifLabel:执行one判断Statement,成立才会执行Label体内的sqlStatement,test:写上条件判断Statement
        Notice:这里每oneifTry to add it beforeand,如果你是第one条件,The framework will help you automaticallyandIntercept,
            If it's the secondifCan't be omittedand--&gt;
        &lt;if test="empId != null and empId != ''"&gt;
            and emp_id=#{empId}
        &lt;/if&gt;
        &lt;if test="empName != null and empName != ''"&gt;
            and emp_name like '%${empName}%'
        &lt;/if&gt;
    &lt;/where&gt;
&lt;/select&gt;

Data input

Get parameters in SQL statement

#{} way

Mybatis will put the SQL statement in the configuration file during the run process.#{}Convert to?Placeholder, sent to the database for execution.

SQL in configuration file

<delete  parameterType="int">
    delete from t_emp where emp_id=#{empId}
</delete>

The actual SQL execution

delete from t_emp where emp_id=?

${} way

Mybatis will be run during the process and will be based on${}Spelling string

SQL statements in configuration files

<select  resultType="">
    select emp_id empId,emp_name empName,emp_salary empSalary from t_emp where emp_name like '%${empName}%'
</select>

Mapper interface

Note: Since the method name in the Mapper interface is the id as the SQL statement label and cannot be repeated, methods with duplicate names cannot appear in the Mapper interface, and overloading is not allowed!

  • #{}: Precompilation method can prevent SQL injection

  • ${}: Using direct assignment method, SQL injection attack cannot be prevented

Single simple type parameter

Abstract methods in the Mapper interface

Employee selectEmployee(Integer empId);

Mapping configuration file: At this time, parameters are obtained in SQL statements#

<select  resultType="">
    select emp_id empId,emp_name empName,emp_salary empSalary from t_emp where emp_id=#{empId}
</select>

Multiple simple type parameters

Abstract methods in the Mapper interface:At this time, each method needs to be named using Param annotation

int updateEmployee(@Param("empId") Integer empId,@Param("empSalary") Double empSalary);

Mapping configuration files:At this time, the parameters are obtained in the SQL statement#

<update >
    update t_emp set emp_salary=#{empSalary} where emp_id=#{empId}
</update>

Entity class type parameters

Abstract methods in the Mapper interface:

int insertEmployee(Employee employee);

Mapping configuration files:At this time, SQL statements get parameters#{name corresponding to getXXX method, the first letter is changed to lowercase}

<insert >
    insert into t_emp(emp_name,emp_salary) values(#{empName},#{empSalary})
</insert>

Mybatis will#{}The data passed in is processed intogetXxx()Method, call this method in entity class object through reflection, thereby obtaining the corresponding data. Fill in the #{} position.

Map type parameters

Abstract methods in the Mapper interface:

int updateEmployeeByMap(Map<String, Object> paramMap);

Mapping configuration file:At this time, the SQL statement obtains parameters#

<update >
    update t_emp set emp_salary=#{empSalaryKey} where emp_id=#{empIdKey}
</update>

Data output

Data output is a method of querying data to return query results.

Returns a single simple type of data

Abstract methods in the Mapper interface:The return value of the method is a simple data type

/**
 * Statistics of the number of employees
 * @return
 */
Long selectEmployeeCount();

Mapping configuration file:At this time the taggedresultTypeThe type corresponding to the return value type of the abstract method

&lt;!--
        Return to simple type:
        resultTypeRepresents the result type:The type returned by the result set,To beMapperThe return value types of corresponding methods in the interface are consistent
    --&gt;
&lt;select  resultType="long"&gt;
    select count(emp_id) from t_emp
&lt;/select&gt;

Return a data

Return entity class object

Abstract methods in the Mapper interface:The return value of the method isPOJOtype

Employee selectEmployee(Integer empId);

Mapping configuration file:At this time, the type of the resultType of the tag corresponds to the fully qualified name of the return value type of the abstract method

&lt;!-- Write specificSQLStatement,useidA unique tag for the attributeSQLStatement --&gt;
&lt;!-- resultTypeproperty:Specify the encapsulated query resultJavaThe full class name of the entity class --&gt;
&lt;select  resultType=""&gt;
    &lt;!-- MybatisResponsible for takingSQLStatement中的#{} part replaced with "?" placeholder -->    &lt;!-- Set an alias for each field,Let alias andJava实体类中property名一致 --&gt;
    select emp_id empId,emp_name empName,emp_salary empSalary from t_emp where emp_id=#{maomi}
&lt;/select&gt;

By aliasing the database table fields, each column of the query result corresponds to the properties in the Java entity class.

Add global configuration automatic mapping camel naming rules. Do the following configuration in Mybatis core configuration file. You can not set aliases for fields in the select statement.

&lt;!-- On a global scaleMybatisMake configuration --&gt;
&lt;settings&gt;
    &lt;!-- Specific configuration --&gt;
    &lt;!-- You can view the configuration items that can be used from the class --&gt;
    &lt;!-- WillmapUnderscoreToCamelCaseThe attribute is configured astrue,Indicates that automatic mapping camel naming rules are enabled --&gt;
    &lt;!-- Rules require database table fields to be named:word_word --&gt;
    &lt;!-- Rules RequirementsJavaNaming method of entity class attribute name:Camel naming with lowercase initial letter --&gt;
    &lt;setting name="mapUnderscoreToCamelCase" value="true"/&gt;
&lt;/settings&gt;

Return to Map type

The fields returned by SQL queries do not correspond to any existing entity class and cannot be encapsulated into entity class objects. If it can be encapsulated into entity class type, the Map type will not be used.

Abstract methods in the Mapper interface:The return value of the method is Map type

/**
 * Query employee information based on empId and encapsulate the result set into the map
 * @param empId
 * @return
 */
Map selectEmployeeMapByEmpId(Integer empId);

Mapping configuration file:At this time the taggedresultTypeThe type ofmap

&lt;!--
        returnMaptype:
        resultType表示结果type: that isMapFully qualified name or alias
    --&gt;
&lt;select  resultType="map"&gt;
    select * from t_emp where emp_id=#{empId}
&lt;/select&gt;

Return multiple rows of data

Return to List<POJO>

The query result returns multiple entity class objects, and you hope to return multiple entity class objects in the List collection. There is no need for any special processing at this time, and the entity class type is still set in the resultType property.

Abstract methods in the Mapper interface:The return value of the method isList<POJO>

List<Employee> selectAll();

Mapping configuration file:At this time the taggedresultTypeThe type ofPOJO ClassFully qualified name

<!-- List<Employee> selectAll(); -->
<select  resultType="">
    select emp_id empId,emp_name empName,emp_salary empSalary from t_emp
</select>

Return to List<Map>

The query result returns multiple Map objects, and you want to return multiple Map objects in the List collection. There is no need for any special processing at this time, just set the map in the resultType property.

Abstract methods in the Mapper interface:The return value of the method isList<Map>type

List<Map> selectAllMap();

Mapping configuration files:At this time the taggedresultTypeThe type ofmap

<select  resultType="map">
    select emp_id empId,emp_name empName,emp_salary empSalary
    from t_emp
</select>

Return to the auto-increment key

Use scenarios

For example: Save order information. The Order object needs to be saved andList<OrderItem>. in,OrderItemThe corresponding database table contains a foreign key pointing to the primary key of the corresponding table of Order.

SaveList<OrderItem>When using the following SQL:

insert into t_order_item(item_name,item_price,item_count,order_id) values(...)

What you need to use hereorder_id, is savingOrder objectWhen the database table isSelf-increase methodThe generated method requires a special method to obtain this self-increased primary key value.

Implementation plan

Abstract methods in the Mapper interface:

int insertEmployee(Employee employee);

Mapping configuration files:

&lt;!-- int insertEmployee(Employee employee); --&gt;
&lt;!-- useGeneratedKeysAttribute literally means“Use the generated primary key” --&gt;
&lt;!-- keyPropertyAttributes can specify the corresponding attribute name of the primary key in the entity class object.,MybatisThe obtained primary key value will be stored in this property --&gt;
&lt;insert  useGeneratedKeys="true" keyProperty="empId"&gt;
    insert into t_emp(emp_name,emp_salary)
    values(#{empName},#{empSalary})
&lt;/insert&gt;

Junit test code:

@Test
public void testSaveEmp() {

    EmployeeMapper employeeMapper = ();
    
    Employee employee = new Employee();
        
    ("john");
    (666.66);
    
    (employee);
    //Print automatically returns the primary key value stored in the object    ("() = " + ());

}

Notice:

Mybatis sets the value of the autoincrement primary key into the entity class object, rather than returning it as the return value of the Mapper interface method.

Another way to do it

&lt;insert &gt;
    insert into t_emp (emp_name,emp_salary) values (#{empName},#{empSalary})
    &lt;!--
            keyColumn="emp_id"The column name that represents the primary key to query
            keyProperty="empId"Indicates that the query primary key value is assigned toJavaBeanWhich attribute of
            resultType="int"Indicates the result type of the query
            order="AFTER" Indicates that this query is executedinsertBefore or after?IfAFTERAfter the,BEFOREIndicates before
        --&gt;
    &lt;selectKey keyColumn="emp_id" keyProperty="empId" resultType="int" order="AFTER"&gt;
        select last_insert_id()
    &lt;/selectKey&gt;
&lt;/insert&gt;

How to get primary key value in databases that do not support auto-increment primary key

For databases that do not support auto-incremental primary keys (such as Oracle), you can useselectKey child element: the selectKey element will run firstid Will be set, and then the insert statement will be called

<insert 
parameterType=""  
databaseId="oracle">
<selectKey order="BEFORE" keyProperty="id"
resultType="integer">
select employee_seq.nextval from dual
</selectKey>    
insert into orcl_employee(id,last_name,email,gender) values(#{id},#{lastName},#{email},#{gender})
</insert>

or:

<insert 
parameterType=""  
databaseId="oracle">
<selectKey order="AFTER" keyProperty="id"
resultType="integer">
select employee_seq.currval from dual
</selectKey>    
insert into orcl_employee(id,last_name,email,gender) values(employee_seq.nextval,#{lastName},#{email},#{gender})
</insert>

The corresponding relationship between the field and entity class attributes of the result set

Automatic mapping

MybatisMaking result sets andPOJOWhen the class mapping relationship is performed, the field name of the result set will be automatically changed toPOJOThe attribute name (actually, it is andgetXXX method) perform corresponding mapping, and the data of the result set will be automatically mapped toPOJOThe attribute of the same name in the object;
So when we encounter the table's field name andPOJOWhen the attribute names are inconsistent, we can alias the fields of the result set when writing the query statement, so that the alias will be used withPOJOThe attribute names of the same as that ensure the correct mapping of the result set

Automatically identify camel naming rules for global configuration

Because the naming rules of fields in our table adopt_,andPOJOThe attribute name naming rule adopts camel nomenclature, so we always need to alias the fields of the query when executing the query statement to ensure the correct result set mapping

Mybatis frameworkOf course, this problem has also been noticed, so it provides a configuration that automatically recognizes camel naming rules. As long as we do this configuration, all global query statements will automatically recognize camel naming rules.

existMybatisThe global configuration file is added to the following configuration:

&lt;!-- usesettingsrightMybatisSet globally --&gt;
&lt;settings&gt;
    &lt;!-- Willxxx_xxxSuch column names are automatically mapped toxxXxxThe attribute name of the camel-like name --&gt;
    &lt;setting name="mapUnderscoreToCamelCase" value="true"/&gt;
&lt;/settings&gt;

Alias ​​can be used in SQL statements:

<!-- Employee selectEmployee(Integer empId); -->
<select  resultType="">
    select emp_id,emp_name,emp_salary from t_emp where emp_id=#{empId}
</select>

Manual mapping

useresultMapTags manually specify the result set field andPOJOThe mapping relationship of attributes allows you to map the result sets very flexibly.

&lt;!--
        Manual mapping:passresultMapTag configuration mapping rules
            1. idproperty:表示这个Manual mapping规则的唯一表示
            2. typeproperty: 表示这个Manual mapping规则是将结果集映射给哪个类的对象,that isJavaBeanFully qualified name of the class
        resultMapLabel中的子Labelthat is一一指定映射规则:
            1. idLabel:Specify the mapping rules for primary keys
            2. resultLabel:Specify mapping rules that are not primary keys
        idLabel和resultLabel的property:
            1. column:The field name of the result set to be mapped
            2. property:To be mappedJavaBean的property名
    --&gt;
&lt;resultMap  type=""&gt;
    &lt;id column="emp_id" property="id"/&gt;
    &lt;result column="emp_name" property="name"/&gt;
    &lt;result column="emp_salary" property="salary"/&gt;
&lt;/resultMap&gt;
&lt;!--
        existselectLabel中passresultMapproperty来指定使用哪个Manual mapping规则
    --&gt;
&lt;select  resultMap="EmployeeInfoMap"&gt;
select * from t_emp where emp_id=#{empId}
&lt;/select&gt;

Multi-table association query

Physical Modeling

CREATE TABLE `t_customer` (
`customer_id` INT NOT NULL AUTO_INCREMENT,
`customer_name` CHAR(100),
PRIMARY KEY (`customer_id`)
);
CREATE TABLE `t_order` (
`order_id` INT NOT NULL AUTO_INCREMENT,
`order_name` CHAR(100),
`customer_id` INT,
PRIMARY KEY (`order_id`)
);
INSERT INTO `t_customer` (`customer_name`) VALUES ('c01');
INSERT INTO `t_customer` (`customer_name`) VALUES ('c02');
INSERT INTO `t_order` (`order_name`, `customer_id`) VALUES ('o1', '1');
INSERT INTO `t_order` (`order_name`, `customer_id`) VALUES ('o2', '1');
INSERT INTO `t_order` (`order_name`, `customer_id`) VALUES ('o3', '1');
INSERT INTO `t_order` (`order_name`, `customer_id`) VALUES ('o4', '2');
INSERT INTO `t_order` (`order_name`, `customer_id`) VALUES ('o5', '2');

t_customerTable andt_orderRepresents a one-to-many relationship, otherwiset_orderTable andt_customerTables can be regarded as one-to-one or many-to-one relationships

One-to-one or many-to-one query

Task

Query the order information based on the order ID, and query the customer information to which the order belongs, encapsulate the query result set into the Order object

POJO encapsulation result set

public class Order {
    private Integer orderId;
    private String orderName;
    //Indicate the one-to-one relationship between Order and Customer    private Customer customer;
}

public class Customer {
    private Integer customerId;
    private String customerName;
}

Interface method

public interface OrderMapper{
    Order findByOrderId(Integer orderId);
}

Configure in global configuration files

&lt;!--Global configuration automatically map camel naming--&gt;
&lt;settings&gt;
&lt;setting name="mapUnderscoreToCamelCase" value="true"/&gt;
&lt;/settings&gt;

    &lt;!--Alias ​​for entity classes--&gt;
    &lt;typeAliases&gt;
        &lt;package name=""/&gt;
    &lt;/typeAliases&gt;
        
    &lt;!-- Mapperregister:SpecifyMybatisThe specific location of the map file --&gt;
    &lt;!-- mappersLabel:Configure a specificMapperMapping files --&gt;
    &lt;!-- resourceproperty:SpecifyMapperMapping files的实际存储位置,Here you need to use a classpath root directory
    &lt;mappers&gt;
        &lt;!-- All packagedMapperThe configuration file will be loaded automatically、register,More convenient。 --&gt;
        &lt;package name=""/&gt;
    &lt;/mappers&gt;

Mapping configuration files

&lt;?xml version="1.0" encoding="UTF-8" ?&gt;
&lt;!DOCTYPE mapper
        PUBLIC "-////DTD Mapper 3.0//EN"
        "/dtd/"&gt;
&lt;mapper namespace=""&gt;
    &lt;resultMap  type="Order" autoMapping="true"&gt;
        &lt;!-- autoMappingThe property is set totrueTurn on automatic mapping --&gt;
        &lt;association property="customer" javaType="Customer"&gt;
            &lt;id column="customer_id" property="customerId"&gt;&lt;/id&gt;
            &lt;result column="customer_name" property="customerName"&gt;&lt;/result&gt;
        &lt;/association&gt;
    &lt;/resultMap&gt;
    &lt;select  resultMap="order"&gt;
        select * from t_order o left join t_customer c on o.customer_id=c.customer_id where order_id=#{orderId}
    &lt;/select&gt;
&lt;/mapper&gt;

One-to-many query

Task

Query customer information based on the customer's ID and query all order information of the customer, encapsulate the query order information result set into the Customer object

POJO encapsulation result set

public class Customer {
    private Integer customerId;
    private String customerName;
    //One-to-many relationship between customer and order    private List&lt;Order&gt; orderList;
}

public class Order {
    private Integer orderId;
    private String orderName;
}

Abstract methods in CustomerMapper interface

public interface CustomerMapper {
    Customer findCustomerAndOrders(Integer customerId);
}

Mapping configuration files

&lt;?xml version="1.0" encoding="UTF-8" ?&gt;
&lt;!DOCTYPE mapper
        PUBLIC "-////DTD Mapper 3.0//EN"
        "/dtd/"&gt;
&lt;mapper namespace=""&gt;
    &lt;resultMap  type="Customer" &gt;
        &lt;id column="customer_id" property="customerId"/&gt;
        &lt;result column="customer_name" property="customerName"/&gt;
        &lt;collection property="orderList" ofType="Order" autoMapping="true"&gt;
            &lt;!--
            Perform one-to-many mapping,usecollectionLabel
                ofTypeAttribute refers toorderListGenerics of
            --&gt;
        &lt;/collection&gt;
    &lt;/resultMap&gt;
    &lt;select  resultMap="customer"&gt;
        SELECT * FROM t_customer c,t_order o WHERE o.customer_id=c.customer_id AND c.customer_id=#{customerId}
    &lt;/select&gt;
&lt;/mapper&gt;

This is the end of this article about the implementation of MyBatis Mapper mapping file configuration. For more related contents of MyBatis Mapper mapping file configuration, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!