Introduction to MybatisPlus

MyBatis-Plus (MP for short) is a MyBatis enhancement tool, on the basis of MyBatis only do enhancement do not change, to simplify the development and improve efficiency.

Mybatis-Plus is a domestic framework, there are Chinese documents, so it is very convenient to use, there are not so big obstacles.

File address: baomidou.com/

The current version is 3.5.1

The documentation is pretty clear, so I’m not going to go into that. Go straight to the integration step.

Second, integration steps

We will first pull a feature/mybatisPlus branch to demonstrate the use of springBoot integration with mybatisPlus.

1. Introduce dependencies


      
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>com.lsqingfeng.springboot</groupId>
    <artifactId>springboot-learning</artifactId>
    <version>1.0.0</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.6.2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <! -- Lombok code simplification -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
            <scope>provided</scope>
        </dependency>

        <! -- Mybatis - Plus required dependencies -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1 track of</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.5.1 track of</version>
        </dependency>

        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.31</version>
        </dependency>

        <! -- Development hot start -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>

        <! MySQL > select * from 'MySQL';
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
    </dependencies>
</project>
Copy the code

Mybatis -plus-boot-starter is the core application package

Mybatis – Plus-Generator and Freemarker are designed to be generated in reverse order to help us generate entities, mapper, Service,controller, etc. Basic can achieve nearly 0 code development single table add, delete, change, check.

2. Reverse generation

We will first demonstrate the reverse generation function of Mybatis – Plus. The so-called reverse engineering is based on the table structure of the database to help us generate code, so we need to make sure that the tables in the database are already established.

Reverse engineering is a tool class. We put this class directly under our project, and then configure the relevant database connection and the directory location to generate, and the table to generate. After executing, we can directly generate the class we need.

The new version of MybatisPlus automatically generates in a different way from the old version, please note when using it, this has been specified in the official documentation.

Baomidou.com/pages/779a6…

Since we are using the latest version, we use the new-version generation method.

We create a package utils under the project and add our utility class MybatisPlusGenerator as follows.

package com.lsqingfeng.springboot.utils;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.fill.Column;

import java.util.Collections;

/ * * *@className: MybatisPlusGenerator
 * @description:
 * @author: sh.Liu
 * @date: the 2022-01-26 11:19 * /
public class MybatisPlusGenerator {
    public static void main(String[] args) {
        FastAutoGenerator.create("jdbc:mysql://localhost:3306/springboot_learning? useUnicode=true&useSSL=false&characterEncoding=utf8"."root"."root")
                .globalConfig(builder -> {
                    builder.author("springBoot-Learning") // Set the author
                            EnableSwagger () // enableSwagger mode
                            .fileOverride() // Overwrite the generated file
                            .outputDir(System.getProperty("user.dir") +"/src/main/java"); // Specify the output directory
                })
                .packageConfig(builder -> {
                    builder.parent("com.lsqingfeng") // Set the parent package name
                            .moduleName("springboot") // Set the module name of the parent package
                            //.service() // Sets a custom service path
                            .pathInfo(Collections.singletonMap(OutputFile.mapperXml, System.getProperty("user.dir") +"/src/main/resources/mapper/")); // Set the mapperXml generation path
                })
                .strategyConfig(builder -> {
                    builder.addInclude("t_user") // Set the name of the table to be generated
                            .addTablePrefix("t_"."c_")
                            // Set the autofill time field
                            .entityBuilder().addTableFills(
                                    new Column("create_time", FieldFill.INSERT),new Column("update_time", FieldFill.INSERT_UPDATE))
                    ; // Set the filter table prefix

                })
                .templateEngine(new FreemarkerTemplateEngine()) // Use the Freemarker engine template, which defaults to the Velocity engine template.execute(); }}Copy the code

In this class, we need to set the database connection information: database link address, username and password, etc. You need to set the author, whether to enable Swagger mode, and where to generate code. Using the system variable user.dir here directly gets the path to our current project.

You also need to set the corresponding register, module name, and ignored table name prefix. The addInclude method can have multiple table names and can be used to specify which tables will be generated automatically or not. Otherwise, the code will be generated for all tables in the current library by default.

Through the above code to run automatically generated after the controller, the service, the mapper default in com. Lsqingfeng. Springboot controller, service, mapper under the table. Mapper XML files are located in the Resources /mapper folder. These are also modifiable.

The default for a generated file is as follows;

3. Add the configuration

After the reverse generation is completed, the basic environment of mybatis-Plus is basically set up. The next step is to do the configuration.

First we need to add a Mapper scan annotation MapperScan on the startup class to configure the location of the Mapper package to be scanned. Of course, this configuration can also be placed on any configuration class, the effect is the same.

package com.lsqingfeng.springboot;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/ * * *@className: SpringBootLearningApplication
 * @description: SpringBoot boot class *@author: sh.Liu
 * @date: the 2022-01-10 away * /
@SpringBootApplication
@MapperScan("com.lsqingfeng.springboot.mapper")
public class SpringBootLearningApplication {
    public static void main(String[] args) { SpringApplication.run(SpringBootLearningApplication.class, args); }}Copy the code

If we want to use paging in Mybatis-Plus, we also need to add a configuration class to the paging interceptor configuration.

package com.lsqingfeng.springboot.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/ * * *@className: MybatisPlusConfig
 * @description:
 * @author: sh.Liu
 * @date: the 2022-03-04 14:55 * /
@Configuration
public class MybatisPlusConfig {
    /** * Old version, currently invalid *@return* /
    / * *@Beanpublic PaginationInterceptor paginationInterceptor() { PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); return paginationInterceptor; } * /


    /** * The new paging plugin follows the rules of Mybatis, */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(a) {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        returninterceptor; }}Copy the code

Add a configuration class that automatically fills create_time and update_time:

package com.lsqingfeng.springboot.config;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/ * * *@className: MyMetaObjectHandler
 * @description:
 * @author: sh.Liu
 * @date: 2022-03-04 to * /
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill...");
        this.setFieldValByName("createTime", LocalDateTime.now(), metaObject);
        this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start update fill...");
        this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject); }}Copy the code

This configuration class is used with the annotation configuration on the entity class. Since the auto-generated utility class has been set up, the auto-generated entities will have corresponding annotations on createTime and updateTime so that they can be filled automatically.

/** * create time */
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;

/** * update time */
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
Copy the code

4. Test

MybatisPlus provides some common apis: Page, List,getOne, Save, Update, etc. And you can focus on how to write it.

package com.lsqingfeng.springboot.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lsqingfeng.springboot.base.Result;
import com.lsqingfeng.springboot.entity.User;
import com.lsqingfeng.springboot.service.IUserService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/** ** <p> * Front-end controller * </p> **@author springBoot-Learning
 * @sinceThe 2022-02-28 * /
@RestController
@RequestMapping("/user")
public class UserController {

    /** * the constructor inserts */
    private final IUserService userService;

    public UserController(IUserService userService) {
        this.userService = userService;
    }

    @GetMapping("/save")
    public Result save(a){
        User user =new User();
        user.setAge(18);
        user.setAddress("Wangfujing Street, Beijing");
        user.setName("Zhang xx");
        userService.save(user);

        return Result.success();
    }

    @GetMapping("/update")
    public Result update(Integer id){
        User user =new User();
        user.setId(id);
        user.setName("Modified name");

        userService.updateById(user);

        return Result.success();
    }

    @GetMapping("/list")
    public Result list(a){
        // Return all
        List<User> list = userService.list();
        return Result.success(list);
    }

    @GetMapping("/listByContion")
    public Result listByContion(a){
        * eq: equal * like: fuzzy matching * orderBy: sort * in, notin * greater than, less than, between, etc. */
        List<User> list = userService.list(new LambdaQueryWrapper<User>()
                // query age =11
                .eq(User::getAge, 11)
                // Fuzzy matching
                .like(User::getName, "%张%")
                // Sort by creation time
                .orderByDesc(User::getCreateTime)
        );
        return Result.success(list);
    }

    @GetMapping("/getById")
    public Result getById(Integer id){
        User user = userService.getById(id);
        return Result.success(user);
    }

    @GetMapping("/delete")
    public Result delete(Integer id){
        userService.removeById(id);
        return Result.success();
    }

    @GetMapping("/page")
    public Result page(int pageNum, int pageSize, String name){
        IPage<User> page = new Page<>(pageNum, pageSize);

        IPage<User> page1 = userService.page(page, new LambdaQueryWrapper<User>()
                // The main demo can be conditional here. Execute when name is not empty
                .eq(StringUtils.isNotEmpty(name), User::getName, "%" + name + "%"));

        returnResult.success(page1); }}Copy the code

Validation:

Save the interface:

Database:

Update interface:

Database:

Query all interfaces:

Conditional query interface:

Select * from ‘age’ where ‘age’ = ’11’ and ‘name’ = ‘zhang’

List<User> list = userService.list(new LambdaQueryWrapper<User>()
                // query age =11
                .eq(User::getAge, 11)
                // Fuzzy matching
                .like(User::getName, "%张%")
                // Sort by creation time
                .orderByDesc(User::getCreateTime)
        );
Copy the code

Query interface by id:

Paging query:

Third, summary

We have covered the common operations of mybtisPlus. The current popularity of mybatisPlus is also growing. Through this article, I believe that you will have a profound understanding of the use of mybatisPlus.

The main step is to design the library table first, and then generate the entities, mapper, service and so on we need through the automatic generation tool. Controller is generally developed by ourselves, so we don’t need to use the Controller generated by them, and then in our project, By invoking the corresponding service, mapper realizes the common add, delete, change and query operations. The main reason why mybatisPlus is so popular is that even though it encapsulates the single-table operation API, it saves us the workload of writing a lot of SQL. Most of the single-table operation functions can be completed directly by calling the corresponding API, which is very simple.

Besides the first time, mybatisPlus provides a very detailed and readable Chinese document, in which we can find everything we want to find. This should also be an important reason why he is very popular in China.

If we want to develop custom SQL, use the same way as Mybatis, because it is fully compatible with MyBatis, we just need to write our own custom SQL in mapper.xml file.

GitCode: gitcode.net/lsqingfeng/…

All articles will be first updated in the wechat public account, welcome to pay attention to: a wisp of 82 years of wind