最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring JPA學(xué)習(xí)之delete方法示例詳解

 更新時(shí)間:2023年04月26日 15:27:23   作者:煙雨戲江南  
這篇文章主要為大家介紹了Spring JPA學(xué)習(xí)delete方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

一、deleteById 和 delete

為什么要把這兩個(gè)方法放在一起呢?我們先看源碼再說(shuō)

deleteById(Id id)(通過(guò)id進(jìn)行刪除)

@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)));
}

delete(T entity)(通過(guò)實(shí)體對(duì)象進(jìn)行刪除)

@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 先在方法體內(nèi)通過(guò) id 求出 entity 對(duì)象,然后調(diào)用了 delete 的方法。也就是說(shuō),這兩個(gè)方法同根同源,使用起來(lái)差距不大,結(jié)果呢?也是一樣的,就是單條刪除。實(shí)際使用中呢,也是使用 deleteById 的情況比較多,廢話少說(shuō),try it。

實(shí)例

service 層

添加deleteById方法(deleteByIdJPA 自帶接口不需要在dao層中添加)

@Transactional
public void deleteById(Integer id){
    userDao.deleteById(id);
}

control層

/**
 * 通過(guò)id進(jìn)行刪除數(shù)據(jù)
 * @param id
 */
@GetMapping("/deleteById")
public void deleteById(Integer id){
	userService.deleteById(id);
}

執(zhí)行請(qǐng)求 /deleteById?id=2,控制臺(tái)打印如下:

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=?

結(jié)論

先通過(guò) select 查詢實(shí)體對(duì)象是否存在,然后再通過(guò) id 進(jìn)行刪除。

二、deleteAllById 和 deleteAll

1、deleteAllById(Iterable<? extends ID> ids)(通過(guò)id進(jìn)行批量刪除)

@Override
@Transactional
public void deleteAllById(Iterable&lt;? extends ID&gt; ids) {
   Assert.notNull(ids, "Ids must not be null!");
   for (ID id : ids) {
      deleteById(id);
   }
}

結(jié)論

通過(guò)源碼可以看出,就是遍歷 ids 然后循環(huán)調(diào)用上面的 deleteById(Id id) 方法。

2、deleteAll(Iterable<? extends T> entities)(通過(guò)實(shí)體對(duì)象進(jìn)行批量刪除)

@Override
@Transactional
public void deleteAll(Iterable&lt;? extends T&gt; entities) {
   Assert.notNull(entities, "Entities must not be null!");
   for (T entity : entities) {
      delete(entity);
   }
}

結(jié)論

這個(gè)呢?也就是遍歷 entities 然后循環(huán)調(diào)用上面的 delete(T entity) 方法

還有一個(gè)不傳參數(shù)的deleteAll()方法來(lái)刪除所有數(shù)據(jù)(慎用)

@Override
@Transactional
public void deleteAll() {
   for (T element : findAll()) {
      delete(element);
   }
}

就是通過(guò)findAll求出所有實(shí)體對(duì)象然后循環(huán)調(diào)用delete方法

綜上所述,我們發(fā)現(xiàn)以上所有的刪除事件都是調(diào)用了delete(T entity)方法,也就是差距不是很大,就是單條 和多條刪除的區(qū)別。

實(shí)例

service 層

添加 deleteAllById 方法(deleteAllById 是三方件自帶接口不需要在dao層中添加)

@Transactional
public void deleteAllById(Iterable ids){
	userDao.deleteAllById(ids);
}

control層

/**
 * 通過(guò)id進(jìn)行批量刪除
 * @param ids
 */
@GetMapping("/deleteAllById")
public void deleteAllById(Integer[] ids){
	userService.deleteAllById(Arrays.asList(ids));
}

瀏覽器測(cè)試成功 /deleteAllById?id=3,4刪除前:

image.png

刪除后:

image.png

控制臺(tái)打印如下:

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=?

由此可以看出,數(shù)據(jù)是一條一條的進(jìn)行了刪除。

三、deleteAllInBatch 和 deleteAllByIdInBatch

1、deleteAllInBatch(Iterable<T> entities)(通過(guò)實(shí)體對(duì)象進(jìn)行批量刪除)

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;
}

通過(guò)上面的源碼,我們大體能猜測(cè)出deleteAllInBatch(Iterable<T> entities)的實(shí)現(xiàn)原理:
delete from %s where x=? or x=?實(shí)際測(cè)試一下:http://localhost:7777/deleteAllInBatch?ids=14,15,16&names=a,b,c&ages=0,0,0控制臺(tái)打印如下:

Hibernate: delete from user where id=? or id=? or id=?

2、deleteAllByIdInBatch(Iterable<ID> ids)源碼(通過(guò)ids批量刪除)

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();
   }
}

通過(guò)上面源碼我們大體可以猜出deleteAllByIdInBatch(Iterable ids)的實(shí)現(xiàn)原理:
delete from %s where id in (?,?,?)實(shí)際測(cè)試一下:http://localhost:7777/deleteAllByIdInBatch?ids=17,18,19 控制臺(tái)打印如下:

Hibernate: delete from user where id in (? , ? , ?)

這里同樣有個(gè)不帶參數(shù)的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());
}

通過(guò)源碼不難猜到實(shí)現(xiàn)原理吧,多的不說(shuō),直接給測(cè)試的控制臺(tái)數(shù)據(jù):
Hibernate: delete from user

結(jié)論:

從上面兩種刪除接口來(lái)看,第二種實(shí)現(xiàn)比起第一種更加的快捷;

第一種就是一條一條的進(jìn)行刪除操作,如果有萬(wàn)級(jí)的數(shù)據(jù),執(zhí)行起來(lái)肯定非常耗時(shí),所以如果數(shù)據(jù)量比較大的話,還是建議大家使用第二種。

以上就是Spring JPA學(xué)習(xí)之delete方法示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Spring JPA delete方法的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Spring Boot日志的打印與持久化詳細(xì)解析

    Spring Boot日志的打印與持久化詳細(xì)解析

    Spring Boot默認(rèn)使用SLF4J+Logback 記錄日志,并提供了默認(rèn)配置,即使我們不進(jìn)行任何額外配,也可以使用SLF4J+Logback進(jìn)行日志輸出
    2022-07-07
  • Java多線程中的死鎖詳解

    Java多線程中的死鎖詳解

    這篇文章主要介紹了Java多線程中的死鎖詳解,死鎖是指兩個(gè)或多個(gè)線程在執(zhí)行過(guò)程中,因爭(zhēng)奪資源而造成的一種互相等待的現(xiàn)象,如果不提前預(yù)防或外界干擾,這些線程將無(wú)法執(zhí)行下去,需要的朋友可以參考下
    2023-08-08
  • java實(shí)現(xiàn)AES可逆加密算法

    java實(shí)現(xiàn)AES可逆加密算法

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)AES可逆加密算法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-03-03
  • logback 自定義Pattern模板教程

    logback 自定義Pattern模板教程

    這篇文章主要介紹了logback 自定義Pattern模板教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • springboot整合netty過(guò)程詳解

    springboot整合netty過(guò)程詳解

    這篇文章主要介紹了springboot整合netty過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • Spring?boot?運(yùn)用策略模式實(shí)現(xiàn)避免多次使用if

    Spring?boot?運(yùn)用策略模式實(shí)現(xiàn)避免多次使用if

    這篇文章主要介紹了Spring?boot?運(yùn)用策略模式實(shí)現(xiàn)避免多次使用if,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-09-09
  • SpringBoot環(huán)境搭建及第一個(gè)程序運(yùn)行(小白教程)

    SpringBoot環(huán)境搭建及第一個(gè)程序運(yùn)行(小白教程)

    這篇文章主要介紹了SpringBoot環(huán)境搭建及第一個(gè)程序運(yùn)行,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • mybatis學(xué)習(xí)之路mysql批量新增數(shù)據(jù)的方法

    mybatis學(xué)習(xí)之路mysql批量新增數(shù)據(jù)的方法

    這篇文章主要介紹了mybatis學(xué)習(xí)之路mysql批量新增數(shù)據(jù)的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • Java中l(wèi)ogback?自動(dòng)刷新不生效的問(wèn)題解決

    Java中l(wèi)ogback?自動(dòng)刷新不生效的問(wèn)題解決

    本文主要介紹了Java中l(wèi)ogback?自動(dòng)刷新不生效的問(wèn)題解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • 詳解JAVA中使用FTPClient工具類(lèi)上傳下載

    詳解JAVA中使用FTPClient工具類(lèi)上傳下載

    這篇文章主要介紹了JAVA中使用FTPClient工具類(lèi)上傳下載的相關(guān)資料,java 使用FTP服務(wù)器上傳文件、下載文件,需要的朋友可以參考下
    2017-08-08

最新評(píng)論

武夷山市| 泗洪县| 石屏县| 沾益县| 平罗县| 南漳县| 洛浦县| 沙河市| 东明县| 黔东| 平阴县| 辽宁省| 积石山| 德安县| 安化县| 汕尾市| 阿荣旗| 抚顺市| 紫金县| 德钦县| 南华县| 绥化市| 沭阳县| 新营市| 民和| 汉阴县| 屯留县| 五指山市| 江口县| 屯昌县| 惠安县| 昌图县| 巴楚县| 衡山县| 康马县| 建宁县| 阆中市| 青田县| 商城县| 扬州市| 施甸县|