簡體   English   中英

如何在沒有沖突的情況下使用spring jpa將記錄插入數據庫

[英]How to insert record into database using spring jpa when there is no conflict

我有使用spring-data-jpa與PostgreSQL數據庫連接的spring啟動應用程序,這里是我的實體,有近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> {
   }

但現在我有要求,如果表中有任何學生記錄的namedept我不應該插入新記錄,我知道我可以使用PostgreSQL ON CONFLICT與本機查詢,但如果我使用本機查詢我必須指定查詢中的所有40個字段以及看起來很難看的方法參數。

有沒有辦法讓它變得更簡單?

本機查詢的示例

@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);

使用數據庫。 在2個字段上創建一個唯一約束 ,並嘗試添加多個字段將被阻止。

就像是

ALTER TABLE StudentEntity ADD CONSTRAINT UQ_NAME_DEPT UNIQUE (studentName,dept);

此唯一約束將阻止插入重復的組合。

您還可以在JPA實體上定義約束以自動創建用於測試的索引

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

不需要本機查詢。 您也可以通過編寫面向對象的查詢來完成它。 首先檢查表格中是否有任何記錄和namedept 如果它返回null,那么執行保存。

StudentRepository.java

public interface StudentRepository implements JPARepository<Long, Student> {


@Query("FROM Student AS stu WHERE lower(stu.name) = lower(:studentName) AND lower(stu.dept) = lower(:dept)")
public Student findStudentByNameAndDept(@Param("studentName") String studentName, @Param("dept") String dept);

//if you have already duplicates in your db, then you can do the followings too..
@Query("FROM Student AS stu WHERE lower(stu.name) = lower(:studentName) AND lower(stu.dept) = lower(:dept)")
public List<Student> findAllStudentsByNameAndDept(@Param("studentName") String studentName, @Param("dept") String dept);

}

StudentService.java

if(studentRepository.findStudentByNameAndDept(name,dept)==null){
    //save
}else{
    //custom hanlding
    throw StudentExistsException("Student with the given name/dept exists");
}

OR
//if already duplicates exisited in db

if(studentRepository.findStudentByNameAndDept(name,dept).isEmpty()){
    //save
}else{
    //custom hanlding
    throw StudentExistsException("Student with the given name/dept exists");
}

如果你的優先級是減少冗長,因為它是原生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中(這里不需要本機):

@Query("SELECT a FROM Student as a WHERE lower(a.studentName) = lower(:studentName) AND lower(a.dept) = lower(:dept)")
    public Student findByStudentNameAndDebt(@Param("studentName") final String studentName, @Param("dept") final String dept);

在您的服務中:

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

您可以使用輕量級查詢來檢查具有相同名稱和部門的學生是否已存在

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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM