在一次参与公司的技术讨论会上,一位同事在演示SpringBoot的JPA的操作时,发现SpringBoot的JPA的save操作时,发现会先有select再insert,然后老板说,我们在网关已经处理过select了,我们调用save肯定是想直接保存的,所以这个问题记下来,下面去解决下这个问题。虽然只是实习生,但是还是想知道这个问题的,如果就自己试了下,想知道里面的原因。


StudentRepository:

package com.hyl.springboot.Repository;import com.hyl.springboot.Entity.Student;
import org.springframework.data.jpa.repository.JpaRepository;/*** @Author HYL* @Date 2019/10/31 下午7:56* @Version 1.0**//*** 参数一:当前需要映射的实体* 参数二:当前映射的实体中OID的类型*/
public interface StudentRepository extends JpaRepository<Student, Integer> {}

Student:

package com.hyl.springboot.Entity;import javax.persistence.*;/*** @Author HYL* @Date 2019/10/31 下午7:52* @Version 1.0**/@Entity
public class Student {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private int id;@Column(name = "name")private String name;@Column(name = "age")private int age;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}

SpringTest:

package com.hyl.springdatajpa.test;
package com.hyl.springboot;import com.hyl.springboot.Entity.Student;
import com.hyl.springboot.Repository.StudentRepository;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = SpringbootApplication.class)
public class SpringbootApplicationTests {@Autowiredpublic StudentRepository studentRepository;@Testpublic void testSave() {Student student = new Student();student.setAge(2);student.setName("242");studentRepository.save(student);}
}

我们通过改变我们我们testSaveStudent的方法来测试:

  1. 当传入不带自增主键时

    @Test
    public void testSave() {Student student = new Student();student.setAge(35);student.setName("上官云雀");studentRepository.save(student);}
    

2.当传入带自增主键并且数据库不存在时

@Testpublic void testSave() {Student student = new Student();student.setId(37);student.setAge(35);student.setName("上官云雀");studentRepository.save(student);}

3.当传入带自增主键并且数据库存在时(当前主键存在数据)

  @Testpublic void testSave() {Student student = new Student();student.setId(19);student.setAge(34);student.setName("上官云雀");studentRepository.save(student);}


总结:


源码分析:

@Transactional@Overridepublic <S extends T> S save(S entity) {//当当前实体为一个新的就把当前实体实例化并持久化if (entityInformation.isNew(entity)) {em.persist(entity);return entity;} else {//将给定实体的状态合并到当前的持久性上下文return em.merge(entity);}}

persist:

 /*** Make an instance managed and persistent.* @param entity  entity instance* @throws EntityExistsException if the entity already exists.* (If the entity already exists, the <code>EntityExistsException</code> may * be thrown when the persist operation is invoked, or the* <code>EntityExistsException</code> or another <code>PersistenceException</code> may be * thrown at flush or commit time.) * @throws IllegalArgumentException if the instance is not an*         entity* @throws TransactionRequiredException if there is no transaction when*         invoked on a container-managed entity manager of that is of type *         <code>PersistenceContextType.TRANSACTION</code>*/public void persist(Object entity);

当前实体为一个新的就把当前实体实例化并持久化

merge:

/*** Merge the state of the given entity into the* current persistence context.* @param entity  entity instance* @return the managed instance that the state was merged to* @throws IllegalArgumentException if instance is not an*         entity or is a removed entity* @throws TransactionRequiredException if there is no transaction when*         invoked on a container-managed entity manager of that is of type *         <code>PersistenceContextType.TRANSACTION</code>*/    public <T> T merge(T entity);

persist会把传进去的实体放到持久化上下文中,此时如果持久化上下文中有了这个实体,就会抛出javax.persistence.EntityExistsException,没有的话事务提交的时候把那个对象加进数据库中。

persist是保存,跟save方法一样,更接近持久化的含义;而merge是合并的意思,就是当保存的实体,根据主键id划分,如果已存在,那么就是更新操作,如果不存在,就是新增操作。


文章为ArvinHan原创,如果文章有错的地方欢迎指正,大家互相交流。

SpringBoot实现JPA的save操作相关推荐

  1. 【Java快速入门】--基于SpringBoot的JPA数据库ORM操作

    依赖 <!-- jpa数据库操作 --><dependency><groupId>org.springframework.boot</groupId>& ...

  2. SpringBoot与JPA

    SpringBoot与JPA集成: 简介 JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对 ...

  3. SpringBoot + Mybatis/JPA

    这篇主要讲解SpringBoot结合JPA和Mybatis的使用 SpringBoot作为后端框架,必定要对数据库进行crud操作,JPA和Mybatis把这些操作进行了封装,方便了代码的编写. JP ...

  4. springboot之jpa支持

    springboot之jpa支持 创建一个sprigboot项目 application.yml文件配置 server:port: 8080servlet:context-path: /spring: ...

  5. Jpa第一话 -- Springboot集成Jpa和Mybatis以及Jpa的最全使用

    本文主要记录spring-boot-starter-data-jpa的详细使用. 在做一些小型无并发的项目时,说实话第一个想到的就是Jpa,一个Entity走天下. 1.Spring Jpa的使用 基 ...

  6. Springboot整合JPA

    文章目录 JPA技术 常用注解 Springboot整合JPA 1.引入JPA依赖 2.配置 3.启动类 4.实体类 5.定义接口和数据库交互(dao) 6.JPA中使用原生态的SQL语句 7.Tes ...

  7. SpringBoot 中JPA集成PostgreSql(详细步骤)避坑!

    SpringBoot 中JPA集成PostgreSql(详细步骤) 什么是JPA?(Java Persistence API) Spring Data JPA, part of the larger ...

  8. SpringBoot使用JPA多表关联动态查询指定字段

    SpringBoot使用JPA多表关联动态查询指定字段 目标需求 Maven依赖 项目结构 代码 运行结果 源码下载 目标需求 在SpringBoot中用JPA实现多表关联动态查询,并且只查询指定字段 ...

  9. SpringBoot通过JPA连接Mysql集群

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 为什么要进行Mysql的主从复制 一.Mysql主从复制配置 1.配置主数据库 2.配置从数据库 3.在主数据库上进行用户授 ...

最新文章

  1. python积分管理系统_python实现每天自动签到领积分的示例代码
  2. idea中自定义修改jdk源码,加注释
  3. leetcode算法题--Triangle
  4. composer安装laravel
  5. thinkphp5模拟post请求_Thinkphp5.1模拟登录并提交form表单
  6. 熊猫分发_熊猫新手:第二部分
  7. MVC — 初步理解IIS工作流程
  8. PHP中的正则表达式函数preg_
  9. 浅谈 OneAPM 在 express 项目中的实践
  10. 壁纸控:小清新桌面壁纸
  11. Exp6 信息收集与漏洞扫描
  12. 【ACL'21】弱标签的垃圾数据,也能变废为宝!
  13. c语言编程ppt免费下载,概述C语言编程.ppt
  14. 数据挖掘概念与技术学习笔记(1)
  15. java代码c3p0连接池配置,c3p0连接池acquireincrement属性配置详解
  16. 学会-精湛-应用,一个数据分析师的养成手册
  17. 死亡、疾病、意外,如何面对?
  18. 技嘉主板前置面板没有声音的解决
  19. 方法(Method)
  20. 001java面试笔记——【java基础篇】从团800失败面试总结的java面试题

热门文章

  1. Protues的一些心得(画子电路)
  2. 打开金蝶云专业版显示服务器不是有效的,金蝶云专业版服务器不是有效的
  3. iCloud怎么协同作业文? iCloud协同编辑文档的技巧
  4. 设计模式——生成器(建造者)模式
  5. 从0到1打造我的高效团队
  6. C++实践小经验——#include 何时放在头文件里,何时放在cpp文件里?
  7. 智慧交通|交通监控系统的数据可视化如何实现?
  8. 黑龙江哪家学校学计算机好,黑龙江省内哪个专科学校计算机专业比较好?
  9. 华为云发布,怎么样?
  10. 免费易我录屏软件|一键帮您记录精彩瞬间!