Mybatis-plus使用--常用注解

本文详细介绍了MyBatis Plus中的实体注解,包括@TableId、@TableField、@Version、@EnumValue和@TableLogic的用法。通过这些注解,可以方便地管理主键、字段填充、乐观锁、枚举类型映射和逻辑删除。同时,文中给出了具体的配置和测试案例,展示了如何在实际操作中应用这些注解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

直接官方的文档


  • @TableName

表名

  • @TableId

主键

属性类型必须指定默认值描述
valueString“”主键字段名
typeEnumIdType.NONE主键类型

IdType

描述
AUTO数据库ID自增
NONE无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)
INPUTinsert前自行set主键值
ASSIGN_ID分配ID(主键类型为Number(Long和Integer)或String)(since 3.3.0),使用接口IdentifierGenerator的方法nextId(默认实现类为DefaultIdentifierGenerator雪花算法)
ASSIGN_UUID分配UUID,主键类型为String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID(默认default方法)
ID_WORKER分布式全局唯一ID 长整型类型(please use ASSIGN_ID)
UUID32位UUID字符串(please use ASSIGN_UUID)
ID_WORKER_STR分布式全局唯一ID 字符串类型(please use ASSIGN_ID)

也就是对应着我们在底层中讲解的IdType主键类型

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.baomidou.mybatisplus.annotation;

public enum IdType {
    AUTO(0), //自增,程序中赋值,结果根据数据库的自增来
    NONE(1), //雪花算法实现
    INPUT(2),//	默认需要提供,不提供的话程序是赋值为null,数据库为自增
    ASSIGN_ID(3),//跟默认是一样的
    ASSIGN_UUID(4),//主键的数据类型必须是String,自动生成UUID进行赋值,而且数据库中的主键不可以设置为自增类型
    /** @deprecated */
    @Deprecated
    ID_WORKER(3),
    /** @deprecated */
    @Deprecated
    ID_WORKER_STR(3),
    /** @deprecated */
    @Deprecated
    UUID(4);

    private final int key;

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

    public int getKey() {
        return this.key;
    }
}

总结:
这里总结的最好的

  • @TableField

映射非主键字段

属性类型必须指定默认值描述
valueString“”数据库字段名
existbooleantrue是否为数据库表字段
selectbooleantrue是否进行 select 查询
fillEnumFieldFill.DEFAULT字段自动填充策略

项目中的创建时间、修改时间、以及状态可以使用fill策略

Fill使用

1.实体类

    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @TableField(fill=FieldFill.UPDATE)
    private LocalDateTime updateTime;

进行创建时间和修改时间的添加

2.添加配置handler策略

MyMeteObjectHandler类

package com.mybatisplusstudty.handler;

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

import java.time.LocalDateTime;

/**
 * @Program: mybatisplus
 * @Description
 * @Author: 涛涛 * ^ *
 * @Create: 2021-01-07 16:50
 **/
@Component
public class MyMeteObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        this.setFieldValByName("createTime", LocalDateTime.now(),metaObject);
        this.setFieldValByName("updateTime", LocalDateTime.now(),metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("updateTime", LocalDateTime.now(),metaObject);

    }
}

3.数据库添加字段

添加时间字段

4.测试

    @Test
    void insert() {
        User user = new User();

        user.setId(1212);
        user.setEmail("1339906213@qq.com");
        user.setLastName("小明");
        user.setAge(12);
        user.setGender("男");
        userMapper.insert(user);
    }
    @Test
     void update(){
        User user = new User();
        user.setId(1212);
        user.setAge(16);
        userMapper.updateById(user);

    }

5.结果

JDBC Connection [HikariProxyConnection@1878045132 wrapping com.mysql.cj.jdbc.ConnectionImpl@3b55dd15] will not be managed by Spring
==>  Preparing: INSERT INTO user ( id, last_name, email, gender, age, create_time ) VALUES ( ?, ?, ?, ?, ?, ? ) 
==> Parameters: 1212(Integer), 小明(String), 1339906213@qq.com(String),(String), 12(Integer), 2021-01-07T16:59:41.905(LocalDateTime)
<==    Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@73ae0257]

JDBC Connection [HikariProxyConnection@1142931081 wrapping com.mysql.cj.jdbc.ConnectionImpl@6088451e] will not be managed by Spring
==>  Preparing: UPDATE user SET age=?, update_time=? WHERE id=? 
==> Parameters: 16(Integer), 2021-01-07T16:58:18.297(LocalDateTime), 1212(Integer)
<==    Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6fc1020a]

测试数据

  • @Version

标记乐观锁,通过version字段来保证数据的安全性,当修改数据的时候,会以version作为条件,当然条件成立的时候才可以修改成功。

version = 1;
线程1:update version = 2 where version = 1;
线程2:update version = 2 where version = 1;

1.数据库表中添加version字段,默认值为1,并且可以在策略中添加初始化默认值

添加version字段

this.setFieldValByName("version", 1, metaObject);

2.实体类中添加成员变量version并且添加@Version作为乐观锁的标识

 	@Version
    private Integer version;

3.注册配置类进行乐观锁的生效

package com.mybatisplusstudty.config;

import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

/**
 * @Program: mybatisplus
 * @Description
 * @Author: 涛涛 * ^ *
 * @Create: 2021-01-07 17:11
 **/
@EnableTransactionManagement
@Configuration
@MapperScan("com.mybatisplusstudty.mapper")
public class MyBatisPlusConfig {
    /**
     * 返回一个乐观锁对象,并将其返回到IOC容器中
     * @return
     */
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }
//     MP3.4.1之后的版本才有
//    @Bean
//    public MybatisPlusInterceptor mybatisPlusInterceptor() {
//        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 分页插件
//        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); // 乐观锁插件
//        return interceptor;
//    }
}

4.测试

package com.mybatisplusstudty.mapper;

import com.mybatisplusstudty.entity.entity.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import static org.junit.jupiter.api.Assertions.*;

/**
 * @Description:
 * @Author: 涛涛 *^*
 * @Date: 2021/1/7 15:13
 */
@SpringBootTest
class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    void test() {
        userMapper.selectList(null).forEach(System.out::println);
    }

    @Test
    void selectById() {
        System.out.println( userMapper.selectById(9).toString());
    }

    @Test
    void insert() {
        User user = new User();

        user.setId(9);
        user.setEmail("1339906213@qq.com");
        user.setLastName("小明");
        user.setAge(12);
        user.setGender("男");

        userMapper.insert(user);
    }

    @Test
    void update() {
        User user = userMapper.selectById(9);

        user.setLastName("小红");
//        user.setVersion(user.getVersion());
        User user1 = userMapper.selectById(9);

        user1.setLastName("小黄");
       // user1.setVersion(user.getVersion());
        userMapper.updateById(user1);
        userMapper.updateById(user);


    }

}

Version的使用
这里使用时候,需要注意的是这个插件的运行流程,而且是只能在update和updateByID的方法时候才可以去用
流程:

  1. 先通过Id查出
  2. 然后去set
  3. 然后开始跟新
    MP乐观锁插件
  • @EnumValue

通枚举类注解(注解在枚举字段上),将数据库的字段映射为实体类的枚举类型成员变量

第一种方式

1.实体类

    private StatusEnum status;

2.创建枚举类型

package com.mybatisplusstudty.enums;

import com.baomidou.mybatisplus.annotation.EnumValue;

/**
 * @Program: mybatisplus
 * @Description
 * @Author: 涛涛 * ^ *
 * @Create: 2021-01-07 17:50
 **/
public enum StatusEnum {

    WORK(1, "上班"), REST(0, "休息");
    @EnumValue
    private final Integer code;
    private String msg;

    StatusEnum(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }
}

3.数据库添加字段

@EnumValue注解使用
这里注意一下,数据库的类型不用定义为tinyint,因为数据库会默认将这个类型的转换为boolean值,定义为int就可以了,还有不用设置 默认值

4.配置application.yml文件

mybatis-plus:
  type-enums-package: com.mybatisplusstudty.enums

5.测试

测试

第二种方式

实现接口

1.实体类

    private StatusEnum status;

2.创建枚举类型

package com.mybatisplusstudty.enums;

import com.baomidou.mybatisplus.annotation.EnumValue;
import com.baomidou.mybatisplus.core.enums.IEnum;

import java.io.Serializable;

/**
 * @Description:
 * @Author: 涛涛 *^*
 * @Date: 2021/1/8 9:49
 */
public enum SexEnum implements IEnum {
    MALE(0, "男性"), FEMALE(1, "女");
    @EnumValue
    private Integer code;
    private String age;

    SexEnum(Integer code, String age) {
        this.code = code;
        this.age = age;
    }


    @Override
    public Integer getValue() {
        return this.code;
    }
}

3.数据库添加字段

@EnumValue注解使用

4.配置application.yml文件

mybatis-plus:
  type-enums-package: com.mybatisplusstudty.enums

5.测试

测试

  • @TableLogic

映射逻辑删除

属性类型必须指定默认值描述
valueString“”逻辑未删除值
delvalString“”逻辑删除值

1.数据库添加字段

注解的使用

2.实体类中添加属性

    @TableLogic
    private Integer deleted;

3.application.yml文件中添加配置

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

4.测试

    @Test
    void delete(){
        userMapper.deleteById(6);
    }

逻辑删除

5.查询测试

JDBC Connection [HikariProxyConnection@1708084589 wrapping com.mysql.cj.jdbc.ConnectionImpl@1b410308] will not be managed by Spring
==>  Preparing: SELECT id,last_name,email,gender,age,create_time,update_time,version,sex,status,deleted FROM user WHERE deleted=0 
==> Parameters: 
<==    Columns: id, last_name, email, gender, age, create_time, update_time, version, sex, status, deleted
<==        Row: 7, 詹姆斯, 1339906213@qq.com,, 12, 2021-01-08 08:57:02, 2021-01-08 08:57:22, 1, 1, 0, 0
<==        Row: 9, 小黄, 1339906213@qq.com,, 12, 2021-01-08 09:02:50, 2021-01-08 09:09:32, 2, 0, 1, 0
<==      Total: 2
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@35c9a231]
User(id=7, lastName=詹姆斯, email=1339906213@qq.com, gender=, age=12, createTime=2021-01-08T08:57:02, updateTime=2021-01-08T08:57:22, version=1, sex=FEMALE, status=REST, deleted=0)
User(id=9, lastName=小黄, email=1339906213@qq.com, gender=, age=12, createTime=2021-01-08T09:02:50, updateTime=2021-01-08T09:09:32, version=2, sex=MALE, status=WORK, deleted=0)

这个时候测试的查全部就没有了刚刚删除的那条数据 ,但是在数据库中该数据还是在的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小七会喷火

小七想要bi

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值