Mybatis-plus+Oracle+主键自增策略+Error getting generated key......报错


重点看解决方案第三个即可

问题

在数据库使用postgres和oracle的同时,最开始设置的是主键ID自增,
@TableId(value = “id”, type = IdType.AUTO)
private Long id;
用的mybatis-plus的底层的方法插入数据,postgres数据库插入数据成功,不会报错;
oracle(11版本)插入数据成功,但是报错Error getting generated key or setting result to parameter object,即:获取生成的键或将结果设置为参数对象时出错。
原因:在Oracle数据库中不支持主键自增策略,它是通过Sequence序列来进行完成的,因此需要在MP中进行相关配置。也就是说拿到是序列(虽然你在数据库看起来是1、2、3这样的),自然无法对应上我们的id。

解决方案

1、不适用我的解决方案——xml配置
在xml文件中写的插入语句里加上useGeneratedKeys="false"或者将useGeneratedKeys="true"和keyProperty="id"删除

<insert id="create" parameterType="java.util.List" useGeneratedKeys="false" keyProperty="id">

或者

<insert id="create" parameterType="java.util.List">

对于我来说,没有用,我没有用xml文件写sql语句。

2、不适用我的解决方案——@Options注解
添加@Options(useGeneratedKeys=true,keyProperty=“id”,keyColumn=“id”)注解,useGeneratedKeys=true表示使用数据库自动增长的主键,keyColumn用于指定数据库table中的主键,keyProperty用于指定传入对象的成员变量。设置是否使用JDBC的getGenereatedKeys()方法获取主键并赋值到keyProperty设置的对象的属性中,也就是就是把自增长的主键值赋值给对象相应的属性。

@Insert("INSERT INTO ......")
@Options(useGeneratedKeys = true, keyProperty = "xxx.id",keyColumn="id")
void add(@Param("xxx") Xxx xxx);

这个是注解是放在方法上的,用在mapper类中的方法上,如果采用注解的方式写sql的话应该也是可以的。
但是还是不适用我,我用的mybatis-plus底层提供的那些方法,比如这些
在这里插入图片描述
我的mapper类中没有方法,也就没有办法添加这个注解,将Options注解直接添加到insert上会报错,添加到调用insert方法的service层的方法上也不会起作用。
3、适用我的解决方案——@KeySequence+OracleKeyGenerator配置
1)在mybatisplus配置文件(MyBatisPlusConfig,有@Configuration注解)中加入OracleKeyGenerator的bean配置,让mp支持oracle主键策略。

MyBatisPlusConfig.java配置
在这里插入图片描述

	/**
     * Sequence主键自增
     */
    @Bean
    public OracleKeyGenerator oracleKeyGenerator() {
        return new OracleKeyGenerator();
    }

2)在实体类上加@KeySequence注解,value为oracle数据库中生成的序列名称,并且主键id要用INPUT方式。
在这里插入图片描述
3.1.2自动匹配,无需指定clazz。

实体配置
在这里插入图片描述
在这里插入图片描述
这样就不会报错了!

注:
如果需要多个实体用同一个序列,可以将@keySequence 定义在父类中, 可实现多个子类对应的多个表公用一个 Sequence。

拓展阅读

1、MyBatis-Plus内置支持的数据库主键序列

1、DB2KeyGenerator
2、H2KeyGenerator
3、KingbaseKeyGenerator
4、OracleKeyGenerator
5、PostgreKeyGenerator
在@Configuration 注解的mp配置类中定义好 @Bean就可以。

2、MyBatis-Plus主键策略

注解>全局
①注解配置主键方式:

@TableId(value = “id”, type = IdType.AUTO)
private Long id;

IdType
AUTO:数据库ID自增
INPUT:用户输入ID
NONE:该类型为未设置主键类型,注解里等于跟随全局,全局里约等于 INPUT
ASSIGN_ID:使用雪花算法分配ID,主键类型为Number(Long和Integer)或String
ASSIGN_UUID:分配UUID,主键类型为String
ID_WORKER:分布式全局唯一ID 长整型类型,已弃用
UUID:UUID:32位UUID字符串,已弃用
ID_WORKER_STR:分布式全局唯一ID 字符串类型,已弃用
在这里插入图片描述

②全局配置主键方式

mybatis-plus:
  global-config:
    db-config:
      id-type: auto

特别说明:
当实体的主键没有配置的时候,也就是既没有注解,也没有全局配置。
private Long id;
生成的ID是这样的
在这里插入图片描述
mp使用了分配ID——ASSIGN_ID(默认)
在这里插入图片描述
在这里插入图片描述
3.2版本,源码在MybatisDefaultParameterHandler里面,3.4版本以上,过时了,源码在MybatisParameterHandler类里面,内容还是差不多。
在这里插入图片描述

3、mybatis-plus版本不同,oracle序列配置不同

mybatis-plus 3以下,在yaml配置策略支持和类型

mybatis-plus:
  mapper-locations: classpath:/mapper/*Mapper.xml
  global-config:
    id-type: auto
    # Sequence序列接口实现类配置
    key-generator: com.baomidou.mybatisplus.incrementer.OracleKeyGenerator

在这里插入图片描述

mybatis-plus 3以上,在配置类中配置
在这里插入图片描述

	/**
     * Sequence主键自增
     */
    @Bean
    public OracleKeyGenerator oracleKeyGenerator() {
        return new OracleKeyGenerator();
    }

4、Orcale11 主键自增策略

Oracle11是序列加触发器实现主键自增策略的,如下写法:

--序列
drop sequence REGULATORY_REPORT_SEQ;
create sequence REGULATORY_REPORT_SEQ
minvalue 1    -- 最小值=1
maxvalue 999999999999999999999999999  -- 指定最大值 
-- 或nomaxvalue      -- 没有最大值
-- NOCYCLE;      -- 不循环
start with 1   -- 从1开始
increment by 1  -- 每次递增1
cache 20;


--触发器
drop trigger REGULATORY_REPORT_SEQ;
create or replace trigger REGULATORY_REPORT_SEQ before insert on REGULATORY_REPORT  
REFERENCING OLD AS "OLD" NEW AS "NEW" FOR EACH ROW
begin
    SELECT REGULATORY_REPORT_SEQ.NEXTVAL INTO :NEW.ID FROM DUAL;
end;

注:
在 Oracle 11g 中,设置自增字段,需要先创建序列(SQUENCE)再创建一个触发器(TRIGGER)。
Oracle12版本后,引进了Identity Columns新特性,从而实现了列自增长功能,Oracle实现了类似MySQL中的auto_increment的自增列。

5、数据库的逻辑删除字段类型

针对是否,有无等字段类型,不同数据库类型也不同
mysql:没有布尔型,一般使用tinyint。
postgres:有布尔型,为bool,也可以使用int2类型,都支持。
oracle:没有布尔型,一般使用NUMBER类型。

mybatis-plus的逻辑删除默认是布尔类型,逻辑删除是true,未删除是false,针对不同数据,设置实体类型不同,如果是Boolean类型,yaml可不指定。如果是Integer类型,则yaml文件需要指定转换,如下:

步骤1:配置com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig

mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: isDelete # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
      logic-delete-value: 1 # 逻辑已删除值(默认为 1)
      logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

步骤2: 实体类字段上加上@TableLogic注解
@TableLogic
private Integer isDelete;

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值