1 问题描述
-
现有一个需要手动设置ID的需求,同时还能够兼容ID自增
-
原有设计
-
原有插入代码
-
生成的SQL
-
INSERT INTO request_system ( channel_name) VALUES (?)
-
-
以之前(上图)的设计来看,只能够满足ID自增,即使给待插入的实体类中设置ID字段,也无法采用设置的ID,还是会自增一个ID
2 快速解决
直接跳到结论即可
3 场景举例
- 现有A表和B表
- B表是A表的扩展表
- B表可以单独新增数据
- A表格在增加数据之后,需要同步该数据到B表,并且ID要保持一致
4 得出需求
- 需要在ID设置为空的时候,自增ID
- 需要在ID设置有值的时候,采用设置的这个值
5 源码流程
需要探究的问题:在BaseMapper调用insert方法后
- SQL是怎么得到的
- 参数和参数值是怎么来的
- 有哪些因素会影响将ID字段添加到SQL中
关键在最后的TableInfo表 5.9
5.1 MybatisPlusAutoConfiguration
5.2 MybatisSqlSessionFactoryBean
5.3 XMLMapperBuilder
5.4 MapperRegistry
5.5 MybatisMapperAnnotationBuilder
5.6 AbstractSqlInjector
5.7 AbstractMethod
5.8 Insert
-
sqlMethod决定了SQL模板
-
columnScript是参数模板
-
columnScript是参数值模板
5.9 TableInfo
- 这里决定了ID是否要加入到SQL
6 Type对插入ID造成的影响测试
6.1 Type.AUTO
测试结论:如果type类型为Type.AUTO,不会将主键ID增加到SQL的拼接中
6.2 Type.NONE
6.2.1 设置了ID
6.2.2 没设置ID
6.3 Type.INPUT
6.3.1 设置了ID
6.3.2 没设置ID
6.4 Type.ASSIGN_ID
会默认设置ID(根据雪花算法)
7 结论
7.1 解决方案1
-
编写XXXMapper.xml,在xml中编写SQL语句进行ID插入
-
修改插入语句(改为调用mapper的方式去插入)
7.2 解决方案2(推荐)
- 修改主键的ID类型为INPUT(仅适用于Mybatis-plus)
8 参考资料
https://juejin.cn/post/6844904142658338829
9 最后
感谢大家看到这里,文章有不足,欢迎大家指出;如果你觉得写得不错,那就给我一个赞吧,欢迎大家关注和收藏转发文章!