MybatisPlus的增删改查以及特点

MybatisPlus的增删改查以及特点

1.分布式系统唯一ID生成方案

系统唯一ID是我们在设计一个系统的时候常常会遇见的问题,也常常为这个问题而纠结。生成ID的方法有很多,适应不同的场景、需求以及性能要求。所以有些比较复杂的系统会有多个ID生成的策略。以下链接是非常全面的介绍解决方案,在我们解决多个数据库的id唯一性的问题

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

2.MP的主键自增策略

2.1 ASSIGN_ID

MyBatis-Plus默认的主键策略是:ASSIGN_ID (使用了雪花算法)

@TableId(type = IdType.ASSIGN_ID)
private String id;
2.2 AUTO自增策略

(1)需要在创建数据表的时候设置主键自增
(2)实体字段中配置 @TableId(type = IdType.AUTO

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

要想影响所有实体的配置,可以设置全局主键配置

#全局设置主键生成策略
mybatis-plus.global-config.db-config.id-type=auto
2.3 其他类型见源码
/*
 * Copyright (c) 2011-2020, hubin (jobob@qq.com).
 * <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.自动填充

需求描述:

项目中经常会遇到一些数据,每次都使用相同的方式填充,例如记录的创建时间,更新时间等。我们可以使用MyBatis Plus的自动填充功能,完成这些字段的赋值工作。

3.1、数据库修改

在User表中添加datetime类型的新的字段 创建时间 create_time、修改时间 update_time

3.2实体类的修改

我们需要在javabean的属性冠上注解

如下图的代码

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实现元对象处理器接口

注意:不要忘记添加 @Component 注解

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测试

我们在测试类中生成一条数据然后再次修改

4.线程安全的操作数据库

4.1、乐观锁

**主要适用场景:**当要更新一条记录的时候,希望这条记录没有被别人更新,也就是说实现线程安全的数据更新

乐观锁实现方式:

  • 取出记录时,获取当前version
  • 更新时,带上这个version
  • 执行更新时, set version = newVersion where version = oldVersion
  • 如果version不对,就更新失败

(1)数据库中添加version字段

ALTER TABLE `user` ADD COLUMN `version` INT

(2)实体类添加version字段

并添加 @Version 注解

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

(3)元对象处理器接口添加version的insert默认值

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

(4)在 MpConfig中注册 Bean

创建配置类

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)测试乐观锁可以修改成功

测试后分析打印的sql语句,将version的数值进行了加1操作

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

5.数据库删除操作

5.1、逻辑删除
  • 物理删除:真实删除,将对应数据从数据库中删除,之后查询不到此条被删除数据
  • 逻辑删除:假删除,将对应数据中代表是否被删除字段状态修改为“被删除状态”,之后在数据库中仍旧能看到此条数据记录

(1)数据库中添加 deleted字段

ALTER TABLE `user` ADD COLUMN `deleted` boolean

(2)实体类添加deleted 字段

并加上 @TableLogic 注解 和 @TableField(fill = FieldFill.INSERT) 注解

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

(3)元对象处理器接口添加deleted的insert默认值

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

(4)application.properties 加入配置

此为默认值,如果你的默认值和mp默认的一样,该配置可无

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

(5)在 MyConfig 中注册 Bean

/***
 * @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)测试逻辑删除

  • 测试后发现,数据并没有被删除,deleted字段的值由0变成了1

  • 测试后分析打印的sql语句,是一条update

  • **注意:**被删除数据的deleted 字段的值必须是 0,才能被选取出来执行逻辑删除的操作

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

    (7)测试逻辑删除后的查询

    MyBatis Plus中查询操作也会自动添加逻辑删除字段的判断

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

    测试后分析打印的sql语句,包含 WHERE deleted=0

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

6.分页查询

6.1、分页插件

MyBatis Plus自带分页插件,只要简单的配置即可实现分页功能

**(1)**添加分页插件

配置类中添加@Bean配置

/***
     * @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)测试selectPage分页

**测试:**最终通过page对象获取相关数据

@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.其他查询

7.1 map查询
@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查询
@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);
    }
}

未完待续

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值