刚开始使用JPA 的小伙伴们,可能有些困惑:

如下源码所示,JPA的CrudRepository只有save 方法,没有update和insert方法。我怎样告诉JPA我是要更新(update)而不是插入(insert)?

@NoRepositoryBean
public interface CrudRepository<T, ID> extends Repository<T, ID> {
	<S extends T> S save(S entity);
	<S extends T> Iterable<S> saveAll(Iterable<S> entities);
	Optional<T> findById(ID id);
	boolean existsById(ID id);
	Iterable<T> findAll();
	Iterable<T> findAllById(Iterable<ID> ids);
	long count();
	void deleteById(ID id);
	void delete(T entity);
	void deleteAll(Iterable<? extends T> entities);
	void deleteAll();

在解决以上困惑之前,我们了解一下PA(Persistence API)的两种主要设计方法。

  • update、insert方法
    当你需要修改数据库时,显式的调用PA(Persistence API)的方法:调用insert来插入对象,调用update将对象的新状态保存到数据库。

  • 工作单元方法
    当你需要将新记录插入数据库时,您可以托管相应的对象。 托管对象由其主键标识,因此,如果你使用预定义的主键托管对象,则它将与具有相同ID的数据库记录关联。在这种情况下,你有一组由持久性库(persistence library)管理的对象。 您对这些对象所做的所有更改将在工作单元结束时自动刷新到数据库(通常在当前事务结束时)。

JPA遵循后一种方法,它的save使你的实体如上所述进行管理。 这意味着在具有预定义id的对象上调用save将更新相应的数据库记录而不是插入新的记录,这也解释了为什么是save而不能称为insert。

所以,当我们save没有id的对象时,它直接添加一行到数据库,但是如果我们save有id的对象时,它将更新数据库。如下代码所示:

public void updateStudent(Student student) {
    Student studentFromDb = studentRepository.findById(student.getId());
    studentFromDb.setFirstname("ming"); 
    studentFromDb.setLastname("li");
    studentFromDb.setAge(20);
    studentRepository.save(studentFromDb);
手写update sql

如果觉得JPA的save做更新操作不习惯,我们可以手写update sql,JPA也是支持sql语句的。@Modifying 表明要对数据库进行修改,方法的返回类型是Integer,它等于受影响的行数,但如果不需要,可以将其设置为void。

@Repository
public interface StudentRepository extends CrudRepository<Student, Integer> {
    @Modifying
    @Query("UPDATE Student c SET c.address = :address WHERE c.id = :studentId")
    int updateAddress(@Param("studentId") int studentId, @Param("address") String address);
                    刚开始使用JPA 的小伙伴们,可能有些困惑:如下源码所示,JPA的CrudRepository只有save 方法,没有update和create方法。我怎样告诉JPA我是要更新(update)而不是插入(create)?@NoRepositoryBeanpublic interface CrudRepository&lt;T, ID&gt; extends Repository&lt;T, ...
				
有两种方法。 第一种:先查询到update的对象,然后对对象中你需要更新数据进行set后,再去执行save方法。 第二种:使用@Modifying和@Query的方法,这种方法对于刚刚认识jpa的人来说不太好理解,反正我是听了springboot+jpa几堂课之后,直接做项目的,对于这些都不太懂,所以个人认为第一种方法较为简单。 以下是第一种方法的代码: contoller文件部分代码 @GetMapping("/add") public Object add( @RequestParam
public interface Table1Repository extends JpaRepository<Table1, Integer> { @Query(nativeQuery = true, value = "select * from xxx.ccc.yyy") List<Object[]&.
今天写j2ee大作业的时候写到用户修改信息,需要对用户提交的域进行更新操作,因为还是spring-data-jpa菜鸟,踩了不少坑。。。先把现在有的记录一个 刚开始是想要找一个可以更新整个实体的方法,找到如下方法 在service层的代码中 Customer cust = CustomerDAO.findByUserid(id);//根据id找到要进行修改的实体 cust.set....//这里可...
直接使用她自己拥有的save方法,如果需要保存或更新的对象的id在数据库中已存在,此时save方法自动会执行update操作,如果id不存在则执行保存操作,但是切记,不要乱加注解,我之前就是多了个@Transactional注解造成JUnit Test不执行更新操作,害得我还要上网查crudrepository怎么更新的问题,既然解决了,就分享给大家。 crudrepository
Spring JPA是Spring Data提供的一种简化数据库操作的接口,可以通过它来进行数据库的增删改查操作。在Spring JPA中,我们可以使用save()方法来实现对实体类的新增和修改操作。 对于新增操作,我们只需创建一个新的实体对象,并调用save()方法即可保存到数据库中。如果需要更新一个已存在的实体对象,也只需要将实体对象的属性修改后,再次调用save()方法即可完成更新操作。Spring JPA会根据实体的主键来判断是新增还是修改操作。 除了save()方法外,Spring JPA还提供了一些其他的更新方法,包括delete()方法用于删除实体对象,以及findByXXX()方法用于根据条件查询实体对象等。这些方法都可以配合JPA注解和查询方法定义来完成各种数据库操作。 但是需要注意的是,Spring JPA没有提供一个专门的方法来单独执行更新操作,比如像SQL语句中的UPDATE语句那样。因为在JPA中,更新操作并不需要单独的更新方法,而是通过修改实体对象的属性后再保存来实现的。 综上所述,虽然Spring JPA没有专门的更新方法,但我们可以通过修改实体对象的属性后再次调用save()方法来实现更新操作。这也是Spring JPA为我们提供的一种简便的方式来操作数据库的机制。