Using XML files to configure MyBatis in Spring Boot

When using MyBatis to access the database in Spring Boot, we have completed the simple addition, deletion, modification and query operations by directly using annotations. Now in this article, I will focus on configuring the relevant SQL statements in the xml file. In other words, this article will use SQL The separation of statements and related Java interfaces is more in line with our actual development operations. This article can be said to be more suitable for our development operations in enterprises.

And friends who know IOC should know that IOC (Inversion of Control) is a unique operation in Spring. We configure the relevant properties of Mybatis and load the MyBatis configuration file and Mapper XML file into the Spring container to achieve IOC. .

To be specific:

  • The location of the MyBatis configuration file is specified by configuring the mybatis.config-location property in the application.properties or application.yml file. Spring Boot will automatically load the configuration file into the Spring container, thereby achieving management and control of the MyBatis configuration.
  • By configuring the mybatis.mapper-locations property in the application.properties or application.yml file, specifies the location of the Mapper XML file . Spring Boot will automatically scan and load these Mapper XML files and parse them into the Mapper interface of MyBatis, thereby realizing the management and control of the Mapper interface.
  • In the MyBatisConfig configuration class, use the @MapperScan annotation to scan the package where the Mapper interface is located and register it in the Spring container. In this way, we can use these Mapper interfaces in other components through dependency injection, realizing inversion of control of the Mapper interface.

Okay, after introducing relevant knowledge points, we start to build a demo

As usual, still introduce related dependencies

 <dependencies>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
            <groupId>com.oracle.ojdbc</groupId>
            <artifactId>ojdbc8</artifactId>
            <version>19.3.0.0</version>
            <scope>compile</scope>
        </dependency>
</dependencies>

Step 2: Configure our database and port in the application file

#MySQL
#spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true & amp;characterEncoding=utf-8 & amp;useSSL=true & amp;serverTimezone=UTC
#spring.datasource.username=root
#spring.datasource.password=123456
#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

#Oracle
server.port=1001
#spring.datasource.url=jdbc:oracle:thin:@localhost:1521/orcl
#spring.datasource.username=root
#spring.datasource.password=root
#spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver

# Configure the Mybatis file location and tell Spring Boot the location you need to scan.
mybatis.mapper-locations=classpath:mapper/*.xml

MySQL database structure:

CREATE TABLE `User` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `name` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL,
  `age` int DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci

Create entity class objects based on the table structure:

public class User {<!-- -->

    private Long id;

    private String name;
    private Integer age;

    public User(String name, Integer age) {<!-- -->
        this.name = name;
        this.age = age;
    }

    public Long getId() {<!-- -->
        return id;
    }

    public void setId(Long id) {<!-- -->
        this.id = id;
    }

    public String getName() {<!-- -->
        return name;
    }

    public void setName(String name) {<!-- -->
        this.name = name;
    }

    public Integer getAge() {<!-- -->
        return age;
    }

    public void setAge(Integer age) {<!-- -->
        this.age = age;
    }

    public User() {<!-- -->
    }
}

Create a Mapper interface and associate it with the UserMapper.xml file. Anyone who knows MyBatis knows that this method is done through mapping.

public interface UserMapper {<!-- -->
    User findByName(@Param("name") String name);

    int insert(@Param("name") String name, @Param("age") Integer age);

}

Next we need to create a MyBatis configuration file. Generally we will create the *Mapper.xml file. For example, the entity class we are using now is User, then we will create a UserMapper.xml file and put it in Resources/mapper. If you do not have a mapper folder, create a new one.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
        <!--Note that the namespace points to the Java interface path where we store the mapper interface-->
<mapper namespace="com.miaow.demo.mapper.UserMapper">
    <select id="findByName" resultType="com.miaow.demo.entity.User">
        SELECT * FROM USER WHERE NAME = #{name}
    </select>

    <insert id="insert">
        INSERT INTO USER(NAME, AGE) VALUES(#{name}, #{age})
    </insert>
</mapper>

At this point we can perform interface testing by writing a unit test.

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
public class ApplicationTests {<!-- -->

    @Autowired
    private UserMapper userMapper;

    @Test
    @Rollback //Rollback the operation after completion to avoid affecting the data
    public void test() throws Exception {<!-- -->
    //Insert miaow, age 20 years old
        userMapper.insert("maiow", 20);
        //Search based on the name miaow
        User u = userMapper.findByName("miaow");
        //Assert.assertEquals(20, u.getAge().intValue()) means to assert that the value of the age attribute of object u is equal to 20. If the assertion succeeds, that is, the object's age property is equal to 20, the program continues execution; if the assertion fails, that is, the object's age property is not equal to 20, an AssertionError exception is thrown.
        Assert.assertEquals(20, u.getAge().intValue());
    }
}

PS: Let me explain here. This case does not require the operation of the Service layer for direct display. The correct operation is that we create the Service interface, then create a Service implementation class, and call the Mapper interface in the Service implementation class.