Detailed interpretation of MyBatis persistence layer framework: Mapper agent development

1 Introduction

In the previous MyBatis Quick Start article, we used the MyBatis native development method to operate the database, which solved the problems of hard coding and cumbersome operation when JDBC operates the database. In fact, in Java projects, we use the Mapper agent development method more often.

image-20230126233131746

What is the difference between the two methods?

When using the basic method to operate the database, we use the native method selectList of sqlSession to execute the sql statement and process the result set object. Example:

List<Student> students = sqlSession.selectList("test.selectAll"); //参数是一个字符串,该字符串必须是映射配置文件的 namespace.id

The parameter of this method must be the sql mapping configuration file name.id, and it is passed to this method in the form of a string, so there is a problem of hard coding here, and the way of using id here is not a convenient design, because we When coding, it is also necessary to find the id in the corresponding mapping configuration file, so the Mapper proxy development method appears to solve this problem.

When using the Mapper proxy development method to operate the database, obtain a Mapper proxy object specifying the Mapper interface through the SqlSession class object, use the proxy object to call the method in the corresponding Mapper interface, and this method corresponds to the id in the mapping configuration file , so as to find the sql and execute it, and finally process the result set object. Example:

//3. 执行sql
//3.1 获取StudentMapper接口的代理对象
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
List<Student> students = studentMapper.selectAll();

In general, the Mapper proxy method has the following two advantages:

  • Solved the problem of hardcoding in native mode
  • Simplified post-execution sql

2. Mapper agent development

It is not difficult to see from the above examples that the method of using Mapper proxy has more advantages. First of all, it does not depend on the literal value of the string, which is more convenient and safe. Secondly, if your IDE has the function of code auto-completion, it can help you quickly select the sql statement of the mapping file without depending on the corresponding id.

To use the Mapper proxy development method, the following steps must be performed:

  1. Define the Mapper interface with the same name as the sql mapping configuration file, and prevent the Mapper interface and the sql mapping configuration file from being in the same directory
  2. Set the namespace attribute of the sql mapping file to the fully qualified name of the Mapper interface
  3. Define the method in the Mapper interface, the method name is the id of the sql statement in the sql mapping file, and keep the parameter type and return value type the same

The following uses a case to understand the process of developing the Mapper agent. The case is still using the query student information in the Getting Started chapter, and encapsulating it as an object and storing it in a collection.

first step :

Create StudentMapper under the org.chengzi.mapperpackage , example:

public interface StudentMapper {
    
    
    List<Student> selectAll();
    Student selectById(int id);
}

Create a org / chengzi / mapperdirectory , and create a StudentMapper.xml configuration file under this file directory. Doing so ensures that the Mapper interface and the sql mapping configuration file are in the same file directory.

Step 2 : Set the namespace attribute of the sql mapping file to be consistent with the fully qualified name of the Mapper interface. Example:

<!--
    namespace:名称空间。必须是对应接口的全限定名
-->
<mapper namespace="org.chengzi.mapper.StudentMapper">
    <select id="selectAll" resultType="org.chengzi.pojo.User">
        select *
        from student;
    </select>
</mapper>

Step 3 : Load the sql mapping configuration file in the MyBatis core configuration file, example:

<mappers>
      <!--加载sql映射文件-->
      <mapper resource="org/chengzi/mapper/StudentMapper.xml"/>
</mappers>

Note: the next two steps use /as file path separator

After completing the above three steps, we can write test code to operate the database and complete related operations. Example:

public class MyBatisDemo2 {
    
    

    public static void main(String[] args) throws IOException {
    
    

        //1. 加载mybatis的核心配置文件,获取 SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //2. 获取SqlSession对象,用它来执行sql
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //3. 执行sql
        //3.1 获取StudentMapper接口的代理对象
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        List<Student> students = studentMapper.selectAll();

        System.out.println(students);
        //4. 释放资源
        sqlSession.close();
    }
}

operation result:

image-20230128201911101

Different from the basic method of MyBatis, here we obtain the proxy object of the StudentMapper interface through the method corresponding to the sqlSession object, use the proxy object to execute the sql statement, and encapsulate the result set object. The process of returning the proxy object is done internally by MyBatis.

Tips: When loading the sql mapping configuration file in the MyBatis core configuration file, if the number of sql mapping configuration files is large, this step is also troublesome. MyBatis also provides a solution to this problem.

If the name of the Mapper interface is the same as that of the sql mapping file and they are in the same directory, you can use package scanning to simplify the loading of the sql mapping file. You only need to modify the part of loading the sql mapping configuration file in the core configuration file to:

<mappers>
    <!--加载sql映射文件-->
    <!-- <mapper resource="org/chengzi/mapper/UserMapper.xml"/>-->
    <!--Mapper代理方式-->
    <package name="org.chengzi.mapper"/>
</mappers>

3. Process analysis

When using Mapper proxy development, we get the SqlSession class object through the openSession() method of the SqlSessionFactory class, and then get the Mapper proxy object of the specified Mapper interface through the SqlSession class object.

When obtaining the Mapper proxy object, we can find the corresponding Mapper interface, and in the same directory, we can find the corresponding sql mapping file with the same name as the interface. Use the proxy object to call the method in the corresponding Mapper interface. This method corresponds to the id attribute in the sql mapping configuration file. Through the id attribute, you can find the corresponding sql statement, and then execute the sql statement and encapsulate the result set object.

For example, in the above case, the studentMapperproxy object executes the selectAll() method and returns a List object. In fact, the bottom layer still executes the following statement:

 List<User> users = sqlSession.selectList("test.selectAll"); 

4. Summary

Developed in the native way of MyBatis, some processes depend on string constant values, and there are hard-coded problems. At the same time, using command space and sql unique identifier as parameters for executing sql is troublesome when writing code. The way of using Mapper proxy has more advantages. First of all, it does not depend on the literal value of the string, which will be more convenient and safe. Secondly, if your IDE has the function of code auto-completion, it can help you quickly select the sql statement of the mapping file without depending on the corresponding id.

Guess you like

Origin blog.csdn.net/zhangxia_/article/details/128781725