【问题标题】:How ignore duplicate rows when insert插入时如何忽略重复行
【发布时间】:2016-03-03 21:07:40
【问题描述】:

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

我每分钟解析一个文件并将数据插入 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<AvayaCmCdr> cdrList) {
    em.getTransaction().begin();
    for (AvayaCmCdr aCdrList : cdrList) {
        em.persist(aCdrList);
    }
    em.getTransaction().commit();
}

如何通过 ORM 使用函数ignore_row_on_dupkey_index 的模拟?

附言在过去的认识中,我使用的是 Oracle DB。

【问题讨论】:

  • 你刚刚得到的(俄语)答案有什么问题here

标签: java mysql sql-server hibernate jpa


【解决方案1】:

数据库样式选项

Hibernate 不提供向其insert into 语句添加选项。而且我不知道 MS SQL 是否可以使用相同的选项。

但如果你找到这样的选项,你可以截取插入语句并自己添加:

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中声明这个拦截器:

<property name="hibernate.ejb.interceptor" value="...IgnoreRowOnDupInterceptor" />

JPA 样式选项

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

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

【讨论】:

    猜你喜欢
    • 2016-10-22
    • 1970-01-01
    • 2012-08-25
    • 1970-01-01
    • 1970-01-01
    • 2011-09-24
    • 2017-04-20
    • 1970-01-01
    相关资源
    最近更新 更多