[MyBatis-Plus] Quickly master the Mybatis-plus framework—Quick Start

In daily development, you should be able to find that the CRUD function code of a single table is highly repetitive and not difficult. This part of the code is often relatively large and time-consuming to develop.

Therefore, some components are currently used in enterprises to simplify or omit the CRUD development work of a single table. One component that is currently used more in China is MybatisPlus.

The official website is as follows:

Of course, MybatisPlus not only simplifies single-table operations, but also has many enhancements to the functions of Mybatis. It can make our development simpler and more efficient.

Through today's study, we will achieve the following goals:

  • Can use MybatisPlus to implement basic CRUD

  • Will use conditional construction to build queries and update statements

  • Will use common annotations in MybatisPlus

  • Will use MybatisPlus to process enumeration and JSON type fields

  • Will use MybatisPlus to implement paging

In order to facilitate testing, we first create a new project and prepare some basic data.

1.Environment preparation

Copy a project provided in the pre-course material to your workspace (do not include spaces or special characters):

Then open it with your IDEA tool. The project structure is as follows:

Pay attention to configuring the JDK version of the project to JDK11. First click on the project structure settings:

Configure JDK in the pop-up window:

Next, we need to import two tables. The SQL files have been provided in the pre-class materials:

The corresponding database table structure is as follows:

Finally, application.yamlmodify the jdbc parameters in to your own database parameters:

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/mp?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: MySQL123
logging:
  level:
    com.itheima: debug
  pattern:
    dateformat: HH:mm:ss

2. Quick start

For example, if we want to implement CRUD for the User table, we only need the following steps:

  • Introduce MybatisPlus dependency

  • Define Mapper

2.1Introduce dependencies

MybatisPlus provides a starter to realize the automatic assembly function of automatic Mybatis and MybatisPlus. The coordinates are as follows:

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.3.1</version>
</dependency>

Since this starter contains automatic assembly of mybatis, it can completely replace the Mybatis starter. Ultimately, the project’s dependencies are as follows:

<dependencies>
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.5.3.1</version>
    </dependency>
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

2.2 Define Mapper

In order to simplify single-table CRUD, MybatisPlus provides a basic BaseMapperinterface, which has already implemented single-table CRUD:

Therefore, as long as our custom Mapper implements this BaseMapper, there is no need to implement single-table CRUD ourselves. Modify the interface com.itheima.mp.mapperunder the package in mp-demo UserMapperand let it inherit BaseMapper:

code show as below:

package com.itheima.mp.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.mp.domain.po.User;

public interface UserMapper extends BaseMapper<User> {
}

2.3 Testing

Create a new test class, write several unit tests, and test basic CRUD functions:

package com.itheima.mp.mapper;

import com.itheima.mp.domain.po.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.time.LocalDateTime;
import java.util.List;

@SpringBootTest
class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    void testInsert() {
        User user = new User();
        user.setId(5L);
        user.setUsername("Lucy");
        user.setPassword("123");
        user.setPhone("18688990011");
        user.setBalance(200);
        user.setInfo("{\"age\": 24, \"intro\": \"英文老师\", \"gender\": \"female\"}");
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        userMapper.insert(user);
    }

    @Test
    void testSelectById() {
        User user = userMapper.selectById(5L);
        System.out.println("user = " + user);
    }

    @Test
    void testSelectByIds() {
        List<User> users = userMapper.selectBatchIds(List.of(1L, 2L, 3L, 4L, 5L));
        users.forEach(System.out::println);
    }

    @Test
    void testUpdateById() {
        User user = new User();
        user.setId(5L);
        user.setBalance(20000);
        userMapper.updateById(user);
    }

    @Test
    void testDelete() {
        userMapper.deleteById(5L);
    }
}

As you can see, the SQL log printed during the running process is very standard:

11:05:01  INFO 15524 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
11:05:02  INFO 15524 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
11:05:02 DEBUG 15524 --- [           main] c.i.mp.mapper.UserMapper.selectById      : ==>  Preparing: SELECT id,username,password,phone,info,status,balance,create_time,update_time FROM user WHERE id=?
11:05:02 DEBUG 15524 --- [           main] c.i.mp.mapper.UserMapper.selectById      : ==> Parameters: 5(Long)
11:05:02 DEBUG 15524 --- [           main] c.i.mp.mapper.UserMapper.selectById      : <==      Total: 1
user = User(id=5, username=Lucy, password=123, phone=18688990011, info={"age": 21}, status=1, balance=20000, createTime=Fri Jun 30 11:02:30 CST 2023, updateTime=Fri Jun 30 11:02:30 CST 2023)

3. Common annotations

In the introductory case just now, we only introduced dependencies, and inherited BaseMapper to be able to use MybatisPlus, which is very simple. But here comes the question: How does MybatisPlus know which table we want to query? What fields are there in the table?

Recall that UserMapper specified a generic when inheriting BaseMapper:

The User in the generic type is the PO corresponding to the database.

MybatisPlus infers table information based on PO entity information to generate SQL. by default:

  • MybatisPlus will convert the class name of the PO entity to camel case and underline it as the table name.

  • MybatisPlus will convert all variable names of the PO entity to camel case and underline them as the field names of the table, and infer the field type based on the variable type.

  • MybatisPlus will use the field named id as the primary key

But in many cases, the default implementation does not match the actual scenario, so MybatisPlus provides some annotations to facilitate us to declare table information.

3.1@TableName

illustrate:

  • Description: Table name annotation, identifying the table corresponding to the entity class

  • Where to use: Entity class

Example:

@TableName("user")
public class User {
    private Long id;
    private String name;
}

In addition to specifying the table name, the TableName annotation can also specify many other attributes:

Attributes

type

Must be specified

default value

describe

value

String

no

""

Table Name

schema

String

no

""

schema

keepGlobalPrefix

boolean

no

false

Whether to keep using the global tablePrefix value (when the global tablePrefix is ​​in effect)

resultMap

String

no

""

The id of resultMap in xml (used to satisfy specific types of entity class object binding)

autoResultMap

boolean

no

false

Whether to automatically build and use resultMap (if resultMap is set, automatic construction and injection of resultMap will not be performed)

excludeProperty

String[]

no

{}

Attribute names that need to be excluded@since 3.3.1

3.2@TableId

illustrate:

  • Description: Primary key annotation, identifying the primary key field in the entity class

  • Where to use: Primary key field of entity class

Example:

@TableName("user")
public class User {
    @TableId
    private Long id;
    private String name;
}

TableIdAnnotations support two properties:

Attributes

type

Must be specified

default value

describe

value

String

no

""

Table Name

type

Enum

no

IdType.NONE

Specify primary key type

IdTypeSupported types are:

value

describe

AUTO

Database ID auto-increment

NONE

Stateless, this type has no primary key set (the annotation is equivalent to following the global, and the global Rio is approximately equal to INPUT)

INPUT

Set the primary key value before inserting

ASSIGN_ID

Assign ID (primary key type is Number (Long and Integer) or String) (since 3.3.0), use the method nextId of the interface IdentifierGenerator (the default implementation class is DefaultIdentifierGenerator snowflake algorithm)

ASSIGN_UUID

Assign UUID, the primary key type is String (since 3.3.0), use the method nextUUID of the interface IdentifierGenerator (default method)

ID_WORKER

Distributed globally unique ID long integer type (please use ASSIGN_ID)

UUID

32-bit UUID string (please use ASSIGN_UUID)

ID_WORKER_STR

Distributed globally unique ID string type (please use ASSIGN_ID)

There are three common ones here:

  • AUTO: Use the database id to grow automatically

  • INPUT: Manually generate id

  • ASSIGN_ID: The snowflake algorithm generates Longa globally unique id for the type. This is the default ID strategy.

3.3@TableField

illustrate:

Description: Common field annotations

Example:

@TableName("user")
public class User {
    @TableId
    private Long id;
    private String name;
    private Integer age;
    @TableField("isMarried")
    private Boolean isMarried;
    @TableField("concat")
    private String concat;
}

Generally, we do not need to add @TableFieldannotations to fields, except for some special circumstances:

  • The member variable name is inconsistent with the database field name

  • Member variables are isXXXnamed after, and according to JavaBeanthe specification, MybatisPlusthey will be removed when identifying fields is, which results in inconsistency with the database.

  • The member variable name is consistent with the database, but conflicts with the keyword of the database. Use @TableFieldannotations to add ```` escapes to field names

Other supported attributes are as follows:

Attributes

type

Required

default value

describe

value

String

no

""

Database field name

exist

boolean

no

true

Whether it is a database table field

condition

String

no

""

Field where entity query comparison condition. If there is a value set, the set value shall prevail. If not, the default global %s=#{%s} will be used. Please refer to (opens new window)

update

String

no

""

Field update set is partially injected. For example: when annotating update="%s+1" on the version field indicates that it will set version=version+1 when updating (this attribute has a higher priority than the el attribute)

insertStrategy

Enum

no

FieldStrategy.DEFAULT

举例:NOT_NULL insert into table_a(<if test="columnProperty != null">column</if>) values (<if test="columnProperty != null">#{columnProperty}</if>)

updateStrategy

Enum

no

FieldStrategy.DEFAULT

举例:IGNORED update table_a set column=#{columnProperty}

whereStrategy

Enum

no

FieldStrategy.DEFAULT

举例:NOT_EMPTY where <if test="columnProperty != null and columnProperty!=''">column=#{columnProperty}</if>

fill

Enum

no

FieldFill.DEFAULT

Field autofill strategy

select

boolean

no

true

Whether to perform select query

keepGlobalFormat

boolean

no

false

Whether to keep using the global format for processing

jdbcType

JdbcType

no

JdbcType.UNDEFINED

JDBC type (this default value does not mean that it will take effect according to this value)

typeHandler

TypeHander

no

Type processor (this default value does not mean that it will take effect according to this value)

numericScale

String

no

""

Specify the number of digits to retain after the decimal point

4. Common configurations

MybatisPlus also supports custom configuration based on yaml files. Please see the official documentation for details:

Most configurations have default values, so we don't need to configure them. But there are also some that have no default value, such as:

  • Alias ​​scanning package for entity classes

  • global id type

mybatis-plus:
  type-aliases-package: com.itheima.mp.domain.po
  global-config:
    db-config:
      id-type: auto # 全局id类型为自增长

It should be noted that MyBatisPlus also supports handwritten SQL, and the reading address of the mapper file can be configured by yourself:

mybatis-plus:
  mapper-locations: "classpath*:/mapper/**/*.xml" # Mapper.xml文件地址,当前这个是默认值。

You can see that the default value is classpath*:/mapper/**/*.xml, which means that as long as we place the mapper.xml file in this directory, it will be loaded.

For example, let's create a new UserMapper.xmlfile:

 Then define a method in it:

<?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">
<mapper namespace="com.itheima.mp.mapper.UserMapper">

    <select id="queryById" resultType="User">
        SELECT * FROM user WHERE id = #{id}
    </select>
</mapper>

Then UserMapperTesttest the method in the test class:

@Test
void testQuery() {
    User user = userMapper.queryById(1L);
    System.out.println("user = " + user);
}

Guess you like

Origin blog.csdn.net/weixin_45481821/article/details/133588436