java - 使用 JOOQ 插入忽略多个 pojo

标签 java mysql spring-boot jooq

我想用 Jooq 实现如下目标:

INSERT IGNORE INTO table1 (col1,col2,col3) 
VALUES ('val1','val2','val3'),('val4','val5','val6');

但使用 pojos 列表

类似于:

public list insertIgnoreMulti(List records) { // ignore if exists return dsl.batchStore(records).execute(); }

但我似乎找不到相关文档。

谢谢。

我试过 Lukas 的例子:

public Loader<ScopusRecord> insertIgnoreMulti(List<ScopusRecord> records) throws IOException {
                return dsl.
                    loadInto(Tables.SCOPUS).
                    onDuplicateKeyIgnore().
                    loadRecords(records).
                    fields(Tables.SCOPUS.fields()).
                    execute();
    }

但我在日志中遇到异常和以下内容:

> org.jooq.tools.LoggerListener - Executing query          : select 1 as
> `one` from dual where exists (select `db`.`Scopus`.`id_word`,
> `db`.`Scopus`.`word`, `db`.`Scopus`.`frequency`,
> `db`.`Scopus`.`type_word`, `db`.`Scopus`.`phonetic`,
> `db`.`Scopus`.`norma`, `db`.`Scopus`.`status_word`,
> `db`.`Scopus`.`wiki`, `db`.`Scopus`.`aspl`, `db`.`Scopus`.`med`,
> `db`.`Scopus`.`last_process_date` from `db`.`Scopus` where
> `db`.`Scopus`.`id_word` = ?) org.jooq.tools.LoggerListener - -> with
> bind values      : select 1 as `one` from dual where exists (select
> `db`.`Scopus`.`id_word`, `db`.`Scopus`.`word`,
> `db`.`Scopus`.`frequency`, `db`.`Scopus`.`type_word`,
> `db`.`Scopus`.`phonetic`, `db`.`Scopus`.`norma`,
> `db`.`Scopus`.`status_word`, `db`.`Scopus`.`wiki`,
> `db`.`Scopus`.`aspl`, `db`.`Scopus`.`med`,
> `db`.`Scopus`.`last_process_date` from `db`.`Scopus` where
> `db`.`Scopus`.`id_word` = null) org.jooq.tools.StopWatch - Query
> executed           : Total: 16.566ms org.jooq.tools.StopWatch -
> Finishing                : Total: 19.398ms, +2.832ms
> org.jooq.tools.LoggerListener - Fetched result           : +----+
> org.jooq.tools.LoggerListener -                          : | one|
> org.jooq.tools.LoggerListener -                          : +----+
> org.jooq.tools.LoggerListener - Executing query          : insert into
> `db`.`Scopus` (`id_word`, `word`, `frequency`, `type_word`,
> `phonetic`, `norma`, `status_word`, `wiki`, `aspl`, `med`,
> `last_process_date`) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
> org.jooq.tools.LoggerListener - -> with bind values      : insert into
> `db`.`Scopus` (`id_word`, `word`, `frequency`, `type_word`,
> `phonetic`, `norma`, `status_word`, `wiki`, `aspl`, `med`,
> `last_process_date`) values (null, 'INTERNAL', 0, 'ENG', 'ntrnAl',
> null, null, null, 1, null, null) o.s.b.f.xml.XmlBeanDefinitionReader -
> Loading XML bean definitions from class path resource
> [org/springframework/jdbc/support/sql-error-codes.xml]
> o.s.j.support.SQLErrorCodesFactory - SQLErrorCodes loaded: [DB2,
> Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase,
> Hana] org.jooq.tools.LoggerListener - Exception                
> org.springframework.dao.DuplicateKeyException: jOOQ; SQL [insert into
> `db`.`Scopus` (`id_word`, `word`, `frequency`, `type_word`,
> `phonetic`, `norma`, `status_word`, `wiki`, `aspl`, `med`,
> `last_process_date`) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)];
> Duplicate entry 'INTERNAL' for key 'IX_Scopus'; nested exception is
> com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:
> Duplicate entry 'INTERNAL' for key 'IX_Scopus'    at
> org.jooq_3.9.1.MYSQL.debug(Unknown Source)    at
> org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:239)
>   at
> org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73)
>   at
> com.op.u2i.exceptions.ExceptionTranslator.exception(ExceptionTranslator.java:39)
>   at
> org.jooq.impl.ExecuteListeners.exception(ExecuteListeners.java:245)
>   at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:364)  at
> org.jooq.impl.LoaderImpl.executeSQL(LoaderImpl.java:808)  at
> org.jooq.impl.LoaderImpl.executeRows(LoaderImpl.java:709)     at
> org.jooq.impl.LoaderImpl.execute(LoaderImpl.java:640)     at
> org.jooq.impl.LoaderImpl.execute(LoaderImpl.java:100)     at
> com.op.u2i.services.db.ScopusService.insertIgnoreMulti(ScopusService.java:46)
> Caused by:
> com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:
> Duplicate entry 'INTERNAL' for key 'IX_Scopus'    at
> sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
>   at
> sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
>   at
> sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
>   at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
>   at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)     at
> com.mysql.jdbc.Util.getInstance(Util.java:408)    at
> com.mysql.jdbc.SQLError.createSQLException(SQLError.java:935)     at
> com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3973)    at
> com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3909)    at
> com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2527)     at
> com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2680)  at
> com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2501)   at
> com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1858)
>   at
> com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1197)
>   at
> com.zaxxer.hikari.pool.ProxyPreparedStatement.execute(ProxyPreparedStatement.java:44)
>   at
> com.zaxxer.hikari.pool.HikariProxyPreparedStatement.execute(HikariProxyPreparedStatement.java)
>   at
> org.jooq.tools.jdbc.DefaultPreparedStatement.execute(DefaultPreparedStatement.java:194)
>   at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:431)  at
> org.jooq.impl.AbstractDMLQuery.execute(AbstractDMLQuery.java:335)     at
> org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:349)   ... 25
> common frames omitted DEBUG org.jooq.tools.StopWatch - Exception      
> : Total: 324.324ms DEBUG org.jooq.tools.StopWatch - Warning           
> : Total: 326.594ms, +2.27ms DEBUG org.jooq.tools.StopWatch - Finishing
> : Total: 327.434ms, +0.84ms

最佳答案

有几个选项:

静态SQL

如果您的 SQL 语句足够静态,您可以为此使用 DSL API:

dsl.insertInto(TABLE1)
   .columns(TABLE1.COL1, TABLE1.COL2, TABLE1.COL3)
   .set(dsl.newRecord(TABLE1).values("val1", "val2", "val3"))
   .newRecord()
   .set(dsl.newRecord(TABLE1).values("val4", "val5", "val6"))
   .newRecord()
   .onDuplicateKeyIgnore() // This translates to MySQL's INSERT IGNORE
   .execute();

如果您的 SQL 是动态的(可变长度的记录列表),您可以将中间 DSL API 类型分配给局部变量并迭代记录。但在那种情况下,你可能会过得更好......

动态 SQL 和加载器 API

... Loader API :

dsl.loadInto(TABLE1)
   .onDuplicateKeyIgnore() // This translates to MySQL's INSERT IGNORE
   .loadRecords(records)
   .fields(TABLE1.COL1, TABLE1.COL2, TABLE1.COL3)
   .execute();

此 API 还允许您根据要插入的数据量微调批量、批量和提交大小。

关于java - 使用 JOOQ 插入忽略多个 pojo,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43377188/

相关文章:

java - ant 更新后 DSpace 5 "disappears"

mysql - 是否可以通过 ON DUPLICATE KEY UPDATE 强制 Sequel 始终返回自动增量 id?

java - quartz 调度程序的每个表表示什么?

java - ManyToOne OneToMany 双向 : Retrieve data from reference table

Java GMail api - java.lang.VerifyError : Cannot inherit from final class

java - 如何迭代并获取动态传递的类的值

mysql - 为什么我的更新查询对我的表格内容没有影响?

java - spring-boot 在多模块应用程序上失败

java - 计算地理点之间的距离

php - MySQL if 存在语法