使用多个 ID 时在 JPQL 中执行 CRUD 操作的正确方法是啥
Posted
技术标签:
【中文标题】使用多个 ID 时在 JPQL 中执行 CRUD 操作的正确方法是啥【英文标题】:What is correct way to do CRUD operation in JPQL when working with multiple IDs使用多个 ID 时在 JPQL 中执行 CRUD 操作的正确方法是什么 【发布时间】:2015-03-03 15:09:48 【问题描述】:我想知道执行涉及获取和删除多个实体对象的操作的首选/正确方法是什么?
这是一个例子:
这里是使用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"
)
【问题讨论】:
【参考方案1】:第一个操作是 JPQL“批量”操作的示例,虽然在执行的 SQL 语句数量方面效率更高,但您应该注意以下要点:
https://docs.oracle.com/html/E24396_01/ejb3_langref.html#ejb3_langref_bulk_ops
10.2.9。 JPQL 批量更新和删除
操作批量更新和删除操作适用于一个实体 单个实体类(连同它的子类,如果有的话)。
删除操作仅适用于指定类的实体,并且 它的子类。 它不会级联到相关实体。这 为更新操作指定的新值必须在类型上兼容 与分配给它的状态字段。 批量更新地图 直接到数据库更新操作,绕过乐观锁定 检查。便携式应用程序必须手动更新 版本列,如果需要,和/或手动验证 版本列。 持久化上下文不同步 批量更新或删除的结果。应谨慎使用时 执行批量更新或删除操作,因为 它们可能会导致 数据库和活动中的实体之间的不一致 持久化上下文。一般来说,批量更新和删除操作 只能在单独的事务中或在 事务的开始(在访问其实体之前 状态可能会受到此类操作的影响)。
因此,在决定采用一种或其他方法时,您需要考虑上述因素。
【讨论】:
【参考方案2】:在这种情况下,第一个选项肯定有其优势。最大的一个是它转换为单个 delete
SQL 查询,而在第二个选项中,您在将每个实体传递给 em.remove()
之前加载它。
【讨论】:
以上是关于使用多个 ID 时在 JPQL 中执行 CRUD 操作的正确方法是啥的主要内容,如果未能解决你的问题,请参考以下文章