插入忽略多个pojo与JOOQ

时间:2017-04-12 18:37:43

标签: java mysql spring-boot jooq

我想用Jooq实现以下内容:

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

但使用pojos列表

类似的东西:

  

公开名单   insertIgnoreMulti(列表记录){       //如果存在则忽略返回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

1 个答案:

答案 0 :(得分:0)

有几种选择:

静态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还允许您根据要插入的数据量来微调批量,批量和提交大小。