天天看點

Halo 開源項目學習(二):實體類與資料表

Halo 項目中定義了一些實體類,用于存儲部落格中的關鍵資料,如使用者資訊、文章資訊等。在深入學習 Halo 的設計理念與實作過程之前,不妨先學習一下一個完整的部落格系統都由哪些元素組成。

基本介紹

Halo 項目中定義了一些實體類,用于存儲部落格中的關鍵資料,如使用者資訊、文章資訊等。在深入學習 Halo 的設計理念與實作過程之前,不妨先學習一下一個完整的部落格系統都由哪些元素組成。

實體類

Halo 中的除 BaseEntity 外的每一個實體類都對應着一個資料表,以 User 類為例,每一個 User 對象都對應 users 表中的一條記錄,每一個對象屬性的值也等于資料表中對應字段的值。

User 類定義如下:

@Data // Lombok 注解, 自動生成 get()、set()、toString() 等方法
@Entity // JPA 注解, 聲明該類為一個實體類, 必須與 @Id 搭配使用
@Table(name = "users") // JAP 注解, 聲明該類映射到資料庫的 users 資料表
@ToString(callSuper = true) // Lombok 注解, callSuper = true 表示調用 toString() 方法時輸出父類的屬性
@EqualsAndHashCode(callSuper = true) // 自動生成 equals() 和 hashCode() 方法, 預設 callSuper 為 false, 為 true 表示 equals() 方法比較時會調用父類的 equals() 方法
public class User extends BaseEntity {

    @Id // JPA 注解, 聲明主鍵
    @GeneratedValue(strategy = GenerationType.IDENTITY) // JPA 注解, 聲明主鍵的生成政策, IDENTITY 表示使用自增 id
    @Column(name = "id") // JPA 注解, 聲明實體類的屬性 id 映射到資料表中的字段 id
    private Integer id;

    /**
     * User name.
     */
    @Column(name = "username", columnDefinition = "varchar(50) not null")
    private String username;

    /**
     * User nick name,used to display on page.
     */
    @Column(name = "nickname", columnDefinition = "varchar(255) not null")
    private String nickname;

    /**
     * Password.
     */
    @Column(name = "password", columnDefinition = "varchar(255) not null")
    private String password;

    /**
     * User email.
     */
    @Column(name = "email", columnDefinition = "varchar(127) default ''")
    private String email;

    /**
     * User avatar.
     */
    @Column(name = "avatar", columnDefinition = "varchar(1023) default ''")
    private String avatar;

    /**
     * User description.
     */
    @Column(name = "description", columnDefinition = "varchar(1023) default ''")
    private String description;

    /**
     * Expire time.
     */
    @Column(name = "expire_time", columnDefinition = "timestamp default CURRENT_TIMESTAMP")
    @Temporal(TemporalType.TIMESTAMP)
    private Date expireTime;


    @Override
    public void prePersist() {
        super.prePersist();

        id = null;

        if (email == null) {
            email = "";
        }

        if (avatar == null) {
            avatar = "";
        }

        if (description == null) {
            description = "";
        }

        if (expireTime == null) {
            expireTime = DateUtils.now();
        }
    }
}
           

注解解釋:

  • @Data:Lombok 注解,自動生成 get()、set()、toString() 等方法。
  • @Entity:JPA 注解,聲明該類為一個實體類, 必須與 @Id 搭配使用。
  • @Table:JAP 注解,聲明該類對應資料庫中的某個資料表,name 指明表名。
  • @ToString:lombok 注解,callSuper = true 表示調用 toString() 方法時會輸出父類的屬性。
  • @EqualsAndHashCode:自動生成 equals() 和 hashCode() 方法,預設 callSuper 為 false, 為 true 表示 equals() 在方法比較時會調用父類的 equals()(如果父類的 equals() 傳回 false,則直接傳回 false,否則繼續比較)。
  • @Id:JPA 注解,聲明主鍵。
  • @GeneratedValue:JPA 注解,聲明主鍵的生成政策,IDENTITY 表示使用自增 id。
  • @Column:JPA 注解,聲明實體對象的屬性映射到資料表中的哪一個字段,name 指定字段名,columnDefinition 指定字段的定義。

User 類中定義了使用者名、昵稱、郵箱等使用者資料,Halo 使用 JPA 将實體對象持久化到資料庫中,也就是将 User 對象的各個屬性存儲到資料表 users 的各個字段中。JPA 支援自動建立資料表,是以啟動項目前無需建表,關于 JPA 的使用,可以參考 SpringBoot 整合 Spring Data JPA。

User 類繼承了 BaseEntity,BaseEntity 類中定義了一些通用的屬性,如 createTime、updateTime 以及 deleted 等,分别指使用者的建立時間、修改時間以及是否被删除,users 表中有對應的字段。此外,BaseEntity 類還定義了三個方法,分别為 prePersist()、preUpdate() 和 preRemove():

  • prePersist() 方法在對象持久化到資料庫之前被調用。
  • preUpdate() 方法在對象的某個屬性發生變動時被調用,如更新實體的 update_time。
  • preRemove() 方法在對象從資料庫删除前被調用。

BaseEntity 并沒有對應某一個資料表,它被 @MappedSuperclass 修飾, @MappedSuperclass 屬于 JPA 注解,應用于實體類的父類中, 該注解作用的類不會映射到資料表,但其屬性都将映射到子類所對應的資料表。也就是說不同實體類的通用屬性可在相同的父類中定義,子類繼承父類後,父類中的這些通用屬性會持久化到子類對應的資料表中。

BaseEntity 類定義如下:

@Data
@ToString
@MappedSuperclass // JPA 注解, 應用于實體類的父類中, 該注解作用的類不會映射到資料表,但其屬性都将映射到子類的資料表
@EqualsAndHashCode
public class BaseEntity {

    /**
     * Create time.
     */
    @Column(name = "create_time", columnDefinition = "timestamp default CURRENT_TIMESTAMP")
    @Temporal(TemporalType.TIMESTAMP)
    private Date createTime;

    /**
     * Update time.
     */
    @Column(name = "update_time", columnDefinition = "timestamp default CURRENT_TIMESTAMP")
    @Temporal(TemporalType.TIMESTAMP)
    private Date updateTime;

    /**
     * Delete flag.
     */
    @Column(name = "deleted", columnDefinition = "TINYINT default 0")
    private Boolean deleted = false;

    @PrePersist // @PrePersist 事件在實體對象插入到資料庫的過程中發生
    protected void prePersist() {
        deleted = false;
        Date now = DateUtils.now();
        if (createTime == null) {
            createTime = now;
        }

        if (updateTime == null) {
            updateTime = now;
        }
    }

    @PreUpdate // @PreUpdate 事件在實體的狀态同步到資料庫之前觸發
    protected void preUpdate() {
        updateTime = new Date();
    }

    @PreRemove // @PreRemove 事件在實體從資料庫删除之前觸發
    protected void preRemove() {
        updateTime = new Date();
    }
}
           

資料表

項目啟動成功後,JPA 會為實體類自動生成對應的資料表。可以使用 Navicat 檢視 MySQL 中庫名為 'halodb' 的資料庫(自己配置的庫名),發現自動建立了如下資料表:

Halo 開源項目學習(二):實體類與資料表

下面介紹不同資料表的作用以及對應的字段含義,由于許多實體類都繼承自 BaseEntity,是以不同資料表中會有一些通用的字段,如:

  • id

    :主鍵(雖不在 BaseEntity 中定義,但每個子類中都存在)。
  • crate_time

    :建立時間。
  • deleted

    :是否已經删除。
  • update_time

    :更新時間。

下面介紹各個資料表中,特定字段的具體含義:

1. attachments:附件表,用于存放圖檔和檔案。

  • file_key

    :檔案的 key,可以根據 file_key 删除檔案。
  • height

    :圖檔高度。
  • media_type

    :媒體類型,如 text/html、image/jpeg 等。
  • name

    :附件的名字。
  • path

    :附件的存儲路徑。
  • size

    :附件的大小。
  • suffix

    :附件的字尾,如 png、html 等。
  • thumb_path

    :縮略圖的通路路徑,該路徑指定的資源可用作為封面圖。
  • type

    :附件的上傳類型,如上傳到本地(type 為 0)、阿裡雲(type 為 4)。
  • width

    :圖檔寬度。

2. categories:文章分類目錄表,釋出文章時可設定文章所屬的分類。

  • decryption

    :描述。
  • name

    :分類名。
  • parent_id

    :父目錄 id。
  • password

    :密碼。
  • slug

    :别名。
  • slug_name

    :項目中沒有用到。
  • thumbnail

    :分類的封面圖。

3. comment_black_list:評論黑名單表,用于禁止某個 ip 進行評論。

  • ban_time

    :封禁時間。
  • ip_address

    :封禁的 ip。

4. comments:評論表,可對文章進行評論,也可對評論進行回複,還可以對頁面(友情連結、圖庫、日志等)進行評論。

  • type

    :給文章進行評論時 type 為 0,給頁面進行評論時 type 為 1。
  • allow_notification

    :是否允許通知。
  • author

    :評論者的姓名。
  • author_url

    :評論者的 url。
  • content

    :評論内容。
  • email

    :評論者的 email。
  • gravatar_md5

    :評論者的頭像。
  • ip_address

    :評論者的 ip。
  • is_admin

    :評論者是否為部落客。
  • parent_id

    :如果回複某個評論,則 parent_id 為該評論的 id;如果評論文章,則 parent_id 為 0。
  • post_id

    :哪篇文章或哪個頁面的評論。
  • status

    :評論的狀态,0 表示已釋出,1 表示待釋出,2 表示添加到了資源回收筒。
  • top_priority

    :是否置頂。
  • user_agent

    :使用者代理,例如浏覽器。

5. journals:使用者日志表,在 Halo 中使用者可以對外分享日志(記錄生活的日志),日志的資訊存儲在 journals 表中。

  • content

    :日志内容。
  • likes

    :點贊量。
  • source_content

    :原始内容。
  • type

    :日志類型,公開日志的 type 為 0,私密日志的 type 為 1。

6. links:友情連結表,用于通路其他部落格或資源。

  • description

    :描述。
  • logo

    :标志。
  • name

    :名稱。
  • priority

    :排序編号。
  • team

    :所屬分組。
  • url

    :連結。

7. logs:系統日志表,記錄使用者的操作。

  • content

    :日志内容。
  • ip_address

    :操作者的 ip。
  • log_key

    :log_key 通常為操作對象的辨別,例如釋出文章時 log_key 是文章的 id,使用者登入時 log_key 是使用者的 userName。
  • type

    :日志類型,例如發表文章時 type 為 5,登入時 type 為 25。

8. menus:菜單表,部落格的首頁有多個菜單,且每個菜單都可以是多級菜單。

  • icon

    :圖示。
  • name

    :名稱
  • parent_id

    :父級菜單的 id。
  • priority

    :優先級,用于部落格首頁上菜單的排序。
  • target

    :可選 _self 和 _blank,_self 表示在目前頁面打開菜單所指向的連結;_blank 表示在新的頁面打開連結。
  • team

    :所屬分組。
  • url

    :菜單所指向的連結。

9. metas:中繼資料表,用于設定文章或頁面的屬性,可在釋出文章或頁面時的 "進階" 選項中進行操作。

  • type

    :設定文章的中繼資料時 type 為 0,設定頁面的中繼資料時 type 為 1。
  • mate_key

    :中繼資料 key 可以設定文章是否支援點贊、是否支援複制等。
  • mate_value

    :key 對應的值
  • post_id

    : 文章或頁面的 id。

10. options:部落格設定表,或者稱為選項表,用于存儲系統設定的相關資訊。使用者可在 Dashboard 界面的 "系統" -> "部落格設定" 中進行配置。

  • option_key

    :部落格的選項,例如部落格标題 blog_title、主題 theme、是否已安裝 is_installed 等。
  • type

    :部落格的内部選項的 type 為 0,自定義選項的 type 為 1。
  • option_value

    :選項對應的值。

11. photos:圖檔表,Halo 可以設定圖庫,圖庫頁面的圖檔存放在 photos 表中。

  • description

    :描述。
  • likes

    :點贊量。
  • location

    :拍攝地點。
  • name

    :名稱。
  • take_time

    :拍攝日期。
  • team

    :所屬分組。
  • thumbnail

    :縮略圖位址。
  • url

    :圖檔連結。

12. post_categories:文章 - 分類的關系表,記錄每個文章屬于哪個分類。

  • category_id

    :分類 id。
  • post_id

    :文章 id。

13. post_tags:文章标簽表,記錄文章的标簽。

  • post_id

    :文章 id。
  • tag_id

    :标簽 id。

14. posts:文章表,也用來存儲頁面。

  • type

    :文章的 type 為 0,頁面的 type 為 1。
  • disallow_comment

    :是否關閉評論。
  • edit_time

    :編輯時間。
  • editor_type

    :編輯器類型。
  • format_content

    :格式化後的内容。
  • likes

    :點贊量。
  • meta_description

    :自定義描述。
  • meta_keywords

    :自定義關鍵詞。
  • original_content

    :原始内容。
  • password

    :密碼。
  • slug

    :别名。
  • status

    :狀态,0 表示已釋出,1 表示待釋出,2 表示位于資源回收筒,3 表示私密文章或頁面。
  • summary

    :文章摘要。
  • template

    :自定義的模闆,新增頁面時可設定模闆。
  • thumbnail

    :封面圖。
  • title

    :标題。
  • top_priority

    :是否置頂。
  • url

    :連結。
  • visits

    :通路量。
  • word_count

    :字數統計。

15. tags:标簽表,釋出文章時,可為文章設定标簽。

  • name

    :标簽名稱。
  • slug

    :别名。
  • slug_name

    :項目中沒有用到。
  • thumbnail

    :标簽的封面圖。

16. theme_settings:主題設定表,設定部落客題。

  • setting_key

    :主題中可設定的選項,例如文章标題是否大寫 post_title_uppper、部落格首頁的郵箱 email 等。
  • theme_id

    :主題的 id。
  • setting_value

    :setting_key 對應的值。

17. users:使用者表,記錄使用者資訊。

  • avatar

    :頭像。
  • decription

    :描述。
  • email

    :郵箱。
  • expire_time

    :過期時間,嚴格來說應該稱為賬号的起始有效時間,目前時間超過 expire_time 時,該賬号才能正常登入。
  • maf_key

    :兩步驗證碼的 key。
  • maf_type

    :是否開啟了兩步驗證碼,0 表示未開啟(預設),1 表示開啟。
  • nickname

    :昵稱。
  • password

    :密碼。
  • username

    :使用者名。