baomidou / mybatis-plus

An powerful enhanced toolkit of MyBatis for simplify development
https://baomidou.com
Apache License 2.0
16.25k stars 4.29k forks source link

当自增ID非主键时,增加自动回填自增id以及忽略更新 #6255

Closed lijinan closed 2 months ago

lijinan commented 2 months ago

请详细描述需要增加的功能 MSSQL没有强制自增ID必须为主键,这种情况下,如果主键是Guid,另外有自增ID列时,代码生成器生成的代码就会有问题,即update的时候,会把自增id也一并更新,导致报错。必须手动在TableField加上更新策略。

建议 TableField,多加一个是否自增ID属性,通过该属性 在新增后自动回填,并且更新时自动忽略

希望被采纳,谢谢

nieqiurong commented 2 months ago

描述清楚问题与需求

lijinan commented 2 months ago

你好,场景是这样的: 数据库:MSSQL 表:user(id, key, name ,.......) 其中: key是代码生成的string类型的 主键, id是数据库的自增id( identity(1,1) ) 现在通过生成器生成的 entity 是这样的 @Data public class User{ @TableField("id") Integer id;

@TableId("key")
 String key;

@TableField("name")
 String name;

} 问题1: User user=userService.getOne("xxxx");
user.setName("test"); userService.updateById(user); 会报错,因为id是自增id,不允许update

问题2: User user=new User(); user.setKey("xxxxxxxxxxx"); user.setName("test"); userService.save(user); 新增记录后,自增Id 没有值,需要重新去数据库取

建议1: 生成器,可以自动判断非主键的自增列,生成这样的代码: @TableField(value="id",updateStrategy = FieldStrategy.NEVER) Integer id; 建议2:对于有自增列的,insert后,无论是否主键,也可以自动获取自增id值

感谢

nieqiurong commented 2 months ago

类似PG标识列,这种不确定执行完insert后驱动有没有返回的。

lijinan commented 2 months ago

确实对于 建议2 未必支持所有数据库 或者是否可以先实现建议1 如果需要,我这边也可以提pr,我看了一下源码,第一点还是比较好实现的

nieqiurong commented 2 months ago

如果是使用元数据的方式查询的话,能获取到自增列,但无法判定能否更新,在PG下,标识列是有GENERATED ALWAYS 和 GENERATED BY DEFAULT 区分的,SQL server下就不清楚了,要改动的话只能改用SQL查询的方式。

第二点的话,有点类似数据库默认值你却要读到一样的,如果数据库支持RETURNING的话倒还有可能,但SQL server并不支持,最好还是insert完之后自己在select一次了。