使用Jooq 3.18批量插入MySQL时出现Connection为Null的空指针异常
问题原因
你遇到的NullPointerException是因为**batchInsert()是Jooq针对JDBC的同步批量操作API**,它会尝试获取java.sql.Connection,但你使用的是R2DBC反应式驱动,环境中不存在JDBC连接,因此触发空指针。单条插入正常是因为你用的是反应式API,而批量插入误用了JDBC的同步API。
解决方案
改用Jooq针对R2DBC的反应式批量插入API,通过insertInto()构建批量插入语句,示例代码如下:
fun create(tags: List<String>) { // 构建批量插入语句 val batchInsert = dsl.insertInto(TAGS) .columns(TAGS.ID, TAGS.USER_ID, TAGS.TAG) // 为每个tag添加插入值 .apply { tags.forEach { tag -> values( UUID.randomUUID().toString(), "dc5f0fbf-7979-4bcd-9f99-c3261a8d2ffe", tag ) } } // 执行异步批量插入 batchInsert.executeAsync().await() }
或者更简洁的写法,使用batch()方法:
fun create(tags: List<String>) { val insertTemplate = dsl.insertInto(TAGS) .columns(TAGS.ID, TAGS.USER_ID, TAGS.TAG) .values(null, null, null) // 占位符,后续批量填充值 // 将每个tag转换为对应的参数数组 val batchParams = tags.map { tag -> arrayOf( UUID.randomUUID().toString(), "dc5f0fbf-7979-4bcd-9f99-c3261a8d2ffe", tag ) } // 执行批量异步插入 insertTemplate.batch(batchParams).executeAsync().await() }
关键说明
- R2DBC是反应式驱动,必须使用Jooq提供的反应式API(所有带
Async后缀的方法,如executeAsync()),不能使用JDBC的同步API(如batchInsert()、execute())。 - 你的Jooq配置是正确的,
DSL.using(cf)已经创建了适配R2DBC的反应式DSLContext,只需确保操作时使用对应的反应式批量API即可。
内容的提问来源于stack exchange,提问作者hello_928343
相关产品推荐
相关产品推荐

