繁体   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