[MixMVC]MixMVC3.1 Model

在MixMVC中,model代表具体是数据逻辑封装,其中包括数据库访问、外部接口访问[外部web service、memcached、smtp]等,一切跟数据有关的逻辑都会封装到Model里面,最常用的当时数据库访问的封装了。

Model结构

在MixMVC中,如果需要使用数据库相关的接口,我们需要model继承MST_DBO,MST_DBO 封装了常用的CRUD操作API。配合不同的MST_DBC后端,可以实现对不同的数据库的操作,暂时已经实现的DBC只支持MySQL及Oracle。

PS: 有兴趣的同学可以继续向下研究。
更快捷的方式是,到 http://192.168.33.6/mvctools 使用这个生成工具,直接生成相关的Model php文件。

当我们继承了MST_DBO后,我们首页需要建立Model与数据表之间的映射,我们需要在继承类中设置一下静态变量:
一个Model文件的基本模板:

//所有model一般都是有关于操作数据库的,所以一般我们都会继承自MST_DBO。
//这里的类名是使用的pear风格的命名规范,其中Edm_Admin 是命名空间(namespace),
//该文件会放到application/models/edm/admin/Session.php
//注意文件夹的命名都是小写的,而类名(ClassName)中是首字母大写的,而已文件名就跟类名(ClassName)一样是首字母大写的。
class Edm_Admin_Session extends MST_DBO {

    protected static
        //$columns数组,所有继承于MST_DBO的类,必须包含的定义,用于定义具体的字段参数。
        //数组中包含多个配置定义,分别用于自动生成form组件,及数据验证时使用。
        //基本格式为 $key => array($type, 'title' => $title) $key 字段在数据库中的名称,
        //$type form组件类型会根据此值生成相关的input[text/datepicker/radiogroup等]
        //$title 关于该字段的文字描述, 其他选项会有专门相关的文章说明。
        $columns = array(
            'sess_id' => array('text', 'title' => 'Sess ID', 'require' => 1),
            'value' => array('text', 'title' => 'Value', 'require' => 1),
            'created_at' => array('datetime', 'title' => 'Created Time', 'require' => 1),
            'created_ip' => array('text', 'title' => 'Created Ip', 'require' => 1),
            'updated_at' => array('datetime', 'title' => 'Updated Time', 'require' => 1),
            'expired_at' => array('text', 'title' => 'Expired At', 'require' => 1),
            'user_id' => array('text', 'title' => 'User ID', 'require' => 1),
        ),
        //$stuct 默认new model的时候包含的字段
        $struct  = array('sess_id','value','created_at','created_ip','updated_at','expired_at','user_id'),
        //$defaultSelect 默认使用find方法时返回的数据字段
        $defaultSelect = 'id,sess_id,value,created_at,created_ip,updated_at,expired_at,user_id';

        //钩子回调函数,当新建数据之前是触发
        protected function beforeCreate(& $data) {
            $data['created_at'] = time();
        }

        //钩子回调函数,当数据更新之前触发
        protected function beforeUpdate(& $data) {
            $data['updated_at'] = time();
        }

        //默认的必须实现的接口方法,配合grid组件使用,用于生成列表头部
        static public function getGridHeads() {
            $heads = self::getAllColumnOptions();
            return $heads;
        }

        //默认必须实现的接口方法,配合dbo_form组件使用,用于获取字段信息,生成相关表单(form)
        public function  getFormColumns() {
            $columns = self::$columns;
            return $columns;
        }
}

上面模板中都有相关的注释说明其意义,$columns的具体参数项请看这个文章,然后我们说一下模板中没有表现出来的地方。

默认回调函数

Model中预定于了若干回调函数,用于在流程插入自定义的逻辑操作。例如在上面的模板中,我们就通过beforeCreate 与beforeUpdate连个预定义回调函数,在插入之前及更新之前的时候,把相关字段的默认值+上。
所有的预定义回调函数如下:

//数据验证前触发,一般在此加入自定义的数据库验证判断逻辑,可以通过return false中断流程
 public function beforeValidate(& $data, $args) {} 

 //创建数据前触发,一般在此+入创建时间戳
 public function beforeCreate(& $data, $args) {}

 //数据更新前触发,一般在此+入更新时间戳
 public function beforeUpdate(& $data, $args) {}

 //数据保存前触发,此回调会在创建和更新的时候都会触发
 public function beforeSave(& $data, $args) {}

 //数据创建后触发,一般用于关联项目的更新及插入操作,状态判断请使用isNews()方法
 public function afterCreate(& $data, $args) {}

 //数据更新后触发,一般用于关联项目的更新及插入操作,状态判断请使用isNews()方法
 public function afterUpdate(& $data, $args) {}

 //数据保存后触发,在更新及创建后都会触发该回调,一般用于关联项目的更新及插入操作,状态判断请使用isNews()方法
 public function afterSave(& $data, $args) {}
 

Model常用函数

查找相关:

        //单条记录最简单方法
        $admin_session = Admin_Session::find($id);

        //使用isNew方法判断是否查询成功
        $admin_session->isNew();

        //单条记录完整查询模式,基本上使用array生成SQL,SQL语法就不在叙说了
        $admin_session = Admin_Session::find(Admin_Session::FIRST, array(
            'select' => '*',
            'join' => 'LEFT JOIN *** on admin_session.id=***.**',
            'group' => 'admin_session.id',
            'order' => 'id desc',
            'limit' => 1,
            'having' => array('id' => array('=', 1)) //having 聚合条件查询,eg:array('id' => array('>', 1))/array('id' => array('<', 1)),
            'in' => array('id' => array(1,2,3,)), // sql in 条件查询
            'where' => array('id=?', $id) //条件查询使用dbo风格,?代替变量
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
        ));

        //多条记录完整查询模式
        $list = Admin_Session::find(Admin_Session::ALL, array(
            'select' => '*',
            'join' => 'LEFT JOIN *** on admin_session.id=***.**',
            'group' => 'admin_session.id',
            'order' => 'id desc',
            'limit' => 1,
            'having' => array('id' => array('=', 1)) //having 聚合条件查询,eg:array('id' => array('>', 1))/array('id' => array('<', 1)),
            'in' => array('id' => array(1,2,3,)), // sql in 条件查询
            'where' => array('id=?', $id)//条件查询使用dbo风格,?代替变量
        ));

        //由于DBO继承自MST_DBO_DataSet, 使用isEmpty方法判断返回的list是否为空,
        //然后可以直接使用foreach迭代DBO数据,不需要再转成数组!
        if (!$list-&gt;isEmpty()) {
            foreach($list as $row) {
                //code
            }
        }

数据添加/更新/删除

 
       //最常用的插入方法,直接new一个Model
        $admin_session = new Admin_Session();
        //使用assign方法填充数据
        $admin_session-&gt;assign(array(
            'created_at' => time(),
            'updated_at' => time(),
            'user_id' => $user_id,
        ));
        //使用upgrade方法保存数据,返回操作结果
        $admin_session-&gt;upgrade();
        //使用isNew判断操作是否成功
        if ($admin_session-&gt;isNew()) {
            //code
        }

        //一般更新数据之前,我们会先查询
        $admin_session = Admin_Session::find($id);
        //也可以使用直接赋值的方法填充数据
        $admin_session['user_id'] = $user_id;
        //使用upgrade方法保存数据,返回操作结果
        $admin_session-&gt;upgrade();

        //使用静态方法update更新,第一个参数是条件,可以直接使用id
        //第二个参数是需要更新的数据
        Admin_Session::update($id, array(
            'user_id' => $user_id,
        ));

        //也可以使用自定义条件更新数据,一般用于批量操作
        Admin_Session::update(array(
            'where' => array('id=?', $id)
        ), array(
            'user_id' => $user_id,
        ));

        //最简单的删除数据方法,直接传id,返回操作结果
        Admin_Session::delete($id);
        //使用自定义条件进行删除操作,一般用于批量操作
        Admin_Session::delete(array(
            'where' => array('user_id=?', $user_id),
        ));

以上就是有关Model部分的基本描述。

Update 2015-08-21: 增加 in条件/having条件的例子。

文章分类 MixMVC, 经验分享
2 comments on “[MixMVC]MixMVC3.1 Model
  1. Ken AU说道:

    //一般更新数据之前,我们会先查询
    $admin_session = Admin_Session::find($id);
    //也可以使用直接赋值的方法填充数据
    $admin_session[‘user_id’] = $user_id;
    //使用upgrade方法保存数据,返回操作结果
    $admin_session->upgrade();

    上述解释中,用upgrade()更新数据时,有个情况,就是如果能find出$id,即查到有记录对象返回,那样更新是没问题,但是,要是find不到这$id,那情况就不同了,会变成向数据表插入一条记录,这显然不是想要的结果。而用update(),哪怕是没有查到相应的条件,但它只是返回一条查询的SQL语句,所以用静态的update更新数据记录更为妥当!

    isNew()和isEmpty()的疑问

    $id = 272990;
    $db = self::find(self::FIRST, array(
    ‘where’ => array(‘id >= ?’, $id)
    ));
    var_dump($db->isEmpty());
    var_dump($db->isNew());

    上述代码中,当find方法中第一个参数是FIRST时,无论条件是否找到,能正常执行,而当第一个参数是ALL时,isEmpty能正常执行,而isNew会报错,那么按测试如果用find时,不管第一个参数是FIRST还是ALL,我们执行后都用isEmpty,不更为妥当?

    • Sam Zhou说道:

      DBO::find 方法的会根据第一个参数的,return不同的类型。

      如果是传$id, 如model::find($id) 或者 model::find(model::FIRST, array(…)), 会返回一个model对象。

      而如果是查询list,如model::find(model::ALL, array(…)),就会返回MST_DBO_DataSet。

      由于model 继承自 MST_DBO,而MST_DBO又继承自 MST_DBO_DataSet,所以两个返回的对象中都可以找到 isEmpty()方法[该方式来自MST_DBO_DataSet的父类MST_DataSet],用于判断集合(list)是否为空。而isNew()方式是来自MST_DBO,用于判断对象是否填充数据。

      由于model::find返回的对象不同,所以使用的时候需要注意,正确理解返回的是什么对象。

发表评论


Warning: Use of undefined constant XML - assumed 'XML' (this will throw an Error in a future version of PHP) in /var/www/wp/code/wp-content/plugins/wp-syntaxhighlighter/wp-syntaxhighlighter.php on line 1048