您好,登錄后才能下訂單哦!
今天小編給大家分享一下Spring JPA學習之delete方法怎么使用的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
為什么要把這兩個方法放在一起呢?我們先看源碼再說
@Transactional @Override public void deleteById(ID id) { Assert.notNull(id, ID_MUST_NOT_BE_NULL); delete(findById(id).orElseThrow(() -> new EmptyResultDataAccessException( String.format("No %s entity with id %s exists!", entityInformation.getJavaType(), id), 1))); }
@Override @Transactional @SuppressWarnings("unchecked") public void delete(T entity) { Assert.notNull(entity, "Entity must not be null!"); if (entityInformation.isNew(entity)) { return; } Class<?> type = ProxyUtils.getUserClass(entity); T existing = (T) em.find(type, entityInformation.getId(entity)); // if the entity to be deleted doesn't exist, delete is a NOOP if (existing == null) { return; } em.remove(em.contains(entity) ? entity : em.merge(entity)); }
一目了然了吧!deleteById 先在方法體內通過 id 求出 entity 對象,然后調用了 delete 的方法。也就是說,這兩個方法同根同源,使用起來差距不大,結果呢?也是一樣的,就是單條刪除。實際使用中呢,也是使用 deleteById 的情況比較多,廢話少說,try it。
添加deleteById方法(deleteById 是 JPA 自帶接口不需要在dao層中添加)
@Transactional public void deleteById(Integer id){ userDao.deleteById(id); }
/** * 通過id進行刪除數據 * @param id */ @GetMapping("/deleteById") public void deleteById(Integer id){ userService.deleteById(id); }
執行請求 /deleteById?id=2
,控制臺打印如下:
Hibernate: select user0_.id as id1_0_0_, user0_.age as age2_0_0_, user0_.name as name3_0_0_ from user user0_ where user0_.id=? Hibernate: delete from user where id=?
結論
先通過 select 查詢實體對象是否存在,然后再通過 id 進行刪除。
@Override @Transactional public void deleteAllById(Iterable<? extends ID> ids) { Assert.notNull(ids, "Ids must not be null!"); for (ID id : ids) { deleteById(id); } }
結論
通過源碼可以看出,就是遍歷 ids 然后循環調用上面的 deleteById(Id id) 方法。
@Override @Transactional public void deleteAll(Iterable<? extends T> entities) { Assert.notNull(entities, "Entities must not be null!"); for (T entity : entities) { delete(entity); } }
結論
這個呢?也就是遍歷 entities 然后循環調用上面的 delete(T entity) 方法
還有一個不傳參數的deleteAll()方法來刪除所有數據(慎用)
@Override @Transactional public void deleteAll() { for (T element : findAll()) { delete(element); } }
就是通過findAll求出所有實體對象然后循環調用delete方法
綜上所述,我們發現以上所有的刪除事件都是調用了delete(T entity)方法,也就是差距不是很大,就是單條 和多條刪除的區別。
添加 deleteAllById 方法(deleteAllById 是三方件自帶接口不需要在dao層中添加)
@Transactional public void deleteAllById(Iterable ids){ userDao.deleteAllById(ids); }
/** * 通過id進行批量刪除 * @param ids */ @GetMapping("/deleteAllById") public void deleteAllById(Integer[] ids){ userService.deleteAllById(Arrays.asList(ids)); }
瀏覽器測試成功 /deleteAllById?id=3,4
刪除前:
刪除后:
控制臺打印如下:
Hibernate: select user0_.id as id1_0_0_, user0_.age as age2_0_0_, user0_.name as name3_0_0_ from user user0_ where user0_.id=?
Hibernate: select user0_.id as id1_0_0_, user0_.age as age2_0_0_, user0_.name as name3_0_0_ from user user0_ where user0_.id=?
Hibernate: delete from user where id=?
Hibernate: delete from user where id=?
由此可以看出,數據是一條一條的進行了刪除。
public static final String DELETE_ALL_QUERY_STRING = "delete from %s x"; @Override @Transactional public void deleteAllInBatch(Iterable<T> entities) { Assert.notNull(entities, "Entities must not be null!"); if (!entities.iterator().hasNext()) { return; } applyAndBind(getQueryString(DELETE_ALL_QUERY_STRING, entityInformation.getEntityName()), entities, em) .executeUpdate(); }
/** * Creates a where-clause referencing the given entities and appends it to the given query string. Binds the given * entities to the query. * * @param <T> type of the entities. * @param queryString must not be {@literal null}. * @param entities must not be {@literal null}. * @param entityManager must not be {@literal null}. * @return Guaranteed to be not {@literal null}. */ public static <T> Query applyAndBind(String queryString, Iterable<T> entities, EntityManager entityManager) { Assert.notNull(queryString, "Querystring must not be null!"); Assert.notNull(entities, "Iterable of entities must not be null!"); Assert.notNull(entityManager, "EntityManager must not be null!"); Iterator<T> iterator = entities.iterator(); if (!iterator.hasNext()) { return entityManager.createQuery(queryString); } String alias = detectAlias(queryString); StringBuilder builder = new StringBuilder(queryString); builder.append(" where"); int i = 0; while (iterator.hasNext()) { iterator.next(); builder.append(String.format(" %s = ?%d", alias, ++i)); if (iterator.hasNext()) { builder.append(" or"); } } Query query = entityManager.createQuery(builder.toString()); iterator = entities.iterator(); i = 0; while (iterator.hasNext()) { query.setParameter(++i, iterator.next()); } return query; }
通過上面的源碼,我們大體能猜測出deleteAllInBatch(Iterable<T> entities)的實現原理:delete from %s where x=? or x=?
實際測試一下:http://localhost:7777/deleteAllInBatch?ids=14,15,16&names=a,b,c&ages=0,0,0
控制臺打印如下:
Hibernate: delete from user where id=? or id=? or id=?
public static final String DELETE_ALL_QUERY_BY_ID_STRING = "delete from %s x where %s in :ids"; @Override @Transactional public void deleteAllByIdInBatch(Iterable<ID> ids) { Assert.notNull(ids, "Ids must not be null!"); if (!ids.iterator().hasNext()) { return; } if (entityInformation.hasCompositeId()) { List<T> entities = new ArrayList<>(); // generate entity (proxies) without accessing the database. ids.forEach(id -> entities.add(getReferenceById(id))); deleteAllInBatch(entities); } else { String queryString = String.format(DELETE_ALL_QUERY_BY_ID_STRING, entityInformation.getEntityName(), entityInformation.getIdAttribute().getName()); Query query = em.createQuery(queryString); /** * Some JPA providers require {@code ids} to be a {@link Collection} so we must convert if it's not already. */ if (Collection.class.isInstance(ids)) { query.setParameter("ids", ids); } else { Collection<ID> idsCollection = StreamSupport.stream(ids.spliterator(), false) .collect(Collectors.toCollection(ArrayList::new)); query.setParameter("ids", idsCollection); } query.executeUpdate(); } }
通過上面源碼我們大體可以猜出deleteAllByIdInBatch(Iterable ids)的實現原理:delete from %s where id in (?,?,?)
實際測試一下:http://localhost:7777/deleteAllByIdInBatch?ids=17,18,19
控制臺打印如下:
Hibernate: delete from user where id in (? , ? , ?)
這里同樣有個不帶參數的deleteAllInBatch()的方法,源碼如下:
@Override @Transactional public void deleteAllInBatch() { em.createQuery(getDeleteAllQueryString()).executeUpdate(); } public static final String DELETE_ALL_QUERY_STRING = "delete from %s x"; private String getDeleteAllQueryString() { return getQueryString(DELETE_ALL_QUERY_STRING, entityInformation.getEntityName()); }
通過源碼不難猜到實現原理吧,多的不說,直接給測試的控制臺數據:Hibernate: delete from user
以上就是“Spring JPA學習之delete方法怎么使用”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。