纯净、安全、绿色的下载网站

首页|软件分类|下载排行|最新软件|IT学院

当前位置:首页IT学院IT技术

SpringBoot JpaRepository删除数据 基于Spring Boot使用JpaRepository删除数据时的注意事项

石头成说   2021-06-10 我要评论
想了解基于Spring Boot使用JpaRepository删除数据时的注意事项的相关内容吗石头成说在本文为您仔细讲解SpringBoot JpaRepository删除数据的相关知识和一些Code实例欢迎阅读和指正我们先划重点:Spring,Boot,JpaRepository,删除数据下面大家一起来学习吧

问题:

在Spring Boot中使用JpaRepository的deleteById(ID id)方法删除数据时首先要使用existsById(ID id)方法判断数据是否存在如果存在再删除

否则删除一个id不存在的数据会抛出org.springframework.dao.EmptyResultDataAccessException异常:

2019-01-02 15:57:24.122 WARN  org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration$JpaWebConfiguration$JpaWebMvcConfiguration Line:234 - spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2019-01-02 15:57:24.673 ERROR org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].[dispatcherServlet] Line:175 - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.EmptyResultDataAccessException: No class com.qiqi.model.entity.UserBean entity with id 33 exists!] with root cause
org.springframework.dao.EmptyResultDataAccessException: No class com.qiqi.model.entity.UserBean entity with id 33 exists!
 at org.springframework.data.jpa.repository.support.SimpleJpaRepository.lambda$deleteById$0(SimpleJpaRepository.java:150)
 at org.springframework.data.jpa.repository.support.SimpleJpaRepository$$Lambda$798/1206249587.get(Unknown Source)
 at java.util.Optional.orElseThrow(Optional.java:290)
 at org.springframework.data.jpa.repository.support.SimpleJpaRepository.deleteById(SimpleJpaRepository.java:149)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:497)
 at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:359)
 at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:200)
 at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:644)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
 at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:608)
 at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.lambda$invoke$3(RepositoryFactorySupport.java:595)
 at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor$$Lambda$787/1363172555.get(Unknown Source)
 at org.springframework.data.repository.util.QueryExecutionConverters$$Lambda$786/1029051888.apply(Unknown Source)
 at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:595)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
 at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)

在使用其他方法时例如:deleteAllByName(name)不进行判断也可以删除不会抛出异常

springboot的jpa数据库操作的坑

前一段用springboot写了篇 springboot整合多数据源小博文从三个数据库里面抓取合适的数据存在另外一个数据库里面在客户生产环境运行了一段时间感觉似乎很良好

客户觉得意犹未尽又提了点需求顺便提了点bug,于是乎又改了改代码客户居然提出一个问题说有时候查不出数据来过一会又好了我在本地试了试发现在本地竟然也存在这个问题问题其实一直都有只是似乎不影响什么所以便没当一回事

经过反复测试原来是往数据库写数据的时候卡住了有点奇怪大概过程是先把表里面数据清除然后再写入数据不到1000条居然耗时差不多10秒什么springboot,什么jpa太不靠谱了吧?

看代码 Repository

package net.springboot.repository.sqlserver;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import net.springboot.entity.sqlserver.RealData;
public interface XXDataRepository extends JpaRepository<XXData, String>
{	
}

调用代码也是简单明了

db.deleteAll();
db.saveAll(list);   //组合list这里就不写了 

其实说白了没有自己的代码都是springboot + jpa 框架实现的框架难道有问题这个一般不会吧把SQL放出来看看

原来这个样子删除全表数据居然是一条一条数据删除批量保存居然是先查询一下然后再插入JPA难道不考虑效率的吗?

问题找到了怎么解决了?删除功能好办自己写SQL嘛简单方便翠花上川菜代码拿来

@Transactional
@Modifying
@Query(value = "TRUNCATE TABLE table",nativeQuery = true)
int TruncateTable();
@Transactional
@Modifying
@Query(value = "delete from table",nativeQuery = true)
int deleteTable();

效果是立竿见影删除效率上来了清空表里数据一秒不到不过后来又仔细看了一下jpa似乎还提供了另外一个删除全部数据的方法 deleteAllInBatch这个方法在删除前似乎没有查询懒得做测试了习惯了自己写SQL解决问题

但是批量插入这个不好办了总不可能自己写成一条一条插入啊那还不如不改了百度一下网上说改一下配置文件即可

spring.jpa.properties.hibernate.jdbc.batch_size=500
spring.jpa.properties.hibernate.jdbc.batch_versioned_data=true
spring.jpa.properties.hibernate.order_inserts=true
spring.jpa.properties.hibernate.order_updates=true

但是好像效果不行show sql 还是一样先查询后插入效率依然不行想了很多百度了很多为什么了为什么啊?JPA这玩意为什么会在插入前查询一下了查询又是怎么个查询方式了?这个应该与主键ID有关系所以改一下实体类id统一为uuid模式

    @Id
    @GenericGenerator(name = "id-generator", strategy = "uuid")
    @GeneratedValue(generator = "id-generator")
    @Column(name = "pid")
    public String pid;

效果明显问题立马解决但是有的系统主键ID是生成好的有自己的规则不可以随便uuid,比如我这个系统就是都是在各个系统里面已经生成好了而且还因为业务需要不能改

没办法只有另加一个字段做为@id 虽然没啥实际意义但是批量写入数据的问题得到彻底解决你好我好大家好

不过话说回来插入前查询一下这个功能是可以有在大多数的业务场景也是很有用的springboot的jpa就这样在系统中具体怎么用码农们各显神通

也算是趟过 springboot,jpa框架的两个坑

以上为个人经验希望能给大家一个参考也希望大家多多支持


相关文章

猜您喜欢

网友评论

Copyright 2020 www.fresh-weather.com 【世纪下载站】 版权所有 软件发布

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 点此查看联系方式