Spring JPA之save方法示例详解

目录
  • 一、save(单条添加)
    • 源码
    • service 层
    • control层
  • 二、saveAll(批量添加)
    • 源码
    • service
    • control层

一、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了

以上就是Spring JPA之save方法示例详解的详细内容,更多关于Spring JPA save方法详解的资料请关注我们其它相关文章!

(0)

相关推荐

  • Spring JPA find分页示例详解

    目录 前言 源码 一.单纯分页查询 查询结果 结论 二.排序分页查询 查询结果 三.方法整理 总结: 前言 在现实项目中,数据量一般都不小,如果一次性全部请求出来,肯定是影响性能,而且大量数据展示到页面上观感也不好.这时我们就需要用到分页,给定一个 pageSize,每次请求的数量就是 pageSize 的大小,这样既可以节约时间,又可以美化页面.Spring JPA 就为我们提供这样一个方法,准确来说是提供了一个对象用来约束数据按照分页的形式进行请求. 源码 findAll(Pageable

  • Spring JPA之find拓展方法示例详解

    目录 前言 一.单条件查询 1.精确查询(确定值,例如:=.is) 2.范围查询(一定范围,例如<.<=.>.>=.in.between) a)运算符 b)between c)in 3.模糊查询 a)findByNameLike b)findByNameStartingWith 二.多条件查询 三.关键字 最后总结: 前言 前两篇我们详细了解了 findById 和 findAll 以及 findAll 的分页查询,如果说JPA只有上面的两种查询功能,那就太low了,今天让我们再深

  • Spring JPA联表查询之注解属性详解

    目录 前言 一.targetEntity 二.cascade 1.不定义 2.CascadeType.PERSIST 3.CascadeType.REMOVE 4.CascadeType.REFRESH 5.CascadeType.MERGE 6.CascadeType.ALL 三.fetch FetchType.LAZY FetchType.EAGER 四.mappedBy 五.orphanRemoval 前言 对于联表查询的四个注解 @OneToOne.@OneToMany.@ManyToO

  • Spring JPA find单表查询方法示例详解

    目录 一.findById(ID id) 二.findAll() 三.findAllById(Iterable<ID> ids) 四.findAll(Sort sort) 单调排序 sort.by 源码 control层 五.findAll(Sort sort) 多参数排序 Sort by 源码 control 层 总结 一.findById(ID id) 通过id进行单条查询,先看看 findById(ID id) 的源码 @Override public Optional<T>

  • Spring JPA学习之delete方法示例详解

    目录 一.deleteById 和 delete deleteById(Id id)(通过id进行删除) delete(T entity)(通过实体对象进行删除) 实例 service 层 control层 二.deleteAllById 和 deleteAll 1.deleteAllById(Iterable<? extends ID> ids)(通过id进行批量删除) 2.deleteAll(Iterable<? extends T> entities)(通过实体对象进行批量删

  • Spring JPA联表查询之OneToOne源码详解

    目录 前言 源码 注解属性 单向联表 user 实体类 car 实体类 查询结果 双向联表 user 实体 car 实体 查询结果 延迟加载(懒加载) user 实体 查询结果: 查询完会发现,控制台又打印了一个 JPQL: 最后结论 前言 前面几篇我们学习的都是单表查询,就是对一张表中的数据进行查询.而实际项目中,基本都会有多张表联合查询的情况,今天我们就来了解下JPA的联表查询是如做的. 源码 @OneToOne 注解实现一对一关系映射.比如用户跟车辆的关系(这里假设一个人只能有一辆车),一

  • Spring JPA之save方法示例详解

    目录 一.save(单条添加) 源码 service 层 control层 二.saveAll(批量添加) 源码 service control层 一.save(单条添加) 源码 @Transactional @Override public <S extends T> S save(S entity) { Assert.notNull(entity, "Entity must not be null."); if (entityInformation.isNew(enti

  • Spring Data JPA注解Entity使用示例详解

    目录 1.JPA协议中关于Entity的相关规定 需要注意的是: 2.常用注解 2.1 JPA支持的注解 2.2 常用注解 3.联合主键 3.1 @IdClass 3.2 @Embeddable与@EmbeddedId注解使用 3.3 两者的区别是什么? 1.JPA协议中关于Entity的相关规定 (1)实体是直接进行数据库持久化操作的领域对象(即一个简单的POJO),必须通过@Entity注解进行标示. (2)实体必须有一个 public 或者 projected的无参数构造方法. (3)持久

  • 编译安装redisd的方法示例详解

    安装方法: yum安装 查看yum仓库redis版本 [root@centos ~]# yum list redis Loaded plugins: fastestmirror, langpacks Loading mirror speeds from cached hostfile Available Packages redis.x86_64 3.2.12-2.el7 myepel yum安装 [root@centos ~]# yum install redis -y 启动服务并设为开机启动

  • Spring AOP事务管理的示例详解

    目录 转账案例-环境搭建 步骤1:准备数据库表 步骤2:创建项目导入jar包 步骤3:根据表创建模型类 步骤4:创建Dao接口 步骤5:创建Service接口和实现类 步骤6:添加jdbc.properties文件 步骤7:创建JdbcConfig配置类 步骤8:创建MybatisConfig配置类 步骤9:创建SpringConfig配置类 步骤10:编写测试类 事务管理 转账案例-环境搭建 步骤1:准备数据库表 之前我们在整合Mybatis的时候已经创建了这个表,可以直接使用 create

  • Go语言中的字符串处理方法示例详解

    1 概述 字符串,string,一串固定长度的字符连接起来的字符集合.Go语言的字符串是使用UTF-8编码的.UTF-8是Unicode的实现方式之一. Go语言原生支持字符串.使用双引号("")或反引号(``)定义. 双引号:"", 用于单行字符串. 反引号:``,用于定义多行字符串,内部会原样解析. 示例: // 单行 "心有猛虎,细嗅蔷薇" // 多行 ` 大风歌 大风起兮云飞扬. 威加海内兮归故乡. 安得猛士兮守四方! ` 字符串支持转义

  • VSCode各语言运行环境配置方法示例详解

    系统环境变量的配置 如:将F:\mingw64\bin添加到系统环境变量Path中 VSCode软件语言json配置C语言 创建个.vscode文件夹,文件夹内创建以下两个文件 launch.json 文件配置 { "version": "0.2.0", "configurations": [ { "name": "(gdb) Launch", "type": "cppdbg&

  • 浅谈使用Java Web获取客户端真实IP的方法示例详解

    Java-Web获取客户端真实IP: 发生的场景:服务器端接收客户端请求的时候,一般需要进行签名验证,客户端IP限定等情况,在进行客户端IP限定的时候,需要首先获取该真实的IP. 一般分为两种情况: 方式一.客户端未经过代理,直接访问服务器端(nginx,squid,haproxy): 方式二.客户端通过多级代理,最终到达服务器端(nginx,squid,haproxy): 客户端请求信息都包含在HttpServletRequest中,可以通过方法getRemoteAddr()获得该客户端IP.

  • PHP基于phpqrcode类生成二维码的方法示例详解

    HP QR Code是一个PHP二维码生成类库,利用它可以轻松生成二维码,官网提供了下载和多个演示demo,查看地址: http://phpqrcode.sourceforge.net/ 下载官网提供的类库后,只需要使用phpqrcode.php就可以生成二维码了,当然您的PHP环境必须开启支持GD2. phpqrcode.php提供了一个关键的png()方法,其中 参数$text表示生成二位的的信息文本: 参数$outfile表示是否输出二维码图片 文件,默认否: 参数$level表示容错率,

  • Python面向对象编程repr方法示例详解

    目录 为什么要讲 __repr__ 重写 __repr__ 方法 str() 和 repr() 的区别 为什么要讲 __repr__ 在 Python 中,直接 print 一个实例对象,默认是输出这个对象由哪个类创建的对象,以及在内存中的地址(十六进制表示) 假设在开发调试过程中,希望使用 print 实例对象时,输出自定义内容,就可以用 __repr__ 方法了 或者通过 repr() 调用对象也会返回 __repr__ 方法返回的值 是不是似曾相识....没错..和 __str__ 一样的

  • jQuery编程动画的基本方法示例详解

    目录 一.动画 .show() .hide() .fadeIn() .fadeOut() .animate() .slideDown() .slideUp() .delay() .clearQueue() .fadeTo() 一.动画 jQuery提供了一些列的动画基本方法,同时也提供了自定动画方案.animate(). .show() 当提供一个 duration(持续时间)参数,.show()成为一个动画方法..show()方法将为匹配元素的宽度,高度,以及不透明度,同时进行动画操作. 持续

随机推荐