JPA的CrudRepository 没有update方法,那么该如何更新数据?

刚开始使用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);
}
Spring Boot结合JPA(Java Persistence API)时,用于配置数据源和实体映射(Schema)的常用方法主要包括以下几个步骤: 1. **添加依赖**: 在`pom.xml`或`build.gradle`文件中添加Spring Data JPA和对应数据库驱动的依赖,比如对于MySQL: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> ``` 2. **配置application.properties或application.yml**: - 数据源配置: ```properties spring.datasource.url=jdbc:mysql://localhost:3306/mydb spring.datasource.username=root spring.datasource.password=password spring.jpa.hibernate.ddl-auto=update 或 create-drop (创建并自动删除数据库) ``` - 指定数据库类型和JPA属性: ```properties spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect spring.jpa.show-sql=true (显示SQL查询) spring.jpa.generate-ddl=true (生成DDL语句) ``` 3. **Entity配置**: 创建实体类(例如User.java),标注@Entity注解,并设置主键(@Id): ```java @Entity public class User { @Id private Long id; private String username; // getters and setters } ``` 4. **Repository接口**: 使用Spring Data JPACrudRepository接口或自定义Repository,声明CRUD操作: ```java public interface UserRepository extends JpaRepository<User, Long> { } ``` 5. **启用扫描**: 在Spring Boot主类上添加@ComponentScan注解,指定需要扫描的包路径,包括Repository和Service等: ```java @SpringBootApplication @ComponentScan(basePackages = {"com.example.myapp.repository", "com.example.myapp.service"}) public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值