Spring JPA之save方法示例详解
作者:烟雨戏江南 发布时间:2023-09-06 15:50:35
标签:Spring,JPA,save,方法
一、save(单条添加)
源码
@Transactional
@Override
public <S extends T> S save(S entity) {
Assert.notNull(entity, "Entity must not be null.");
if (entityInformation.isNew(entity)) {
em.persist(entity);
return entity;
} else {
return em.merge(entity);
}
}
由代码可知,它是先去判断了entity是否为new:
如果是new,就执行save方法;
如果非new,则执行update方法。这就是jpa为啥只有save接口没有update接口的原因吧!
此时我们应该有个疑惑:怎么样才算new呢?继续往下看:
/**
* Must be {@link Transient} in order to ensure that no JPA provider complains because of a missing setter.
*
* @see org.springframework.data.domain.Persistable#isNew()
*/
@Transient // DATAJPA-622
@Override
public boolean isNew() {
return null == getId();
}
恍然大悟,原来他是去看 entity 的id(实体类的主键)是否存在:不存在就是new。(通俗易懂,很好理解)
service 层
添加 save 方法(save 是三方件自带接口不需要再dao层中添加)
@Transactional
public User save(User user) {
return userDao.save(user);
}
control层
/**
* 单条数据保存
* @param id 自增的,可以不填
* @param name
* @param age
* @return
*/
@GetMapping("/save")
public User save(Integer id,String name, Integer age){
User user = new User();
user.setId(id);
user.setName(name);
user.setAge(age);
return userService.save(user);
}
浏览器测试OKhttp://localhost:7777/save?id=1&name=lili&age=18
测试id存在的情况OKhttp://localhost:7777/save?id=1&name=毛毛&age=20
二、saveAll(批量添加)
源码
/*
* (non-Javadoc)
* @see org.springframework.data.jpa.repository.JpaRepository#save(java.lang.Iterable)
*/
@Transactional
@Override
public <S extends T> List<S> saveAll(Iterable<S> entities) {
Assert.notNull(entities, "Entities must not be null!");
List<S> result = new ArrayList<>();
for (S entity : entities) {
result.add(save(entity));
}
return result;
}
一目了然,saveAll其实就是传入entity的集合,然后遍历进行save操作
service
添加 saveAll 方法(saveAll 是三方件自带接口不需要再dao层中添加)
@Transactional
public <S extends User> List<S> saveAll(Iterable<S> entities) {
return userDao.saveAll(entities);
}
control层
/**
* 批量保存数据
* @param ids
* @param names
* @param ages
* @return
*/
@GetMapping("/saveAll")
public List<User> saveAll(int[] ids,String[] names,Integer[] ages){
List<User> list = new ArrayList<>();
for(int i=0; i<names.length; i++){
User user = new User();
user.setId(ids[i]);
user.setName(names[i]);
user.setAge(ages[i]);
list.add(user);
}
return userService.saveAll(list);
}
浏览器测试OKhttp://localhost:7777/saveAll?ids=2,3&names=丁丁,壮壮&ages=13,14
注: 如果在实体类中的id上添加注解@GeneratedValue(strategy = GenerationType.IDENTITY)
,可以给id增加自增属性,这样我们就无需再传入id了
来源:https://juejin.cn/post/7221037881184616507


猜你喜欢
- Java的List在删除元素时,一般会用list.remove(o)/remove(i)方法。在使用时,容易触碰陷阱,得到意想不到的结果。总
- 刚开始学习Service的时候以为它是一个线程的封装,也可以执行耗时操作。其实不然,Service是运行在主线程的。直接执行耗时操作是会阻塞
- 现在的模拟器的功能太强大,从蓝牙,传感器等配件到IMEI,Mac,以及手机硬件信息什么都可以模拟为了防止用户利用模拟器模仿真机进行刷单,刷流
- 一、内部类1.内部类的概念内部类是定义在类中的类。内部类把逻辑上相关的类放在一起。而有的内部类不会在其他地方用到,它没有类名,在定义的时候就
- 在android移动端的开发中,首页轮播图是一个特别常见的功能,所以今天就来将最近写的一个小demo记录一下。首先当然是新建一个项目代码如下
- java volatile关键字在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多
- Struct的理论看过好一些,可是工作上基本没有应用过,Class倒处处都有。难道Struct就没有什么使用价值吗?搜了一下如何在类和结构中
- 前言在真实的项目开发中,使用SpringBoot可以说非常普遍了,而在框架整合中,与数据库的交互无外乎使用jpa,mybatis,mybat
- webview要调起input-file拍照或者选取文件功能,可以在webview.setWebChromeClient方法中重写指定的方法
- ForkJoinTask就是ForkJoinPool里面的每一个任务。他主要有两个子类:RecursiveAction和RecursiveT
- 一、迭代key&value第一种方式:迭代entrySet1.方法一/** * entrySet集合for-each循环(
- 本文实例为大家分享了Android Studio实现简单计算器功能的具体代码,供大家参考,具体内容如下程序步骤:(1)在布局文件定义一些计算
- 前言smart-doc 是一款同时支持 java restful api 和 Apache Dubbo rpc 接口文档生成的工具,smar
- 官方 JSON.NET 地址 http://james.newtonking.com/pages/json-net.aspxXML TO J
- RocketMQ发送消息我们在使用RocketMQ发送消息时,一般都会使用DefaultMQProducer,类型的代码如下:Default
- 一、前言滚动条一般用于加载进度,我们在看视频的时候或者在浏览网页的时候经常能看到加载进度的页面。在程序开发中,默认的进度加载样式可能跟程序风
- 定义:使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理
- 引言平时使用ProtoStuff作为序列化工具,对于一些POJO对象序列化,但是在实际使用中,发现针对BigDecimal对象进行序列化时却
- Java 判断字符串是否为IP地址,供大家参考,具体内容如下1、代码主要就是这么几个条件非空长度符合 0.0.0.0 - 255.255.2
- File类概述File类能新建、删除、重命名文件和目录,但不能访问文件内容本身,如果需要访问文件内容本身,则需要使用后续的输入/输出流。要在