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 passparameterType
Specify the type of input parameter, the type can bePackaging types of simple types, hashmap, pojo
。
parameterType
The attribute isCan be omitted
of,MyBatis framework
Can be based onSqlSession
Parameters 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 with
resultMap property
Appears 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.
<!--mybatis-configFile configuration,Aliases can be defined for some classes--> <!--<typeAliases> <typeAlias type="" alias="emp"></typeAlias> </typeAliases>--> <!-- typeUse alias in the attribute without using the full path --> <resultMap type="emp"> <id property="empId" column="emp_id"></id> <result property="empName" column="emp_name"></result> <result property="empSalary" column="emp_salary"></result> </resultMap> <select resultMap="empMapper"> select * from t_emp </select>
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
<!-- Public code --> <sql > <!-- select * from t_emp --> select emp_id empId,emp_name empName,emp_salary empSalary from t_emp </sql> <!--selectTagsidCorrespond to the method name of the interface,resultTypeand return result encapsulationBeanConsistent--> <select resultType=""> <!-- include:Used to load and extract publicsqlStatement,and<sql>Tag correspondence refid:fill in<sql>In the tagidproperty--> <include ref></include> where emp_id=#{empId} </select> <select parameterType="Emp" resultType="emp"> <!-- 引入Public code --> <include ref></include> <!-- whereLabel:onewhere条件Statement,Usually and<if>Label混合使用 --> <where> <!-- 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--> <if test="empId != null and empId != ''"> and emp_id=#{empId} </if> <if test="empName != null and empName != ''"> and emp_name like '%${empName}%' </if> </where> </select>
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 taggedresultType
The type corresponding to the return value type of the abstract method
<!-- 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 --> <select resultType="long"> select count(emp_id) from t_emp </select>
Return a data
Return entity class object
Abstract methods in the Mapper interface:
The return value of the method isPOJO
type
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
<!-- Write specificSQLStatement,useidA unique tag for the attributeSQLStatement --> <!-- resultTypeproperty:Specify the encapsulated query resultJavaThe full class name of the entity class --> <select resultType=""> <!-- MybatisResponsible for takingSQLStatement中的#{} part replaced with "?" placeholder --> <!-- Set an alias for each field,Let alias andJava实体类中property名一致 --> select emp_id empId,emp_name empName,emp_salary empSalary from t_emp where emp_id=#{maomi} </select>
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.
<!-- On a global scaleMybatisMake configuration --> <settings> <!-- Specific configuration --> <!-- You can view the configuration items that can be used from the class --> <!-- WillmapUnderscoreToCamelCaseThe attribute is configured astrue,Indicates that automatic mapping camel naming rules are enabled --> <!-- Rules require database table fields to be named:word_word --> <!-- Rules RequirementsJavaNaming method of entity class attribute name:Camel naming with lowercase initial letter --> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings>
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 taggedresultType
The type ofmap
<!-- returnMaptype: resultType表示结果type: that isMapFully qualified name or alias --> <select resultType="map"> select * from t_emp where emp_id=#{empId} </select>
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 taggedresultType
The type ofPOJO Class
Fully 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 taggedresultType
The 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,OrderItem
The 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 object
When the database table isSelf-increase method
The 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:
<!-- int insertEmployee(Employee employee); --> <!-- useGeneratedKeysAttribute literally means“Use the generated primary key” --> <!-- 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 --> <insert useGeneratedKeys="true" keyProperty="empId"> insert into t_emp(emp_name,emp_salary) values(#{empName},#{empSalary}) </insert>
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
<insert > insert into t_emp (emp_name,emp_salary) values (#{empName},#{empSalary}) <!-- 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 --> <selectKey keyColumn="emp_id" keyProperty="empId" resultType="int" order="AFTER"> select last_insert_id() </selectKey> </insert>
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 first
,id
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
Mybatis
Making result sets andPOJO
When the class mapping relationship is performed, the field name of the result set will be automatically changed toPOJO
The attribute name (actually, it is andgetXXX method
) perform corresponding mapping, and the data of the result set will be automatically mapped toPOJO
The attribute of the same name in the object;
So when we encounter the table's field name andPOJO
When 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 withPOJO
The 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_
,andPOJO
The 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 framework
Of 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.
existMybatis
The global configuration file is added to the following configuration:
<!-- usesettingsrightMybatisSet globally --> <settings> <!-- Willxxx_xxxSuch column names are automatically mapped toxxXxxThe attribute name of the camel-like name --> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings>
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
useresultMap
Tags manually specify the result set field andPOJO
The mapping relationship of attributes allows you to map the result sets very flexibly.
<!-- 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名 --> <resultMap type=""> <id column="emp_id" property="id"/> <result column="emp_name" property="name"/> <result column="emp_salary" property="salary"/> </resultMap> <!-- existselectLabel中passresultMapproperty来指定使用哪个Manual mapping规则 --> <select resultMap="EmployeeInfoMap"> select * from t_emp where emp_id=#{empId} </select>
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_customer
Table andt_order
Represents a one-to-many relationship, otherwiset_order
Table andt_customer
Tables 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
<!--Global configuration automatically map camel naming--> <settings> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings> <!--Alias for entity classes--> <typeAliases> <package name=""/> </typeAliases> <!-- Mapperregister:SpecifyMybatisThe specific location of the map file --> <!-- mappersLabel:Configure a specificMapperMapping files --> <!-- resourceproperty:SpecifyMapperMapping files的实际存储位置,Here you need to use a classpath root directory <mappers> <!-- All packagedMapperThe configuration file will be loaded automatically、register,More convenient。 --> <package name=""/> </mappers>
Mapping configuration files
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-////DTD Mapper 3.0//EN" "/dtd/"> <mapper namespace=""> <resultMap type="Order" autoMapping="true"> <!-- autoMappingThe property is set totrueTurn on automatic mapping --> <association property="customer" javaType="Customer"> <id column="customer_id" property="customerId"></id> <result column="customer_name" property="customerName"></result> </association> </resultMap> <select resultMap="order"> select * from t_order o left join t_customer c on o.customer_id=c.customer_id where order_id=#{orderId} </select> </mapper>
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<Order> 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
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-////DTD Mapper 3.0//EN" "/dtd/"> <mapper namespace=""> <resultMap type="Customer" > <id column="customer_id" property="customerId"/> <result column="customer_name" property="customerName"/> <collection property="orderList" ofType="Order" autoMapping="true"> <!-- Perform one-to-many mapping,usecollectionLabel ofTypeAttribute refers toorderListGenerics of --> </collection> </resultMap> <select resultMap="customer"> SELECT * FROM t_customer c,t_order o WHERE o.customer_id=c.customer_id AND c.customer_id=#{customerId} </select> </mapper>
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!