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>) //为了实现往视图层传输列表数据
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章