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发布于博客园
标签:uuid,主键,ent,plus,mybatis,import,id From: https://www.cnblogs.com/luo630/p/17583596.html