mybatis-plus:主键id、uuid

mysql-8.0.33-winx64.zip(免安装版)

spring boot 2.7.13

Java 8

mybatis-plus-boot-starter 3.5.3.1
--
 

序言

本文 测试&记录 spring boot 项目 中使用 mybatis-plus 时,主键(整型的 id、字符串型 的 uuid)的生成。
 

准备工作

mybatis-plus 的 spring boot 版本:
<dependency>
	<groupId>com.baomidou</groupId>
	<artifactId>mybatis-plus-boot-starter</artifactId>
	<version>3.5.3.1</version>
</dependency>

建立数据表:tab_id

主键 id 为 Integer。

tab_id 表
 CREATE TABLE `tab_id` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `name` varchar(100) NOT NULL COMMENT '名称',
  `create_time` datetime NOT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='主键为整型类型的表';

 建立数据表:tab_uuid

主键 uuid 为 VARCHAR(100)。

tab_uuid 表
 CREATE TABLE `tab_uuid` (
  `uuid` varchar(100) NOT NULL COMMENT '主键uuid',
  `name` varchar(100) NOT NULL COMMENT '名称',
  `create_time` datetime NOT NULL COMMENT '创建时间',
  PRIMARY KEY (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

 

测试 tab_id

进入 spring boot项目,

建立实体类:

class TabId
 import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.util.Date;

@Data
@TableName(value = "tab_id")
public class TabId {

    private Integer id; // 没有注解修饰

    private String name;

    private Date createTime;

}

 建立实体类对于的 Mapper:

 

interface TabIdMapper
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;

public interface TabIdMapper extends BaseMapper<TabId> {
}

 建立测试类:测试 添加、查询

class TabIdMapperTests
 import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Date;
import java.util.List;

@SpringBootTest
@TestMethodOrder(value = MethodOrderer.OrderAnnotation.class)
public class TabIdMapperTests {

    @Autowired
    private TabIdMapper tabIdMapper;

    @Test
    @Order(1)
    public void testInsert() {
        Date now = new Date();

        TabId ent = new TabId();
        ent.setName(now.toString());
        ent.setCreateTime(now);
        System.out.println("ent=" + ent); // 未设置 id

        int dbret = tabIdMapper.insert(ent);
        System.out.println("testInsert dbret=" + dbret);
        System.out.println("saved ent=" + ent);
    }

    @Test
    @Order(2)
    public void testSelect() {
        List<TabId> dbret = tabIdMapper.selectList(null);
        System.out.println("testSelect dbret=" + dbret);
    }

}

 执行测试 及 结果:

# testInsert()
ent=TabId(id=null, name=Wed Jul 26 20:54:55 CST 2023, createTime=Wed Jul 26 20:54:55 CST 2023)
testInsert dbret=1
saved ent=TabId(id=-894128127, name=Wed Jul 26 20:54:55 CST 2023, createTime=Wed Jul 26 20:54:55 CST 2023)

# testSelect()
testSelect dbret=[TabId(id=-894128127, name=Wed Jul 26 20:54:55 CST 2023, createTime=Wed Jul 26 20:54:55 CST 2023)]

可以看到:

1)不需要设置主键id的值,也可以生成;

2)可是,生成的主键id为 负数,与数据库设置的 自动增长不符;

 

再次执行测试,新记录的 主键id = id=-936005631。

数据库展示如下:

--

 

使用 @TableId

mybatis-plus官文有介绍:

https://baomidou.com/pages/223848/#tableid

有 2个属性:

 关于 type 属性的介绍如下(*本文测试重点*):

 

1)仅注解

结果:

此时,和 没有使用时相同。

 

2)type = AUTO

连续执行 2次测试:实现了 id自增

--

 

疑问:

此时,不设置数据表主键id自增会怎样?

 

3)type = ASSIGN_ID

连续执行 2次测试:

 

测试 tab_uuid

建立 实体类、Mapper 及 测试类。

 

默认情况下,uuid 没有使用 @TableId 注解, 执行 2次测试,查看结果:

测试 testInsert 失败,错误信息如下:

org.springframework.dao.DataIntegrityViolationException: 
### Error updating database.  Cause: java.sql.SQLException: Field 'uuid' doesn't have a default value

没有默认值,mybatis-plus 也不会 自动造一个默认值。

 

疑问:

如果 给这个 uuid 设置一个 动态变化的默认值呢?

MySQL 8 中 应该有这样的函数吧?

 

使用 @TableId

1)仅 @TableId

测试通过:uuid 是一个长长的数字

ent=TabUuid(uuid=null, name=测试uuid, createTime=Wed Jul 26 21:33:18 CST 2023)
testInsert dbret=1
saved ent=TabUuid(uuid=1684195188743102465, name=测试uuid, createTime=Wed Jul 26 21:33:18 CST 2023)

testSelect dbret=[TabUuid(uuid=1684195188743102465, name=测试uuid, createTime=Wed Jul 26 21:33:18 CST 2023)]

 

2)type=ASSIGN_ID

测试结果:同 不设置 type 时。

 

3)type=ASSIGN_UUID

测试结果:uuid 为一个 数字、字母组成的字符串。

 

三次测试结果如下:

--

 

关于 id、uuid 的区别

搜索引擎 可以找到 不少相关文章:

--

 

另外,主键还会使用 著名的雪花算法 来生成,而不是 使用 mybatis-plus 或 数据库本身的工具来生成。

一篇博文:(知乎)分布式ID神器之雪花算法简介

https://zhuanlan.zhihu.com/p/85837641

还有更多资料,读者可以自行搜索。还要考虑该算法的 最佳实践 吧。

 

---END---

 

本文链接:

https://www.cnblogs.com/luo630/p/17583596.html

 

后记

之前遇到数据库数据同步的场景,要求每个表都需要一个主键列

关于,mybatis-plus 生成主键的原理,孤暂未深究。

 

参考资料

1、mybatis-plus 快速入门》注解

https://baomidou.com/pages/223848/#tablename

2、Spring Boot 单元测试(五)自定义测试顺序

https://juejin.cn/post/7041886698464083998

作者:又语
2021-12-15 19:17

3、

 

 

Ben发布于博客园

Ben发布于博客园

 

posted @ 2023-07-26 21:48  快乐的凡人721  阅读(165)  评论(0编辑  收藏  举报