麒麟正青春

 

sqlite-jdbc版本导致插入数据自增id问题

1、问题如下图,

sqlite-jdbc3.44.1.0版本与mybatisplus设置自增id主键问题,使用sqlite-jdbc3.42.0.0即可解决

 

Exception in thread "JavaFX Application Thread" org.springframework.dao.InvalidDataAccessApiUsageException: Error getting generated key or setting result to parameter object.

Cause: java.sql.SQLFeatureNotSupportedException: not implemented by SQLite JDBC driver
; not implemented by SQLite JDBC driver; nested exception is java.sql.SQLFeatureNotSupportedException: not implemented by SQLite JDBC driver

pom文件修改依赖为

<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<!-- <version>3.44.1.0</version>-->
<version>3.42.0.0</version>
</dependency>
程序执行插入数据成功。

 

参考:https://blog.csdn.net/mrxutada/article/details/119239596?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-1-119239596-blog-129272976.235^v40^pc_relevant_3m_sort_dl_base1&spm=1001.2101.3001.4242.2&utm_relevant_index=4

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

文章目录
问题
解决方案
拓展阅读
1、MyBatis-Plus内置支持的数据库主键序列
2、MyBatis-Plus主键策略
3、mybatis-plus版本不同,oracle序列配置不同
4、Orcale11 主键自增策略
5、数据库的逻辑删除字段类型

重点看解决方案第三个即可
问题
在数据库使用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;
————————————————
版权声明:本文为CSDN博主「utada hikki」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/mrxutada/article/details/119239596

 

posted on 2024-01-04 11:25  麒麟正青春  阅读(306)  评论(0编辑  收藏  举报

导航