我使用hibernate-jpa-2.1-api
。我需要一些功能。
我每分钟解析一个文件并将数据插入MSSQL DB。我需要跳过重复的行。例如,在12:00
,我的文件中有300行。我解析每一个并插入300行。一分钟后(12:01
)我的文件包含500行。我解析它,我想只插入200个新行,而不是旧的300行。
在程序的旧实现中,我使用了SQL insert并且没有使用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();
}
如何将模拟功能ignore_row_on_dupkey_index
用于ORM?
P.S。在旧的实现中,我使用了Oracle DB。
答案 0 :(得分:0)
数据库样式选项
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)应用程序中。