Spring JPA Repository方法中如何使用@Query注释描述联接

时间:2018-12-11 22:00:21

标签: java spring spring-data-jpa

我正在将Spring-Boot与JPA和MySQL后端一起使用。现在,我对Spring-Boot提供的存储库感到非常困惑。我知道这些功能非常强大(并且似乎很有用,因为它们可以大大缩短您的代码)。不过,我不知道如何在其中表示联接,因为结果集应该是在几个实体的选择中指定属性的组合。

现在,让我们假设我们有三个表BookAuthorAuthorOfBook,其中最后一个表是通过组合的主数据库简单地连接BookAuthor键。我猜我们有以下Java类:

实体书:

@Entity
@Table(name="BOOK")
public class Book {

  @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "ID")
  private int id;
  @Column(name = "TITLE")
  private String title;

}

实体作者

@Entity
@Table(name="AUTHOR")
public class Author {

  @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "ID")
  private int id;
  @Column(name = "LASTNAME")
  private String lastname;
  @Column(name = "FIRSTNAME")
  private String firstname;
  //Let's assume some getters and setters and a constructor
}

实体AuthorOfBook:

@Entity
@Table(name="BOOK")
public class Book {
  @EmbeddedId
  private AuthorOfBookId pk;
}

嵌入式ID

@Embeddable
public class AuthorOfBookId implements Serializable {
  private int authorId;
  private int bookId;
}

存储库

@Repository
public interface AuthorOfBookRepository extends JpaRepository<,AuthorOfBookId> {

}

现在我将如何表示该查询:

SELECT b.name, a.firstname, a.lastname from AuthorOfBook ab inner join Book b on b.id = ab.book_id inner join Author a on a.id = ab.author_id where a.lastname = :lastname;

在我的存储库中?我知道签名必须像

@Query([the query string from above])
public (...) findAuthorAndBookByAuthorLastname(@Param("lastname") String lastname);

但是我无法确定返回的类型是什么。该方法返回什么? (我猜想AuthorOfBook根本行不通)

2 个答案:

答案 0 :(得分:2)

您不希望AuthorOfBook作为单独的实体。 Book的类型为Author的字段应为@ManyToOne关系。这样,给定任何Book,您都可以找到作者的详细信息。

答案 1 :(得分:2)

如果要处理审核字段,可以执行以下操作:

审计班

@Embeddable
public class Audit {

    @Column(name = "created_on")
    private Timestamp createdOn;

    @Column(name = "updated_on")
    private Timestamp updatedOn;

    @Column(name = "is_deleted")
    private Boolean isDeleted;

    //getters and setters

    }

AuditListener可自动更新审核字段

public class AuditListener {

    private Long loggedUser = 1001L;

    /**
     * Method to set the fields createdOn, and isDeleted when an entity is persisted
     * @param auditable
     */
    @PrePersist
    public void setCreatedOn(Auditable auditable) {
        Audit audit = auditable.getAudit();

        if (audit == null) {
            audit = new Audit();
            auditable.setAudit(audit);
        }

        audit.setIsDeleted(Boolean.FALSE);
        audit.setCreatedOn(Timestamp.from(Instant.now()));
    }

    /**
     * Method to set the fields updatedOn and updatedBy when an entity is updated
     * @param auditable
     */
    @PreUpdate
    public void setUpdatedOn(Auditable auditable) {
        Audit audit = auditable.getAudit();
        audit.setUpdatedOn(Timestamp.from(Instant.now()));
    }
}

并将其添加到实体

@EntityListeners(AuditListener.class)
public class Book implements Auditable {

    @Embedded
    private Audit audit;