Do you really know the "those things" about Mybatis configuration files and mapping files?

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



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.

insert image description here

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

insert image description here

② Import external property files

How to externally define and introduce the property file of the database connection?

  1. For example, define a db.properties file in the resources directory to store the relevant property values ​​​​of the database connection

insert image description here

  1. 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:
insert image description here

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>

insert image description here

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:

insert image description here

b. When setting the property of mapUnderscoreToCamelCase to true in the core configuration file:

<settings>
    <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

insert image description here

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:
insert image description here

Don't believe me, you can try it!

insert image description here


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:

insert image description here

②Right click the mouse to open the option bar below, click "copy Reference"

insert image description here

③ "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();
    }


}

insert image description here

insert image description here

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();
    }


}

insert image description here

insert image description here

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:

insert image description here

① 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();
    }


}

insert image description here

insert image description here

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();
        }

    }

insert image description here

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();
    }


}

insert image description here
insert image description here

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();
    }


}

insert image description here

insert image description here

Guess you like

Origin blog.csdn.net/siaok/article/details/130478410