使用多个 ID 时,在 JPQL 中执行 CRUD 操作的正确方法是什么

What is correct way to do CRUD operation in JPQL when working with multiple IDs

我想知道 pereferred/correct 执行涉及获取和删除多个实体对象的操作的方法是什么?

这是一个例子:

下面是使用 IN 运算符的方法:

@Override
public void delete(Iterable<Long> ids) {
    startTransaction();

    Query query = getEntityManager().createNamedQuery(Entity.DELETE_ALL_BY_IDS_NQ);
    query.setParameter(Entity.DELETE_ALL_BY_IDS_PARAMS[0], ids);
    query.executeUpdate();

    endTransaction();
    closeTransaction();
}

命名查询如下所示:

@NamedQuery(
        name = "Entity.deleteAllByIds",
        query = "DELETE from Entity e WHERE e.id IN :ids"
)

这是通过 EntityManager#remove

完成的方法
public void delete(Iterable<Long> ids) {
    int count = 0;

    startTransaction();

    for (Long id : ids) {
        count++;

        Query query = getEntityManager().createNamedQuery(ImeiTacEntity.IMEITAC_READ_BY_ID_NQ);
        query.setParameter(ImeiTacEntity.IMEITAC_READ_BY_ID_PARAMS[0], id);

        ImeiTacEntity entity = (ImeiTacEntity) query.getSingleResult();
        getEntityManager().remove(entity);

        if ((count % BATCH_THRESHOLD) == 0) {
            endTransaction();
            clearTransaction();
            startTransaction();
        }
    }

    endTransaction();
    closeTransaction();
}

读取查询是这样的:

@NamedQuery(
    name = "Entity.readById", 
    query = "SELECT e from Entity e WHERE e.id = :id"
)

在这种情况下,第一种选择肯定有其优势。最大的一个是它转换为单个 delete SQL 查询,而在第二个选项中,您在将每个实体传递给 em.remove().

之前加载每个实体

第一个操作是 JPQL 'bulk' 操作的示例,虽然在执行的 SQL 语句数量方面效率更高,但您应该注意以下要点:

https://docs.oracle.com/html/E24396_01/ejb3_langref.html#ejb3_langref_bulk_ops

10.2.9. JPQL Bulk Update and Delete

Operations Bulk update and delete operations apply to entities of a single entity class (together with its subclasses, if any).

A delete operation only applies to entities of the specified class and its subclasses. It does not cascade to related entities. The new_value specified for an update operation must be compatible in type with the state-field to which it is assigned. Bulk update maps directly to a database update operation, bypassing optimistic locking checks. Portable applications must manually update the value of the version column, if desired, and/or manually validate the value of the version column. The persistence context is not synchronized with the result of the bulk update or delete. Caution should be used when executing bulk update or delete operations because they may result in inconsistencies between the database and the entities in the active persistence context. In general, bulk update and delete operations should only be performed within a separate transaction or at the beginning of a transaction (before entities have been accessed whose state might be affected by such operations).

因此,在决定采用一种或另一种方法时,您需要考虑上述因素。