02 A first iteration of the data model

簡介

此章節是如何從記憶體暫存資料庫中迭代出第一筆資料並顯示,在此將會學到如何運用JPA功能來操作資料。


The User class

這裡將開始建立BLOG Engine的User class,代表著記錄使用者相關訊息。建立於/yabe/app/models/User.java

package models;

import java.util.*;
import javax.persistence.*;
import play.db.jpa.*;
 
@Entity
public class User extends Model {
    public String email;
    public String password;
    public String fullname;
    public boolean isAdmin;
    
    public User(String email, String password, String fullname) {
        this.email = email;
        this.password = password;
        this.fullname = fullname;
    }
}

@Entity註解標記作為管理JPA實體。你可以運用普遍的JPA方式,並不一定要繼承play.db.jpa.Model。但是,如果繼承了這個類別也是很好的選擇,在大多數的情況下會容易做出很多JPA的相關運用。

若在此之前,你已使用JPA,你已知道每一個JPA實體必須提供一個@Id屬性。在這裡Model已自動生成提供一個數字ID,這樣似乎不錯!


The Post class

Post class意味著BLOG文章。藉此來編寫第一個實作:

package models;
 
import java.util.*;
import javax.persistence.*;
import play.db.jpa.*;
 
@Entity
public class Post extends Model {
 
    public String title;
    public Date postedAt;
    
    @Lob
    public String content;
    
    @ManyToOne
    public User author;
    
    public Post(User author, String title, String content) {
        this.author = author;
        this.title = title;
        this.content = content;
        this.postedAt = new Date();
    }
}

@Lob註解標記將告訴JPA使用大量文字的資料型態來儲存,而宣佈關係型態到User class則使用@ManyToOne。意味著一位使用者可以寫多篇文章,而多篇文章可能是由一位使用者發佈。


Adding Comments

最後,則新增一個Comment class是能夠在文章上附加評論。新增Comment class非常簡單:

package models;

import java.util.*;
import javax.persistence.*;
import play.db.jpa.*;
 
@Entity
public class Comment extends Model {
 
    public String author;
    public Date postedAt;
    
    @Lob
    public String content;
   
    @ManyToOne
    public Post post;
   
    public Comment(Post post, String author, String content) {
        this.post = post;
        this.author = author;
        this.content = content;
        this.postedAt = new Date();
    }
}


現在需要查詢語句來檢索所有在文章上的評論。它必須設定與Post class之間的關係型態,所以需要新增一組comments欄位在Post class上。

...
@OneToMany(mappedBy="post", cascade=CascadeType.ALL)
public List<Comment> comments;
 
public Post(User author, String title, String content) { 
    this.comments = new ArrayList<Comment>();
    this.author = author;
    this.title = title;
    this.content = content;
    this.postedAt = new Date();
}
...
 


這裡要注意,已經使用了mappedBy屬性告訴JPA,Comment class的Post post欄位應保持這種的雙向關係型態。

當定義JPA雙向溝通關係是非常重要的,在這種情況下,comments屬於Post。

這樣可以告訴JPA如果我們想要刪除一則Post則連代關係上comments也將被刪除。

有了這樣的關係之後,我們就新增一個輔助方法於Post class並簡易的添加comments:

public Post addComment(String author, String content) {
    Comment newComment = new Comment(this, author, content).save();
    this.comments.add(newComment);
    this.save();
    return this;
}


Using Fixtures to write more complicated tests

為了進一步的測試,通常需要匯入一組實際資料來輔助。Fixtures讓你可以在測試之前描述你的模組內的YAML檔案並在任何時間可以讀取。此時,編輯/yabe/test/data.yml檔案並描述使用者相關資訊。

User(bob): email: bob@gmail.com password: secret fullname: Bob

當然,為了快速取得更多的使用者訊息,可以download it here

Comments