SpringBoot实现JPA的save操作
在一次参与公司的技术讨论会上,一位同事在演示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的方法来测试:
当传入不带自增主键时
@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操作相关推荐
- 【Java快速入门】--基于SpringBoot的JPA数据库ORM操作
依赖 <!-- jpa数据库操作 --><dependency><groupId>org.springframework.boot</groupId>& ...
- SpringBoot与JPA
SpringBoot与JPA集成: 简介 JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对 ...
- SpringBoot + Mybatis/JPA
这篇主要讲解SpringBoot结合JPA和Mybatis的使用 SpringBoot作为后端框架,必定要对数据库进行crud操作,JPA和Mybatis把这些操作进行了封装,方便了代码的编写. JP ...
- springboot之jpa支持
springboot之jpa支持 创建一个sprigboot项目 application.yml文件配置 server:port: 8080servlet:context-path: /spring: ...
- Jpa第一话 -- Springboot集成Jpa和Mybatis以及Jpa的最全使用
本文主要记录spring-boot-starter-data-jpa的详细使用. 在做一些小型无并发的项目时,说实话第一个想到的就是Jpa,一个Entity走天下. 1.Spring Jpa的使用 基 ...
- Springboot整合JPA
文章目录 JPA技术 常用注解 Springboot整合JPA 1.引入JPA依赖 2.配置 3.启动类 4.实体类 5.定义接口和数据库交互(dao) 6.JPA中使用原生态的SQL语句 7.Tes ...
- SpringBoot 中JPA集成PostgreSql(详细步骤)避坑!
SpringBoot 中JPA集成PostgreSql(详细步骤) 什么是JPA?(Java Persistence API) Spring Data JPA, part of the larger ...
- SpringBoot使用JPA多表关联动态查询指定字段
SpringBoot使用JPA多表关联动态查询指定字段 目标需求 Maven依赖 项目结构 代码 运行结果 源码下载 目标需求 在SpringBoot中用JPA实现多表关联动态查询,并且只查询指定字段 ...
- SpringBoot通过JPA连接Mysql集群
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 为什么要进行Mysql的主从复制 一.Mysql主从复制配置 1.配置主数据库 2.配置从数据库 3.在主数据库上进行用户授 ...
最新文章
- python积分管理系统_python实现每天自动签到领积分的示例代码
- idea中自定义修改jdk源码,加注释
- leetcode算法题--Triangle
- composer安装laravel
- thinkphp5模拟post请求_Thinkphp5.1模拟登录并提交form表单
- 熊猫分发_熊猫新手:第二部分
- MVC — 初步理解IIS工作流程
- PHP中的正则表达式函数preg_
- 浅谈 OneAPM 在 express 项目中的实践
- 壁纸控:小清新桌面壁纸
- Exp6 信息收集与漏洞扫描
- 【ACL'21】弱标签的垃圾数据,也能变废为宝!
- c语言编程ppt免费下载,概述C语言编程.ppt
- 数据挖掘概念与技术学习笔记(1)
- java代码c3p0连接池配置,c3p0连接池acquireincrement属性配置详解
- 学会-精湛-应用,一个数据分析师的养成手册
- 死亡、疾病、意外,如何面对?
- 技嘉主板前置面板没有声音的解决
- 方法(Method)
- 001java面试笔记——【java基础篇】从团800失败面试总结的java面试题