2010-12-07 482 views
18

我想知道給定的記錄是否存在於數據庫中。到目前爲止,我已通過編寫JPA查詢並通過getSingleResult()方法運行它來實現此目的。如果具有給定參數的記錄不存在,則會拋出NoResultException。當然,記錄不是必須存在的,所以有時候這是正常的行爲,這就是爲什麼我問自己,是否有必要拋出一個我必須通過catch塊來處理的異常?據我所知,異常處理的成本相當大,所以我對這個解決方案並不滿意,而且我甚至不需要這個對象,我只需要知道它在DB中的存在。如何使用JPA檢查記錄是否存在

有沒有更好的方法來檢查一個對象是否存在?例如。使用getResultList()並檢查它的大小可能?

+1

好問題,但你應該改變其標題爲「如何檢查是否存在記錄使用JPA」或類似的東西。 – 2010-12-07 12:17:42

+0

感謝您的評論,完成:) – 2010-12-15 14:05:09

+0

更新:存儲庫存在(id)方法。 repo.exist(id)返回true如果記錄存在或者其他錯誤 – 2017-10-12 16:50:01

回答

20

如果您只是想知道對象是否存在,請將SELECT COUNT發送到您的數據庫。這將返回0或1.

異常處理的成本並不是那麼大(除非在正常操作期間執行數百萬次),所以我不打擾。

但代碼並不真正反映你的意圖。由於getSingleResult()呼籲getResultList()在內部,它是像這樣清晰的:

public boolean objExists(...) { 
    return getResultList(...).size() == 1; 
} 

如果通過對象ID查詢,你必須啓用緩存,這將成爲高速緩存簡單的查找對象是否已經被加載。

+0

哦,你完全正確的選擇COUNT解決方案,我忽略了它出於某種原因。但答案的第二部分包含我真正需要的信息,並且非常感謝。 – 2010-12-07 08:46:23

+0

您是否同意如果您想獲得查詢的第一個結果,並且通常查詢不返回任何內容,最好是執行'query.setMaxResults(1)'然後'getResultList()'?這樣我們將避免處理異常。 (注意:我在一個叫做MANY次的工作中運行這個)。 – GuilhermeA 2010-12-23 14:50:49

5

如果您是通過主鍵進行搜索,也可以使用Entitymanger.find(entityClass, primaryKey),當實體不存在時返回null

10

嘗試避免將實體加載到會話(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; 
} 
1

在查詢只需使用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); 
} 

希望幫助別人:)

0

這裏是一個類型牛逼和工作的通用做法任意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; 
} 
相關問題