插入时如何忽略重复行
我使用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)应用程序中。