插入时如何忽略重复行

我使用hibernate-jpa-2.1-api 。 我需要一些function。

我每分钟解析一个文件并将数据插入MSSQL DB。 我需要跳过重复的行。 例如,在12:00我已经在我的文件中有300行。 我解析每一个并插入300行。 一分钟后( 12:01 )我的文件包含500行。 我解析它,我想只插入200个新行而不是旧300行。

在程序的旧实现中,我使用SQL插入并且没有使用ORM。

这是我的旧SQL查询:

 insert /*+ ignore_row_on_dupkey_index(avaya_cm_cdr, i_avaya_cm_cdr_nodub) */ into avaya_cm_cdr(acmcdr_id, cdrdate, cdrtime, secdur, condcode, attdconsole, codeused, outcrtid, codedial, dialednum, intrkcode, incrtid, callingnum, vdn, bcc, ppm, acctcode, authcode) values(seq_acmcdr_id.nextval, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) 

这是我使用ORM的新插件:

 em = Persistence.createEntityManagerFactory("COLIBRI").createEntityManager(); public void insertAVAYAcmCDRs(List cdrList) { em.getTransaction().begin(); for (AvayaCmCdr aCdrList : cdrList) { em.persist(aCdrList); } em.getTransaction().commit(); } 

如何将模拟function与函数ignore_row_on_dupkey_index一起用于ORM?

ps在旧的实现中,我使用了Oracle DB。

数据库样式选项

Hibernate不提供为其insert into语句添加选项。 我不知道MS SQL是否有相同的选项。

但是如果你找到这样的选项,你可以拦截insert语句并自己添加:

 public class IgnoreRowOnDupInterceptor extends EmptyInterceptor { public String onPrepareStatement(String sql) { if (sql.startsWith("insert into avaya_cm_cdr") { return sql.replace("insert into", "insert /*+ ignore_row_on_dupkey_index(avaya_cm_cdr, i_avaya_cm_cdr_nodub) */ into"); } return sql; } } 

您需要在persistence.xml声明此拦截器:

  

JPA风格选项

您可以记住上次解析的最后一行(或从数据库中检索它)并跳过该行直到该行。 在这种情况下,您甚至可以节省一次又一次地解析每个现有项目的时间。

从我的角度来看,这是JPA方式,因为您通常仅将数据库用作存储并将业务逻辑保留在(Java)应用程序中。