文章目录


@TableName

用于映射bean对象与数据库中的表类名与表名不一致的情况

@TableName(value = "t_user")
public class User {
}

@TableId

自动生成主键id,随着考虑到数据库分库分表,对于单表的拆分,分为垂直分表与水平分表

垂直分表:


将表中某些不常用占用大量空间的列拆分出去
例如:图书馆的文本表,对于文件概要描述,和文章信息id,将概要描述拆分为单独的表


水平分表:


水平分表适合表行数特别大的表,有的公司要求单表行数超过 5000 万就必须进行分表,这个数字可以作为参考,但并不是绝对标准,关键还是要看表的访问性能。对于一些比较复杂的表,可能超过 1000 万就要分表了;而对于一些简单的表,即使存储数据超过 1 亿行,也可以不分表。


对于水平分表表的设计

主键自增:


以最常见的用户 ID 为例,可以按照 1000000 的范围大小进行分段,1 ~ 999999 放到表 1中,1000000 ~ 1999999 放到表2中,以此类推。
优点:平滑扩容新的表
缺点:分布不均匀,由于后期的一些数据删除,原始id会占用占位


Hash :


通过hash取模的方式,将数据分布在所属的数据库编号
复杂点:初始表数量的确定。表数量太多维护比较麻烦,表数量太少又可能导致单表性能存在问题,毕竟单表的查询
优点:表分布均匀
缺点:扩充新的表麻烦,所有数据重新分布


雪花算法


由Twitter公布的分布式主键生成算法,它能够保证不同表的主键的不重复性,以及相同表的主键的有序性
核心思想:
长度共64bit(一个long型)
首先是一个符号位,1bit标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0。
41bit时间截(毫秒级),存储的是时间截的差值(当前时间截 - 开始时间截),结果约等于69.73年。
10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID,可以部署在1024个节点)
12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID)
MybatisPlus注解的使用_主键
优点:整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞,并且效率较高。


对于一些表创建属性为非空的主键id列,且未设置自动递增的字段,为主键列添加 @TableId 注解

value属性

实体类的属性名是 id,数据库的列名是 uid,此时使用 value 属性将属性名映射到列名


@TableId(value = “uid”)
private String id;


type属性

type属性用来定义主键策略

IdType.ASSIGN_ID:使用基于雪花算法的策略生成数据id

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

注意:当对象的id被明确赋值时,不会使用雪花算法

IdType.AUTO:使用数据库的自增策略


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


注意:该类型请确保数据库设置了 ID自增 否则无效

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

#全局设置主键生成策略
-type=auto

@TableField

fill 属性

对于数据库中字段的自动填充

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

@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;

实现元对象处理器接口 -> 创建handler包,创建MyMetaObjectHandler类

package com.zyd.handle;

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

import java.time.LocalDateTime;

@Component
public class MyHandle implements MetaObjectHandler {
/**
* 插入操作
* @param metaObject
*/
@Override
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
}

/**
* 更新操作
* @param metaObject
*/
@Override
public void updateFill(MetaObject metaObject) {
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
}
}

避免自动填充时开销过大,填充前先判断当前对象中是否有相关属性

@TableLog

1.逻辑删除

物理删除:真实删除,将对应数据从数据库中删除,之后查询不到此条被删除的数据

逻辑删除:假删除,将对应数据中代表是否被删除字段的状态修改为“被删除状态”,之后在数据库中仍旧能看到此条数据记录

@TableLogic
@TableField(value = "is_deleted")
private Integer deleted;
-- 实际执行的SQL
update user set is_deleted=1 where id = 1 and is_deleted=0

在查询中

2
select id,name,is_deleted from user where is_deleted=0