如何使用JPA检查记录是否存在
我想知道给定的记录是否存在于数据库中。到目前为止,我已通过编写JPA查询并通过getSingleResult()
方法运行它来实现此目的。如果具有给定参数的记录不存在,则会抛出NoResultException
。当然,记录不是必须存在的,所以有时候这是正常的行为,这就是为什么我问自己,是否有必要抛出一个我必须通过catch块来处理的异常?据我所知,异常处理的成本相当大,所以我对这个解决方案并不满意,而且我甚至不需要这个对象,我只需要知道它在DB中的存在。如何使用JPA检查记录是否存在
有没有更好的方法来检查一个对象是否存在?例如。使用getResultList()
并检查它的大小可能?
如果您只是想知道对象是否存在,请将SELECT COUNT
发送到您的数据库。这将返回0或1.
异常处理的成本并不是那么大(除非在正常操作期间执行数百万次),所以我不打扰。
但代码并不真正反映你的意图。由于getSingleResult()
呼吁getResultList()
在内部,它是像这样清晰的:
public boolean objExists(...) {
return getResultList(...).size() == 1;
}
如果通过对象ID查询,你必须启用缓存,这将成为高速缓存简单的查找对象是否已经被加载。
哦,你完全正确的选择COUNT解决方案,我忽略了它出于某种原因。但答案的第二部分包含我真正需要的信息,并且非常感谢。 – 2010-12-07 08:46:23
您是否同意如果您想获得查询的第一个结果,并且通常查询不返回任何内容,最好是执行'query.setMaxResults(1)'然后'getResultList()'?这样我们将避免处理异常。 (注意:我在一个叫做MANY次的工作中运行这个)。 – GuilhermeA 2010-12-23 14:50:49
如果您是通过主键进行搜索,也可以使用Entitymanger.find(entityClass, primaryKey)
,当实体不存在时返回null
。
尝试避免将实体加载到会话(getSingleResult()
)中以检查其是否存在。点数在这里更好。随着条件查询API它会是这个样子:
public <E extends AbstractEntity> boolean exists(final Class<E> entityClass, final int id) {
final EntityManager em = getEntityManager();
final CriteriaBuilder cb = em.getCriteriaBuilder();
final CriteriaQuery<Long> cq = cb.createQuery(Long.class);
final Root<E> from = cq.from(entityClass);
cq.select(cb.count(from));
cq.where(cb.equal(from.get(AbstractEntity_.id), id));
final TypedQuery<Long> tq = em.createQuery(cq);
return tq.getSingleResult() > 0;
}
在查询只需使用count(e)
,所以没有NoResultException
会被抛出,你会避免加载实体对象
所以Java代码可以如下:
public boolean isRecordExist() {
String query = "select count(e) from YOUR_ENTITY e where ....";
// you will always get a single result
Long count = (Long) entityManager.createQuery(query).getSingleResult();
return ((count.equals(0L)) ? false : true);
}
希望帮助别人:)
这里是一个类型牛逼和工作的通用做法任意ID值
public boolean exists(Object key) {
EntityManager entityManager = getEntityManager();
Metamodel metamodel = entityManager.getMetamodel();
EntityType<T> entity = metamodel.entity(entityClass);
SingularAttribute<T, ? extends Object> declaredId = entity.getDeclaredId(key.getClass());
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
javax.persistence.criteria.CriteriaQuery<T> cq = cb.createQuery(entityClass);
Root<T> from = cq.from(entityClass);
Predicate condition = cb.equal(from.get(declaredId), key);
cq.where(condition);
TypedQuery<T> q = entityManager.createQuery(cq);
return q.getResultList().size() > 0;
}
好问题,但你应该改变其标题为“如何检查是否存在记录使用JPA”或类似的东西。 – 2010-12-07 12:17:42
感谢您的评论,完成:) – 2010-12-15 14:05:09
更新:存储库存在(id)方法。 repo.exist(id)返回true如果记录存在或者其他错误 – 2017-10-12 16:50:01