我想知道某个记录是否存在于数据库中。到目前为止,我已经通过编写JPA查询并通过getSingleResult()
方法运行它来实现此目的。如果具有给定参数的记录不存在,则会抛出NoResultException
。当然,记录不是必须存在的,所以这有时是正常行为,这就是为什么我问自己,是否需要抛出一个我必须通过catch块来处理的异常?据我所知,异常处理的成本相当大,所以我对这个解决方案不是很满意,而且,我甚至不需要这个对象,我只需要知道它在DB中是否存在。
有没有更好的方法来检查对象是否存在?例如。使用getResultList()
并检查它的大小可能?
答案 0 :(得分:26)
如果您只想知道对象是否存在,请将SELECT COUNT
发送到您的数据库。那将返回0或1。
异常处理的成本并不是那么大(除非你在正常操作期间做了数百万次),所以我不会打扰。
但是代码并没有真正反映你的意图。由于getSingleResult()
在内部调用getResultList()
,因此更清晰:
public boolean objExists(...) {
return getResultList(...).size() == 1;
}
如果按对象ID查询并且启用了缓存,那么如果已经加载了对象,那么它将成为缓存中的简单查找。
答案 1 :(得分:18)
尽量避免将实体加载到会话(getSingleResult()
)中以检查它是否存在。这里的数量更好。使用Criteria Query 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;
}
答案 2 :(得分:7)
只需在查询中使用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 );
}
希望能帮助某人:)
答案 3 :(得分:4)
如果您按主键搜索,也可以使用Entitymanger.find(entityClass, primaryKey)
,当实体不存在时,null
会返回{{1}}。
答案 4 :(得分:1)
这是使用类型 T 和任意 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;
}
答案 5 :(得分:0)
尝试
public boolean exists(Object id){
return getEntityManager().find(entityClass, id)!=null;
}