Additions, deletions, modifications and features of MybatisPlus

Additions, deletions, modifications and features of MybatisPlus

1. Unique ID generation scheme for distributed systems

The unique ID of the system is a problem that we often encounter when designing a system, and we often struggle with this problem. There are many ways to generate ID, which adapt to different scenarios, needs and performance requirements. Therefore, some more complex systems have multiple ID generation strategies. The following link is a very comprehensive introduction to the solution, we solve the problem of id uniqueness of multiple databases

https://www.cnblogs.com/haoxinyue/p/5208136.html

2. MP's primary key auto-increment strategy

2.1 ASSIGN_ID

MyBatis-Plus default primary key strategy is: ASSIGN_ID (using the snowflake algorithm)

@TableId(type = IdType.ASSIGN_ID)
private String id;
2.2 AUTO self-increment strategy

(1) Need to set the primary key auto-increment when creating the data table
(2) Configure @TableId(type = IdType.AUTO in the entity field)

@TableId(type = IdType.AUTO)
private Long id;

To affect the configuration of all entities, you can set the global primary key configuration

#全局设置主键生成策略
mybatis-plus.global-config.db-config.id-type=auto
2.3 See source code for other types
/*
 * Copyright (c) 2011-2020, hubin ([email protected]).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.baomidou.mybatisplus.annotation;

import lombok.Getter;

/**
 * <p>
 * 生成ID类型枚举类
 * </p>
 *
 * @author hubin
 * @since 2015-11-10
 */
@Getter
public enum IdType {
    
    
    /**
     * 数据库ID自增
     */
    AUTO(0),
    /**
     * 该类型为未设置主键类型
     */
    NONE(1),
    /**
     * 用户输入ID
     * 该类型可以通过自己注册自动填充插件进行填充
     */
    INPUT(2),

    /* 以下3种类型、只有当插入对象ID 为空,才自动填充。 */
    /**
     * 全局唯一ID (idWorker)
     */
    ID_WORKER(3),
    /**
     * 全局唯一ID (UUID)
     */
    UUID(4),
    /**
     * 字符串全局唯一ID (idWorker 的字符串表示)
     */
    ID_WORKER_STR(5);

    private int key;

    IdType(int key) {
    
    
        this.key = key;
    }
}

3. Auto fill

Description of Requirement:

Some data is often encountered in the project, and it is filled in the same way every time, such as the creation time of the record, the update time, etc. We can use the auto-fill function of MyBatis Plus to complete the assignment of these fields.

3.1, database modification

In the User table, add a new field of type datetime to create time create_time and modify time update_time

3.2 Modification of entity classes

We need to add annotations to the properties of javabean

The code as shown below

package com.atguigu.entity;

import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;

import java.util.Date;

/**
 * @Author Kilig Zong
 * @Date 2020/10/27 20:17
 * @Version 1.0
 */
@Data
public class User {
    
    
    //。。。。其他属性
    @TableField(fill = FieldFill.INSERT)//实体上增加字段并添加自动填充注解,在创建的时候会创建这个时间
    private Date createTime;//创建时间
    @TableField(fill=FieldFill.INSERT_UPDATE)//实体上增加字段并添加自动填充注解,在创建和修改的时候会修改这个时间
    private Date updateTime;//修改的时间




}

3.3 Implement the meta object processor interface

Note: Don't forget to add @Component annotation

package com.atguigu.mybatisplus.handler;

@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    
    

    @Override
    public void insertFill(MetaObject metaObject) {
    
    
        log.info("start insert fill ....");
        this.setFieldValByName("createTime", new Date(), metaObject);
        this.setFieldValByName("updateTme", new Date(), metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
    
    
        log.info("start update fill ....");
        this.setFieldValByName("updateTme", new Date(), metaObject);
    }
}
3.4 test

We generate a piece of data in the test class and then modify it again

4. Thread-safe operating database

4.1, optimistic lock

**Main application scenarios: **When a record is to be updated, I hope that this record has not been updated by others, which means that thread-safe data updates are implemented

Optimistic lock implementation:

  • When fetching the record, get the current version
  • When updating, bring this version
  • When performing an update, set version = newVersion where version = oldVersion
  • If the version is wrong, the update fails

(1) Add the version field to the database

ALTER TABLE `user` ADD COLUMN `version` INT

(2) Add the version field to the entity class

And add @Version annotation

@Version
    @TableField(fill = FieldFill.INSERT)
    private Integer version;//版本号,在我们修改数据库的时候需要对比

(3) Add the insert default value of version to the meta object processor interface

@Override
public void insertFill(MetaObject metaObject) {
    
    
    ......
    this.setFieldValByName("version", 1, metaObject);
}

(4) Register Bean in MpConfig

Create configuration class

package com.atguigu.config;

import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.baomidou.mybatisplus.extension.injector.LogicSqlInjector;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Author Kilig Zong
 * @Date 2020/10/28 19:20
 * @Version 1.0
 */
@Configuration
public class MyConfig {
    
    


    /***
     * @author Kilig Zong
     * @date 2020/10/28 19:22
     * @description 这个是乐观锁插件,当我们修改数据库的数据的时候,首先会查询数据的版本号,进行对比后再进行修改
     * 如果修改成功的话也会修改我们的版本号,
     * @param
     * @return com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor
     **/
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor(){
    
    
        return new OptimisticLockerInterceptor();
    }
    }

(5) Test optimistic lock can be modified successfully

After the test, analyze the printed sql statement and add 1 to the version value

//4.测试乐观锁
@Test
public void testOptimisticLocker() {
    
    
    //a.添加一条有version的记录
    //b.再根据用户id查询用户信息
    User user = userMapper.selectById(1257493419485151233L);
    user.setName("老zhang");
    //c.更新用户信息
    userMapper.updateById(user);
}

5. Database delete operation

5.1, logical deletion
  • Physical deletion: the actual deletion, the corresponding data is deleted from the database, and the deleted data cannot be queried afterwards
  • Logical deletion: False deletion, change the state of the field in the corresponding data to "deleted state", and then you can still see this data record in the database

(1) Add the deleted field to the database

ALTER TABLE `user` ADD COLUMN `deleted` boolean

(2) Add the deleted field to the entity class

And add @TableLogic annotation and @TableField(fill = FieldFill.INSERT) annotation

@TableLogic//逻辑删除
    @TableField(fill = FieldFill.INSERT)
    private Integer deleted;//逻辑删除状态码

(3) Add the deleted insert default value to the meta object handler interface

@Override
public void insertFill(MetaObject metaObject) {
    
    
    ......
    this.setFieldValByName("deleted", 0, metaObject);
}

(4) Application.properties join configuration

This is the default value, if your default value is the same as the mp default, this configuration is not necessary

mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0

(5) Register Bean in MyConfig

/***
 * @author Kilig Zong
 * @date 2020/10/28 19:38
 * @description 这个是逻辑删除的插件,在我们删除的时候会修改数据库的逻辑删除的状态码,本质上逻辑删除是update
 * @param
 * @return com.baomidou.mybatisplus.core.injector.ISqlInjector
 **/
@Bean
public ISqlInjector sqlInjector(){
    
    
    return new LogicSqlInjector();
}

(6) Test logic deletion

  • After the test, it was found that the data was not deleted, and the value of the deleted field changed from 0 to 1.

  • Analyze the printed sql statement after the test, it is an update

  • **Note: ** The value of the deleted field of the deleted data must be 0 before it can be selected for logical deletion

    @Test
    public void testDeleteUser() {
          
          
        int result = userMapper.deleteById(1257499997827362817L);
        System.out.println(result);
    }
    

    (7) Query after testing logical deletion

    The query operation in MyBatis Plus will also automatically add the judgment of the logical deletion field

    /**
     * 测试 逻辑删除后的查询:
     * 不包括被逻辑删除的记录
     */
    @Test
    public void testLogicDeleteSelect() {
          
          
        User user = new User();
        List<User> users = userMapper.selectList(null);
        users.forEach(System.out::println);
    }
    

    Analyze the printed sql statement after the test, including WHERE deleted=0

    SELECT id,name,age,email,create_time,update_time,deleted FROM user WHERE deleted=0

6. Paging query

6.1, paging plugin

MyBatis Plus comes with a paging plug-in, and the paging function can be realized with a simple configuration

**(1)** Add paging plugin

Add @Bean configuration to the configuration class

/***
     * @author Kilig Zong
     * @date 2020/10/28 20:18
     * @description 这个是我们的分页工具,分页插件
     * @param
     * @return com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor
     **/
    @Bean
    public PaginationInterceptor paginationInterceptor(){
    
    
        return new PaginationInterceptor();
    }
}

(2) Test selectPage paging

**Test: **Finally get relevant data through the page object

@Test
public void testPageQuery() {
    
    
    //a.2代表第二页 b.3代表每页大小
    Page<User> userPage = new Page<>(3, 3);
    //a.分页包装类 b.查询分页条件
    userMapper.selectPage(userPage, null);
    long total = userPage.getTotal();
    System.out.println(total);
    List<User> userList = userPage.getRecords();
    for (User user : userList) {
    
    
        System.out.println(user);
    }

}

7. Other queries

7.1 map query
@Test
public void testQueryMap(){
    
    
    HashMap<String, Object> mapParam = new HashMap<>();
    mapParam.put("name","老zhang");
    List<User> userList = userMapper.selectByMap(mapParam);
    for (User user : userList) {
    
    
        System.out.println(user);
    }
7.2 wrapper query
@Test
public void testQueryWrapper(){
    
    
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.like("email","baomidou.com");
    wrapper.orderByDesc("age");
    List<User> userList = userMapper.selectList(wrapper);
    for (User user : userList) {
    
    
        System.out.println(user);
    }
}

To be continued

Guess you like

Origin blog.csdn.net/kiligggggggg/article/details/109349585