Compilation software: IntelliJ IDEA 2019.2.4 x64
Operating system: win10 x64-bit Home Edition
Maven version: apache-maven-3.6.3
Mybatis version: 3.5.6
Table of contents
- 1. Detailed explanation of the core configuration file of Mybatis [mybatis-config.xml]
- 2. Explain the mapping file of Mybatis in detail
1. Detailed explanation of the core configuration file of Mybatis [mybatis-config.xml]
1.1 Overview of core configuration files
MyBatis configuration files contain information about settings and properties that deeply affect MyBatis behavior.
1.2 The root label of the core configuration file
effect:
Set all child tags inside the root tag
grammar:
<configuration>
</configuration>
1.3 Commonly used subtags of core configuration files
1.3.1 properties sub-tab
effect:
You can define properties or import external properties files
Why import an external properties file?
Realize the decoupling of database connection properties
Application scenario:
① Set the corresponding properties in the properties element
How to set it?
Set the driver and ur attribute values of the database connection object in the child elements of the properties element
The set attributes driver and url can dynamically replace their attribute values in the same attribute under the dataSource tag, as shown in the figure below.
Usage example: In the core configuration file, use the properties sub-tag to set the driver and url properties required for database connection, refer their property values to the corresponding properties in the dataSource sub-tag under the environments tag, and run the test.
The sample code is as follows:
①In the core configuration file, use the properties sub-tag to set the driver and url properties required for database connection, and refer their property values to the corresponding properties in the dataSource sub-tag under the environments tag
<properties>
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/0411db?serverTimezone=UTC"/>
</properties>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!-- 下面是mysql8版本 -->
<property name="driver" value="${driver}"/>
<!-- url后要加时区 ?serverTimezone=UTC" ,不然报错 -->
<property name="url" value="${url}"/>
<!-- 下面是mysql5版本的写法
<property name="driver"value="com.mysql.jdbc.Driver"/>
<property name="url"value="jdbc:mysql://localhost:3306/0411db"/>
-->
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
② Run the test
② Import external property files
How to externally define and introduce the property file of the database connection?
- For example, define a db.properties file in the resources directory to store the relevant property values of the database connection
- Use the properties tag in the core configuration file to introduce the external property file db.properties
Note: The difference between the two ways of referencing files in the properties tag (resource and url) is shown in the following figure:
The sample code is as follows:
<properties resource="db.properties"></properties>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!-- 下面是mysql8版本 -->
<property name="driver" value="${db.driver}"/>
<!-- url后要加时区 ?serverTimezone=UTC" ,不然报错 -->
<property name="url" value="${db.url}"/>
<!-- 下面是mysql5版本的写法
<property name="driver"value="com.mysql.jdbc.Driver"/>
<property name="url"value="jdbc:mysql://localhost:3306/0411db"/>
-->
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
1.3.2 settings sub-tab
effect:
This is an extremely important tuning setting in MyBatis that changes the runtime behavior of MyBatis.
Common attributes:
mapUnderscoreToCamelCase属性
: Whether to enable the automatic mapping of camel case naming, the default value is false, if set true, the field a_col in the database will be automatically mapped with the aCol attribute in the Java object
Notice:
Only fields with the same letter can be automatically mapped with attributes
The sample code is as follows;
a. When the value of mapUnderscoreToCamelCase is not set in the settings in the core configuration file:
b. When setting the property of mapUnderscoreToCamelCase to true in the core configuration file:
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
1.3.3 typeAliases (type alias) subtag
effect:
Type Alias can set an alias for a Java type
Grammar and features:
① Set an alias for Java pojo (Java bean [entity class]) (not commonly used)
<typeAliases>
//为指定类型定义别名,前者是类的全类名,后者是该类的别名(小名)
<typeAlias type="mybatis.mapper.EmployeeMapper" alias="employee"
</typeAliases>
② Alias all pojos under the specified package (commonly used)
<typeAliases>
//为指定包【mybatis.pojo】下所有的类定义别名。
//默认将类名作为别名,不区分大小写【推荐使用小写字母】
<package name="mybatis.pojo"/>
</typeAliases>
1.3.3.1 Mybatis commonly used custom aliases
alias | type |
---|---|
_int | int |
integer or int | Integer |
string | String |
list or arraylist | ArrayList |
map or hashmap | HashMap |
Note: The naming style of other basic data types in Java is similar to that of int's Mybatis custom aliases, as is the packaging type, so I won't go into details here.
1.3.4 environments (environment configuration) sub-tab
effect:
Set up the database connection environment
The sample code is as follows:
//设置数据库的连接环境
<environments default="development">
//可设置多个<environment></environment>
<environment id="development">
//设置事务管理器的相应属性
<transactionManager type="JDBC"/>
//设置数据源
<dataSource type="POOLED">
//设置数据库连接的相应属性
<!-- 下面是mysql8版本 -->
//设置数据库连接的driver(驱动)
<property name="driver" value="${db.driver}"/>
<!-- url后要加时区 ?serverTimezone=UTC" ,不然报错 ->
//设置数据库连接的url
<property name="url" value="${db.url}"/>
<!-- 下面是mysql5版本的写法
<property name="driver"value="com.mysql.jdbc.Driver"/>
<property name="url"value="jdbc:mysql://localhost:3306/0411db"/>
-->
//设置数据库连接所需要的能够登录MySQL的用户名
<property name="username" value="root"/>
//设置密码
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
1.3.5 mappers sub-tab
effect:
Set the path to load the mapping file
The sample code is as follows:
<mappers>
<mapper resource="mapper/EmployeeMapper.xml"/>
//有些老项目可能会这么写
<!--要求:接口的包名与陕射义件的包名需要致-->
<package name="com.atguigu.mybatis.mapper"/>
</mappers>
Notice:
The subtags in the core configuration file are required in order
The default order is as follows:
Don't believe me, you can try it!
2. Explain the mapping file of Mybatis in detail
2.1 Overview of mapping files
The real power of Mybatis lies in its statement mapping, which is its magic. If you compare it with the JDBC code with the same function, you will immediately find that nearly 95% of the code has been saved. (Excerpt from official documentation)
2.2 Root label of mapping file
Root tag: mapper tag
Notice:
The namespace requirement in the mapper is consistent with the full class name of the interface
How to get the full class name of an interface (method/pojo)?
①Put the cursor on the interface name to be obtained
As shown below:
②Right click the mouse to open the option bar below, click "copy Reference"
③ "mybatis.mapper.DeptMapper" is the full name of the interface name just now
2.3 Mapping file subtags
2.3.1 insert tag
Function:
Define and add sql statement
Usage example:
Use the insert tag to insert a piece of data (employee object) into the database
① Define the method of adding data in the EmployeeMapper interface
The code example is as follows:
//添加员工
public void insertEmployee(Employee employee);
②Use the insert tag in the mapping file corresponding to the above interface
The code example is as follows:
<insert id="insertEmployee">
insert into
tbl_employee(last_name,email,salary)
<!-- 这里是要将employee对象中的属性值传到mysql中 -->
values(#{lastName},#{email},#{salary})
</insert>
③ test
@Test
public void testInsertEmployee(){
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//通过SqlSessionFactory对象调用openSession();
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取EmployeeMapper的代理对象
EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
employeeMapper.insertEmployee(new Employee("张三","[email protected]",9000.0));
//开启事务,数据才能真正存进数据库中,why?
sqlSession.commit();
} catch (IOException e) {
e.printStackTrace();
}
}
Here is a question: Even when using mybatis, when adding data to the MySQL database, why do you need to add the code sqlSession.commit() in the code before the data can actually be stored in the database?
explain:
When using Mybatis to manipulate data, after calling the insert or update method, the SQL statement will not be executed immediately, but will be cached in the current SqlSession object. This literal Session is like a session, which is expected to involve multiple database operations, and its life cycle usually spans multiple request and response (request, response) stages.
Therefore, if you want to actually store the data in the database, you need to manually trigger a commit action. The SqlSession interface in Mybatis provides the commit() method to commit the transaction so that all uncommitted SQL statements are executed immediately and the results are stored in the database.
That is to say, sqlSession.commit() can batch send previously cached SQL statements to the database for processing. At the same time, if the transaction is not committed, all previous changes will be rolled back, and the database will not have any changes.
Therefore, when using Mybatis for data operations, it is very necessary to add the code sqlSession.commit(), otherwise data insertion failure may occur.
2.3.2 delete label
Function:
Define delete sql statement
Usage example:
Use the delete tag to delete the data of employee number 4 in the database
① Define the method of deleting data in the EmployeeMapper interface
The code example is as follows:
//删除员工(根据员工编号删除对应的员工信息)
public void deleteEmployee(int empId);
② Use the delete tag in the mapping file corresponding to the above interface
The code example is as follows:
<delete id="deleteEmployee">
delete from tbl_employee
where id= #{empId}
</delete>
③ test
The code example is as follows:
@Test
public void testDeleteEmployee(){
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//通过SqlSessionFactory对象调用openSession();
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取EmployeeMapper的代理对象
EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
//删除员工编号为4的员工信息
employeeMapper.deleteEmployee(4);
//开启事务,数据才能真正存进数据库中
sqlSession.commit();
} catch (IOException e) {
e.printStackTrace();
}
}
2.3.3 update tag
Function:
Define and modify the sql statement
Usage example:
Use the update tag to modify the relevant employee data with employee number 2
Data before modification:
① Define the method of modifying data in the EmployeeMapper interface
The code example is as follows:
//修改员工数据
public void updateEmployee(Employee employee);
② Use the update tag in the mapping file corresponding to the above interface
The code example is as follows:
<update id="updateEmployee">
update tbl_employee
set email=#{email} , salary=#{salary}
where id=#{id}
</update>
③ test
@Test
public void testUpdateEmployee(){
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//通过SqlSessionFactory对象调用openSession();
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取EmployeeMapper的代理对象
EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
//通过调用代理对象去执行删除,这点和当初在Dao层新建接口,接口的实现类去实现删除的功能很像,代理对
//象就相当于当初接口的实现类一样,但是我并没有写接口的实现类,但在mybatis框架中就真真切切的实现了
//删除的功能,究其原因,应该是mybatis在底层就帮我实现了,但是具体是怎么实现的,我暂时不知道
//修改员工编号为2的员工部分信息
employeeMapper.updateEmployee(new Employee(2,"[email protected]",120.0));;
//开启事务,数据才能真正存进数据库中
sqlSession.commit();
} catch (IOException e) {
e.printStackTrace();
}
}
2.3.4 select tag
Function:
Define query sql statement
Usage example:
Use the select tag to query all employee information in the database
①In the EmployeeMapper interface, first define the method of viewing all employee data
The code example is as follows:
//查看所有的员工信息
public List<Employee> showAllEmployee();
② Use the select tag in the mapping file corresponding to the above interface
The code example is as follows:
<!-- 查看所有的员工信息 -->
<!-- 如果resultType中的值是一个类的类型,如果之前定义它的别名,这里可填写该类的别名,毕竟有时类的全名太长了 -->
<select id="showAllEmployee" resultType="mybatis.pojo.Employee">
select
id,
last_name ,
email,
salary
from
tbl_employee
</select>
Notice:
In resultType, the fully qualified name or alias of the class that is expected to return the result from this statement. If the return is a collection, it should be set to the type contained in the collection, not the type of the collection itself. Only resultType and resultMap can be used at the same time
③ test
@Test
public void testShowAllEmployee(){
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//通过SqlSessionFactory对象调用openSession();
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取EmployeeMapper的代理对象
EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
List<Employee> employees = employeeMapper.showAllEmployee();
for (Employee employee : employees) {
System.out.println(employee);
}
/*
//开启事务,数据才能真正存进数据库中
sqlSession.commit();
*/
} catch (IOException e) {
e.printStackTrace();
}
}
Remarks: The detailed function usage of the following sub-tags will be discussed in detail in the next sequence article, so I won’t go into details here
2.3.5 Sql tags
Function:
Define reusable blocks of SQL statements
2.3.6 cache tag
Function:
Set the cache configuration for the current namespace
2.3.7 cache-ref tag
Function:
Set cache configuration for other namespaces
2.3.8 resultMap label
Function:
Describes how to load objects from a database result set
Notice:
在使用多表查询的场景上,resultType解决不了,就用resultMap
2.4 Commonly used attributes in mapping files
2.4.1 resultType
Function description:
Set the expected result set return type [full class name or alias]
Notice:
If a collection is returned, it should be set to the type contained in the collection, not the type of the collection itself.
resultType和resultMap之间只能同时使用一个
2.5 Get primary key auto-increment data
The following two attributes are required to obtain primary key auto-increment data
-
useGeneratedKeys
: Enable primary key generation strategy -
keyProperty
: Set the stored attribute value
Usage example: Based on the method of inserting data in the EmployeeMapper interface, add the above two attributes to the original insert tag in the mapping file to obtain its auto-incrementing primary key when inserting data
① Write the method of inserting data in the EmployeeMapper interface
The code example is as follows:
//添加员工
public void insertEmployee(Employee employee);
②In the mapping file corresponding to the EmployeeMapper interface, use the inset tag to add two attributes to obtain the primary key auto-increment data
The code example is as follows:
<!-- useGeneratedKeys="true" keyProperty="id" : 启用主键生成策略,返回的结果集中包含自动生成主键的信息,并将其赋值给实体类对象中的 id 属性 -->
<insert id="insertEmployee" useGeneratedKeys="true" keyProperty="id">
insert into
tbl_employee(last_name,email,salary)
<!-- 这里是要将employee对象中的属性值传到mysql中 -->
values(#{lastName},#{email},#{salary})
</insert>
③ test
The code example is as follows
@Test
public void testInsertKeyEmployee(){
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//通过SqlSessionFactory对象调用openSession();
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取EmployeeMapper的代理对象
EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
Employee employee=new Employee("李四1","[email protected]",9000.0);
employeeMapper.insertEmployee(employee);
//当执行插入sql后,获取新增员工的主键(员工编号)
System.out.println("employee.getId() : "+employee.getId());
//开启事务,数据才能真正存进数据库中
sqlSession.commit();
} catch (IOException e) {
e.printStackTrace();
}
}
2.6 Get the number of affected rows in the database
How to get the number of affected rows in the database?
Just set the return value of the corresponding method in the interface to int or boolean
-
int
: Represents the number of affected rows -
boolean
: Represents whether the database is affected, true represents the database is affected, false represents no
Use case: Get the number of rows affected by the database when inserting data
①Based on the code of the usage case in Section 2.5, only modify the type of the return value in the Mapper interface to int
The code example is as follows:
//修改Mapper接口中返回值的类型为int
//添加员工
public int insertEmployee(Employee employee);
② Fine-tune and test the test code accordingly
//测试代码做相应的微调
@Test
public void testInsertKeyEmployee(){
try {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//通过SqlSessionFactory对象调用openSession();
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取EmployeeMapper的代理对象
EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
Employee employee=new Employee("李四1","[email protected]",9000.0);
//获取返回值i(影响数据库的行数)
int i = employeeMapper.insertEmployee(employee);
System.out.println("影响数据库的行数: "+i);
//当执行插入sql后,获取新增员工的主键(员工编号)
System.out.println("employee.getId() : "+employee.getId());
//开启事务,数据才能真正存进数据库中
sqlSession.commit();
} catch (IOException e) {
e.printStackTrace();
}
}