C++網站開發MVC框架TreeFrog Framework教程——6.模型層

所謂的模型,就是返回給瀏覽器的真正有意義信息的抽象集合,但在實際編程中一般會混雜一些業務邏輯代碼,所以並不總是那麼純粹。

模型的狀態一般會保存在數據庫或者其他外部系統中,但是從控制器只關心它的狀態(用於生成視圖的具體信息),而不關心它的底層實現。

直接使用SQL語句對數據庫進行操作,有時會顯得十分煩雜,使得代碼晦澀難懂,特別是當數據表的結構十分複雜的時候。爲了儘量消除這部分阻力,可以使用TreeFrogO/R映射系統(SqlObject),同時對於web程序來說,增刪查改基本上是必需的基本功能,而且這些SQL語句有相當的規律性,這些就爲ORM提供了充分的必要性和可行性。

總的來說,實現ORM模型有一下的優點:

  1. 代碼結構更加清晰直觀;
  2. 更好地隱藏和屏蔽控制器端毫不關心的內在數據信息;
  3. 解除一個模型對應一個數據表的限制,增加模型類設計的自由度

1.模型層的API

通過生成器創建的模型類,其一般內容包括各個屬性的gettetsetter,我們可以通過createget等靜態方法來獲得模型類的實例對象。我們來看下之前的日誌文章管理系統的部分代碼:

static Blog create(const QString &title, const QString &body);
static Blog create(const QVariantMap &values);
static Blog get(int id);        //獲取指定ID的模型對象
static Blog get(int id, int lockRevision); 
static QList<Blog> getAll();    //獲取所有的模型對象

如果執行create()方法,在獲取對象實例的同時還會將它保存到數據庫中。

首先我們先來看看TAbstractModel類的定義方法:

virtual bool create();         //創建
virtual bool save();           // 創建或修改
virtual bool update();         // 修改更新
virtual bool remove();         // 刪除
virtual bool isNull() const;   // 判斷是否存在於數據庫中
virtual bool isNew() const;    // 是否仍未更新到數據庫中
virtual bool isSaved() const;  //是否已經更新到數據庫中 
void setProperties(const QVariantMap &properties);

其中,save()方法比較特殊,如果目標對象不在數據庫中,那麼就會在內部調用create()方法,否則將會調用update()方法。不過不確定是否需要重新創建一個新的模型對象,就可以使用save()方法。

2.模型類的注意事項

一般而言,類的獨立性越高可重用性也越強,因此我們在設計模型層時,也要儘量地減少它與其他模塊的耦合性和依賴性。

通常每個模型都會有對應的一個數據表,而各個模型之間的關係就反映在它們之間的某些關聯屬性上(外鍵)。下面是一些編程中常用到的API

texport方法(在前面的控制器已經能提到過)可以把對應的變量導出到視圖層,但是該變量必須具備一下條件:

  1. 公開的默認構造函數;
  2. 公開的複製構造函數;
  3. 公開的析構函數;
  4. 被進行Q_DECLARE_METATYPE宏定義;

通過生成器創建的模型層類就滿足上述的條件,因爲它們都繼承於TAbstractModel這個類,可以很方便地訪問和操作數據庫。(同時也需要注意的是,如果某個模型類不需要訪問數據庫,那麼可以不必繼承TAbstractModel

3.如何自定義模型類

正如之前說過的,通過生成器創建的模型的命名規則十分簡單而僵硬,就是表名去掉下劃線然後把首字母大寫。我們可以通過在命令的最後加上一個參數作爲該模型的自定義名稱:

$ tspawn  model  blog_entries  MyBlogEntry    ← 生成自定義命名的模型

模型並不一定需要和某個數據表相關聯,如果只是爲了往視圖層傳輸數據信息,也就是作爲一個數據信息的聚合載體。可以不必使用生成器,直接寫模型類的代碼,像下面這樣去定義我們的模型類。

class T_MODEL_EXPORT Post
{
    public:
    //已經聲明好了默認構造函數、拷貝構造函數、析構函數
    //這部分的代碼可以自由編寫
};
Q_DECLARE_METATYPE(Post)//爲了實現往視圖層傳輸單體數據
Q_DECLARE_METATYPE(QList<Post>) //爲了實現往視圖層傳輸列表數據
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章