简体   繁体   English

如何在没有冲突的情况下使用spring jpa将记录插入数据库

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

I have spring boot application that is connected with the PostgreSQL database using spring-data-jpa , here is my entity with nearly 40 fields 我有使用spring-data-jpa与PostgreSQL数据库连接的spring启动应用程序,这里是我的实体,有近40个字段

Now for saving the entity into database, I'm just using the studentRepository.save method 现在将实体保存到数据库中,我只是使用studentRepository.save方法

studentRepository.save(new StudentEntity());

DAO Entity DAO实体

  @Table
  @Entity
  public class StudentEntity {

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

     private String studentName;

     private String dept;

     private String age;
      ..
      ..
      }

Repository 知识库

 public interface StudentRepository implements JPARepository<Long, Student> {
   }

But now I have requirement, if there is any student record in table with name and dept I should not insert the new record, I know I can use PostgreSQL ON CONFLICT with native query for this, but if I use native query I have to specify all 40 fields in query and as method arguments which looks ugly. 但现在我有要求,如果表中有任何学生记录的namedept我不应该插入新记录,我知道我可以使用PostgreSQL ON CONFLICT与本机查询,但如果我使用本机查询我必须指定查询中的所有40个字段以及看起来很难看的方法参数。

Is there any way to make it simpler? 有没有办法让它变得更简单?

Example of native query 本机查询的示例

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

Use the database. 使用数据库。 Create a unique constraint on the 2 fields and trying to add multiple of those will be prevented. 在2个字段上创建一个唯一约束 ,并尝试添加多个字段将被阻止。

Something like 就像是

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

This unique constraint will prevent the insertion of duplicate combinations. 此唯一约束将阻止插入重复的组合。

You could also define an constraint on your JPA entity to automatically create the index for testing 您还可以在JPA实体上定义约束以自动创建用于测试的索引

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

No need of native query. 不需要本机查询。 You can do it by writing object oriented queries too. 您也可以通过编写面向对象的查询来完成它。 first check is there any record present in table by name and dept . 首先检查表格中是否有任何记录和namedept If it returns null, then do your save. 如果它返回null,那么执行保存。

StudentRepository.java 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 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");
}

If your priority is to reduce verbosity, as it is native sql you can avoid the names of the fields if you put them in the correct order, but you must put all the values of the table, even the null: 如果你的优先级是减少冗长,因为它是原生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);

Or instead of doing it with native insert, you can save if the method findByStudentNameAndDebt(studentName, dept), does not return any result. 或者,如果方法findByStudentNameAndDebt(studentName,dept)不返回任何结果,则可以保存而不是使用本机插入。 In StudentRepository (here native is not necessary): 在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);

And in your service: 在您的服务中:

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

you can use a lightweight query to check whether a student with same name and department already exists 您可以使用轻量级查询来检查具有相同名称和部门的学生是否已存在

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