微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Spring JPA学习之delete方法怎么使用

今天小编给大家分享一下Spring JPA学习之delete方法怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

    一、deleteById 和 delete

    为什么要把这两个方法放在一起呢?我们先看源码再说

    deleteById(Id id)(通过id进行删除

    @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)(通过实体对象进行删除

    @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。

    实例

    service 层

    添加deleteById方法deleteByIdJPA 自带接口不需要在dao层中添加

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

    control层

    /**
     * 通过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 进行删除

    二、deleteallById 和 deleteall

    1、deleteallById(Iterable<? extends ID> ids)(通过id进行批量删除

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

    结论

    通过源码可以看出,就是遍历 ids 然后循环调用上面的 deleteById(Id id) 方法

    2、deleteall(Iterable<? extends T> entities)(通过实体对象进行批量删除

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

    结论

    这个呢?也就是遍历 entities 然后循环调用上面的 delete(T entity) 方法

    还有一个不传参数的deleteall()方法删除所有数据(慎用)

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

    就是通过findAll求出所有实体对象然后循环调用delete方法

    综上所述,我们发现以上所有的删除事件都是调用了delete(T entity)方法,也就是差距不是很大,就是单条 和多条删除的区别。

    实例

    service 层

    添加 deleteallById 方法deleteallById 是三方件自带接口不需要在dao层中添加

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

    control层

    /**
     * 通过id进行批量删除
     * @param ids
     */
    @GetMapping("/deleteallById")
    public void deleteallById(Integer[] ids){
    	userService.deleteallById(Arrays.asList(ids));
    }

    浏览器测试成功 /deleteallById?id=3,4删除前:

    Spring JPA学习之delete方法怎么使用

    删除后:

    Spring JPA学习之delete方法怎么使用

    控制台打印如下:

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

    由此可以看出,数据是一条一条的进行了删除

    三、deleteallInBatch 和 deleteallByIdInBatch

    1、deleteallInBatch(Iterable<T> entities)(通过实体对象进行批量删除

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

    2、deleteallByIdInBatch(Iterable<ID> ids)源码(通过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();
       }
    }

    通过上面源码我们大体可以猜出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方法怎么使用”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程之家行业资讯频道。

    版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

    相关推荐