代码之家  ›  专栏  ›  技术社区  ›  Miguel Ping

JPA 1.0是否有任何JPA Fluent API/Critera API?我用的是OpenJPA

  •  4
  • Miguel Ping  · 技术社区  · 14 年前

    是否有用于查询构建的JPA1.0 Fluent API/接口?我使用的是openjpa 1.x,所以我只能使用jpa1。

    我发现 QueryByProxy 但它的Maven回购协议工作不正常。

    3 回复  |  直到 7 年前
        1
  •  2
  •   Pascal Thivent    14 年前

    如果你坚持使用JPA1.0,那么考虑使用 Querydsl 它在JPA之上提供了一个流畅的类型安全API。您必须使用1.6.0之前的版本,即1.5.4(它们在1.6.0中切换到JPA2.0)。这是我的最佳选择。

        2
  •  0
  •   Shervin Asgari    14 年前

    简短的回答是“否”。但这取决于您使用的提供程序。例如,如果您使用的是Hibernate,那么您总是可以从Hibernate中获取标准API。然而,在JPA1.0中,这是不受支持的。但在JPA2.0中是这样的。

        3
  •  0
  •   Vlad Mihalcea    7 年前

    您可以将Fluent接口模式与JPA和Hibernate一起使用。我写 an article which explains this topic in great detail .

    总而言之,如果您使用的是Hibernate,您只需修改setter返回实体:

    @Entity(name = "Post")
    @Table(name = "post")
    public class Post {
    
        @Id
        private Long id;
    
        private String title;
    
        public Post() {}
    
        public Post(String title) {
            this.title = title;
        }
    
        @OneToMany(
            cascade = CascadeType.ALL, 
            orphanRemoval = true, 
            mappedBy = "post"
        )
        private List<PostComment> comments = new ArrayList<>();
    
        public Long getId() {
            return id;
        }
    
        public Post setId(Long id) {
            this.id = id;
            return this;
        }
    
        public String getTitle() {
            return title;
        }
    
        public Post setTitle(String title) {
            this.title = title;
            return this;
        }
    
        public List<PostComment> getComments() {
            return comments;
        }
    
        public Post addComment(PostComment comment) {
            comment.setPost(this);
            comments.add(comment);
            return this;
        }
    }
    
    @Entity(name = "PostComment")
    @Table(name = "post_comment")
    public class PostComment {
    
        @Id
        @GeneratedValue
        private Long id;
    
        private String review;
    
        private Date createdOn;
    
        @ManyToOne
        private Post post;
    
        public Long getId() {
            return id;
        }
    
        public PostComment setId(Long id) {
            this.id = id;
            return this;
        }
    
        public String getReview() {
            return review;
        }
    
        public PostComment setReview(String review) {
            this.review = review;
            return this;
        }
    
        public Date getCreatedOn() {
            return createdOn;
        }
    
        public PostComment setCreatedOn(Date createdOn) {
            this.createdOn = createdOn;
            return this;
        }
    
        public Post getPost() {
            return post;
        }
    
        public PostComment setPost(Post post) {
            this.post = post;
            return this;
        }
    }
    

    这样,您可以这样构建父实体和子实体:

    doInJPA(entityManager -> {
        Post post = new Post()
        .setId(1L)
        .setTitle("High-Performance Java Persistence")
        .addComment(
            new PostComment()
            .setReview("Awesome book")
            .setCreatedOn(Timestamp.from(
                LocalDateTime.now().minusDays(1).toInstant(ZoneOffset.UTC))
            )
        )
        .addComment(
            new PostComment()
            .setReview("High-Performance Rocks!")
            .setCreatedOn(Timestamp.from(
                LocalDateTime.now().minusDays(2).toInstant(ZoneOffset.UTC))
            )
        )
        .addComment(
            new PostComment()
            .setReview("Database essentials to the rescue!")
            .setCreatedOn(Timestamp.from(
                LocalDateTime.now().minusDays(3).toInstant(ZoneOffset.UTC))
            )
        );
        entityManager.persist(post);
    });
    

    如果您关心JPA可移植性,那么您可能不希望违反JavaBean规范,在这种情况下,您需要沿着正则设置器添加FLUENT接口方法:

    @Entity(name = "Post")
    @Table(name = "post")
    public class Post {
    
        @Id
        private Long id;
    
        private String title;
    
        public Post() {}
    
        public Post(String title) {
            this.title = title;
        }
    
        @OneToMany(
            cascade = CascadeType.ALL, 
            orphanRemoval = true, 
            mappedBy = "post"
        )
        private List<PostComment> comments = new ArrayList<>();
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public Post id(Long id) {
            this.id = id;
            return this;
        }
    
        public String getTitle() {
            return title;
        }
    
        public void setTitle(String title) {
            this.title = title;
        }
    
        public Post title(String title) {
            this.title = title;
            return this;
        }
    
        public List<PostComment> getComments() {
            return comments;
        }
    
        public Post addComment(PostComment comment) {
            comments.add(comment.post(this));
            return this;
        }
    }
    
    @Entity(name = "PostComment")
    @Table(name = "post_comment")
    public class PostComment {
    
        @Id
        @GeneratedValue
        private Long id;
    
        private String review;
    
        private Date createdOn;
    
        @ManyToOne
        private Post post;
    
        public Long getId() {
            return id;
        }
    
        public PostComment setId(Long id) {
            this.id = id;
            return this;
        }
    
        public String getReview() {
            return review;
        }
    
        public void setReview(String review) {
            this.review = review;
        }
    
        public PostComment review(String review) {
            this.review = review;
            return this;
        }
    
        public Date getCreatedOn() {
            return createdOn;
        }
    
        public void setCreatedOn(Date createdOn) {
            this.createdOn = createdOn;
        }
    
        public PostComment createdOn(Date createdOn) {
            this.createdOn = createdOn;
            return this;
        }
    
        public Post getPost() {
            return post;
        }
    
        public void setPost(Post post) {
            this.post = post;
        }
    
        public PostComment post(Post post) {
            this.post = post;
            return this;
        }
    }
    

    实体建筑几乎与前一个相同:

    doInJPA(entityManager -> {
        Post post = new Post()
        .id(1L)
        .title("High-Performance Java Persistence")
        .addComment(new PostComment()
            .review("Awesome book")
            .createdOn(Timestamp.from(
                LocalDateTime.now().minusDays(1).toInstant(ZoneOffset.UTC))
            )
        )
        .addComment(new PostComment()
            .review("High-Performance Rocks!")
            .createdOn(Timestamp.from(
                LocalDateTime.now().minusDays(2).toInstant(ZoneOffset.UTC))
            )
        )
        .addComment(new PostComment()
            .review("Database essentials to the rescue!")
            .createdOn(Timestamp.from(
                LocalDateTime.now().minusDays(3).toInstant(ZoneOffset.UTC))
            )
        );
        entityManager.persist(post);
    });