Java 当没有冲突时,如何使用SpringJPA将记录插入数据库

Java 当没有冲突时,如何使用SpringJPA将记录插入数据库,java,postgresql,spring-boot,spring-data-jpa,Java,Postgresql,Spring Boot,Spring Data Jpa,我有一个spring引导应用程序,它使用spring数据jpa与PostgreSQL数据库连接,这里是我的实体,有将近40个字段 现在,为了将实体保存到数据库中,我只使用studentRepository.save方法 studentRepository.save(new StudentEntity()); DAO实体 @Table @Entity public class StudentEntity { @Id @Generate( using databa

我有一个spring引导应用程序,它使用
spring数据jpa
与PostgreSQL数据库连接,这里是我的实体,有将近40个字段

现在,为了将实体保存到数据库中,我只使用
studentRepository.save
方法

studentRepository.save(new StudentEntity());
DAO实体

  @Table
  @Entity
  public class StudentEntity {

     @Id
     @Generate( using database sequenece)
     private long studentId;

     private String studentName;

     private String dept;

     private String age;
      ..
      ..
      }
 public interface StudentRepository implements JPARepository<Long, Student> {
   }
@Query(value = "insert into Users (name, age, email, status) values (:name, :age, :email, :status)", nativeQuery = true)

 void insertUser(@Param("name") String name, @Param("age") Integer age, @Param("status") Integer status, @Param("email") String email);
存储库

  @Table
  @Entity
  public class StudentEntity {

     @Id
     @Generate( using database sequenece)
     private long studentId;

     private String studentName;

     private String dept;

     private String age;
      ..
      ..
      }
 public interface StudentRepository implements JPARepository<Long, Student> {
   }
@Query(value = "insert into Users (name, age, email, status) values (:name, :age, :email, :status)", nativeQuery = true)

 void insertUser(@Param("name") String name, @Param("age") Integer age, @Param("status") Integer status, @Param("email") String email);

如果您的首要任务是减少冗余,因为这是本机sql,那么如果您将字段的名称按正确的顺序排列,则可以避免使用字段名称,但必须将表中的所有值,甚至null:

@Query(value = "insert into Users values (:name, :age, :email, :status)", nativeQuery = true)
 void insertUser(@Param("name") String name, @Param("age") Integer age, @Param("status") Integer status, @Param("email") String email);
或者,如果findByStudentNameAndDebt(studentName,dept)方法未返回任何结果,则可以保存,而不是使用本机插入。在StudentRepository中(此处不需要母语):

为您服务:

if(studentRepository.findByStudentNameAndDebt(studentName, dept)==null) {
   studentRepository.save(new StudentEntity());
}

使用数据库。在这两个字段上创建一个字段,并尝试添加其中的多个字段将被阻止

差不多

ALTER TABLE StudentEntity ADD CONSTRAINT UQ_NAME_DEPT UNIQUE (studentName,dept);
此唯一约束将防止插入重复的组合

您还可以在JPA实体上定义一个约束,以自动创建用于测试的索引

@Table(uniqueConstraints=@UniqueConstraint(columnNames = {"studentName", "dept"})

不需要本机查询。您也可以通过编写面向对象的查询来实现这一点。首先检查表中是否有
name
dept
记录。 如果返回null,则执行保存

StudentRepository.java
您可以使用轻量级查询来检查是否已经存在具有相同姓名和部门的学生

public interface StudentRepository implements JPARepository<Long, Student> {

@Query("SELECT CASE WHEN COUNT(c) > 0 THEN true ELSE false END FROM Student s WHERE s.studentName= :studentName AND s.dept= :dept")
    public boolean existsByNameAndDepartment(@Param("studentName") String studentName, @Param("dept") String dept);
公共接口StudentRepository实现了JPARepository{
@查询(“当计数(c)>0时选择大小写,然后为true,否则为false,从学生s结束,其中s.studentName=:studentName和s.dept=:dept”)
公共布尔值existsbynameandepartment(@Param(“studentName”)字符串studentName,@Param(“dept”)字符串dept);

在这些属性上声明一个唯一的索引,无条件插入,并捕获/转换抛出的异常?先生,我不确定您在解释什么@chrylisWe遇到了一个类似的问题,我不得不使用“on replicate KEY”特定于MYSQL数据库的功能。最初我们使用@Query,但不可读。因此,我们搜索并找到了适合此类情况的替代方案。您能否为上述场景演示一个示例,以及如何集成该示例?看一看,我将尝试此功能。谢谢,插入du时是否会引发异常复制记录?或者只是忽略?在异常情况下,spring将负责关闭连接部分,对吗?作为程序员,除了处理它之外,我们还需要做什么吗?我强烈建议您阅读您正在使用的技术(JPA和spring)。不,您不需要做任何事情(如果您以正常方式使用Thin!)。您也可以在存储库上使用
保存
方法,不需要单独的插入方法,也不需要专门的查询。唯一约束方法的一个缺点是(与
插入…冲突时不执行任何操作
)是Hibernate,将冲突记录为错误。因此,这取决于发生的频率,对您来说可能值得,也可能不值得。(是的,您可以将记录器配置为忽略Hibernate的SqlExceptionHelper类中的错误消息,但这可能会隐藏其他真实错误)。约束是开箱即用的。
insert..on conflict do nothing
需要编写自定义查询,并且不能在所有数据库上运行。这不是线程安全的。想象一下,如果两个线程同时启动:两个线程都将从
findByStudentNameAndDebt获得
null
,然后都将保存新实体。Thi当两个线程通过if条件并同时进入save块时,s允许出现争用条件。