ThinkPHP 学习笔记 ( 四 ) 数据库操作之关联模型 ( RelationMondel ) 和高级模型 ( AdvModel )

一、关联模型 ( RelationMondel )

1.数据查询

① HAS_ONE 查询

创建两张数据表评论表和文章表: tpk_comment , tpk_article 。评论和文章的对应关系为,一条评论 id 对应一篇文章,为 ONE_TO_ONE 关系 ( 一对一 )。评论表的结构为:

其中 aid 字段与文章表的 id 字段对应。打开自定义模型 ArticleModel,让模型继承于 RelationModel,然后定义成员属性 $_link,代码:

ArticleModel.class.php:

<?php
class ArticleModel extends RelationModel{

        protected $_link = array(

        //关联模型(表)1
        ‘comment‘=>array(
        //元素(属性)定义
        ‘mapping_type‘=>HAS_ONE,
        ‘class_name‘=>"comment",                             "mapping_name"=>"comment",
        "foreign_key"=>"aid",
        "mapping_fields"=>array("id","comment","comment_time"),        "as_fields"=>"id:comment_id,comment,comment_time",
        ),

}

foreign_key 为必须的。

控制器:IndexAction.class.php:

<?php
class IndexAction extends Action {

        public function relation(){

        $obj=D("Article");
        $rows=$obj->field(‘id,title‘)->relation(true)->select();
        dump($rows);
    }
}

浏览器输出:

array(6) {
  [0] => array(5) {
    ["id"] => string(1) "1"
    ["title"] => string(4) "test"
    ["comment_id"] => string(1) "1"
    ["comment"] => string(15) "第一条评论"
    ["comment_time"] => string(19) "2014-11-22 22:40:01"
  }
  [1] => array(5) {
    ["id"] => string(1) "2"
    ["title"] => string(12) "吼吼吼吼"
    ["comment_id"] => string(1) "2"
    ["comment"] => string(15) "第二条评论"
    ["comment_time"] => string(19) "2014-11-22 22:40:06"
  }
  [2] => array(5) {
    ["id"] => string(1) "4"
    ["title"] => string(7) "test2_m"
    ["comment_id"] => NULL
    ["comment"] => NULL
    ["comment_time"] => NULL
  }
  [3] => array(5) {
    ["id"] => string(1) "5"
    ["title"] => string(2) "22"
    ["comment_id"] => NULL
    ["comment"] => NULL
    ["comment_time"] => NULL
  }
  [4] => array(5) {
    ["id"] => string(1) "6"
    ["title"] => string(1) "1"
    ["comment_id"] => NULL
    ["comment"] => NULL
    ["comment_time"] => NULL
  }
  [5] => array(5) {
    ["id"] => string(1) "7"
    ["title"] => string(6) "lalala"
    ["comment_id"] => NULL
    ["comment"] => NULL
    ["comment_time"] => NULL
  }
}

http://127.0.0.26/index.php/index/relation

此时文章表和评论表的数据为:

评论表:

文章表:

② BELONGS_TO 查询

一条评论数据对应一个用户 id,评论表和用户表之间的关系是 BELONGS_TO

创建自定义模型 CommentModel,继承于RelationModel:

CommentModel.class.php:

<?php
class CommentModel extends RelationModel{

    protected $_link = array(

        ‘user‘=>array(

            "mapping_type"=>BELONGS_TO,
            "foreign_key"=>"comment_user",
            "mapping_fields"=>array("id","username"),
            "as_fields"=>"id:user_id,username",

        ),

    );
}

tpk_user 表结构

数据:

控制器 ArticleModel.class.php:

<?php
class IndexAction extends Action {

    //BELONGS_TO
    public function relation2(){

        $obj=D("Comment");
        $rows=$obj->relation(true)->select();
        dump($rows);
    }

}

访问 http://127.0.0.26/index.php/index/relation2

显示:

array(2) {
  [0] => array(7) {
    ["id"] => string(1) "1"
    ["aid"] => string(1) "1"
    ["comment"] => string(15) "第一条评论"
    ["comment_time"] => string(19) "2014-11-22 22:40:01"
    ["comment_user"] => string(1) "1"
    ["user_id"] => string(1) "1"
    ["username"] => string(3) "dee"
  }
  [1] => array(7) {
    ["id"] => string(1) "2"
    ["aid"] => string(1) "2"
    ["comment"] => string(15) "第二条评论"
    ["comment_time"] => string(19) "2014-11-22 22:40:06"
    ["comment_user"] => string(1) "2"
    ["user_id"] => string(1) "2"
    ["username"] => string(4) "yoko"
  }
}

③ HAS_MANY

一篇文章可以对应多条评论,评论表和文章表之间的关系为 HAS_MANY

此时评论表的数据为:

模型:CommentModel.class.php:

<?php
class CommentModel extends RelationModel{

        //关联模型2 HAS_MANY
        ‘comment‘=>array(

            ‘mapping_type‘=>HAS_MANY,
            ‘foreign_key‘=>"aid",
        ),

}

控制器 ArticleModel.class.php:

<?php
class IndexAction extends Action {

    //HAS_MANY
    public function relation3(){

        $obj=D("Article");
        $rows=$obj->relation(true)->select();
        dump($rows);
    }
}

访问 http://127.0.0.26/index.php/index/relation3

显示:

array(6) {
  [0] => array(8) {
    ["id"] => string(1) "1"
    ["title"] => string(4) "test"
    ["content"] => string(12) "test_content"
    ["category"] => string(13) "test_category"
    ["area"] => string(6) "北京"
    ["add_user"] => string(5) "admin"
    ["add_time"] => string(19) "2014-11-20 23:03:44"
    ["comment"] => array(2) {
      [0] => array(5) {
        ["id"] => string(1) "1"
        ["aid"] => string(1) "1"
        ["comment"] => string(15) "第一条评论"
        ["comment_time"] => string(19) "2014-11-22 22:40:01"
        ["comment_user"] => string(1) "1"
      }
      [1] => array(5) {
        ["id"] => string(1) "2"
        ["aid"] => string(1) "1"
        ["comment"] => string(15) "第二条评论"
        ["comment_time"] => string(19) "2014-11-22 22:40:06"
        ["comment_user"] => string(1) "2"
      }
    }
  }
  [1] => array(8) {
    ["id"] => string(1) "2"
    ["title"] => string(12) "吼吼吼吼"
    ["content"] => string(18) "任溶溶柔然人"
    ["category"] => string(14) "test_category2"
    ["area"] => string(6) "河北"
    ["add_user"] => string(5) "admin"
    ["add_time"] => string(19) "2014-11-22 15:16:12"
    ["comment"] => NULL
  }
  [2] => array(8) {
    ["id"] => string(1) "4"
    ["title"] => string(7) "test2_m"
    ["content"] => string(4) "haha"
    ["category"] => string(0) ""
    ["area"] => string(6) "福建"
    ["add_user"] => NULL
    ["add_time"] => string(19) "2014-11-22 11:44:26"
    ["comment"] => NULL
  }
  [3] => array(8) {
    ["id"] => string(1) "5"
    ["title"] => string(2) "22"
    ["content"] => NULL
    ["category"] => string(0) ""
    ["area"] => string(6) "福建"
    ["add_user"] => NULL
    ["add_time"] => string(19) "2014-11-22 12:40:58"
    ["comment"] => NULL
  }
  [4] => array(8) {
    ["id"] => string(1) "6"
    ["title"] => string(1) "1"
    ["content"] => string(1) "2"
    ["category"] => string(0) ""
    ["area"] => string(6) "福建"
    ["add_user"] => NULL
    ["add_time"] => NULL
    ["comment"] => NULL
  }
  [5] => array(8) {
    ["id"] => string(1) "7"
    ["title"] => string(6) "lalala"
    ["content"] => string(6) "hohoho"
    ["category"] => string(0) ""
    ["area"] => string(6) "北京"
    ["add_user"] => NULL
    ["add_time"] => NULL
    ["comment"] => NULL
  }
}

2.数据操作

以 HAS_MANY 为例,在tpk_article中添加一篇文章,同时 tpk_comment 中添加两条评论。代码:

控制器 ArticleModel.class.php:

    //HAS_MANY 操作,tpk_article中添加一篇文章,同时tpk_comment中添加两条评论
    public function reladd(){

        $obj=D("Article");
        $data[‘title‘]="新闻标题";
        $data[‘content‘]=‘这是一条体育新闻‘;
        $data[‘add_time‘]=date("Y-m-d H:i:s",time());
        //关联的模型
        $data[‘comment‘]=array(
            array("aid"=>20,"comment"=>"体育新闻评论1","comment_time"=>date("Y-m-d H:i:s",time()),"comment_user"=>1),
            array("aid"=>20,"comment"=>"体育新闻评论2","comment_time"=>date("Y-m-d H:i:s",time()),"comment_user"=>1),
        );
        $obj->relation(true)->add($data);
    }

另一个例子,删除文章的同时也删除了评论:

控制器 IndexAction.class.php:

<?php
class IndexAction extends Action {

        //HAS_MANY 删除
    public function reldel(){

        $obj=D("Article");
        $obj->relation(true)->delete(20);
        echo $obj->getLastSql();
    }

}

二、高级模型 ( AdvModel )

高级模型除了可以实现普通模型所有功能之外,还能够实现数据过滤、操作限制、延迟操作等功能。

例子:

定位查询 getN() , first , last

getN(2) :获取结果集正序第 3 条记录

Model 代码:

<?php
class ArticleModel extends AdvModel{

    //....
}

控制器代码:

<?php

class IndexAction extends Action {

        //使用高级模型定位查询
//        $obj=D("Article");
//        $rows=$obj->getN(2);
//        dump($rows);
//        echo $obj->getLastSql();

        //使用高级模型动态查询
//        $obj=D("Article");
//        $rows=$obj->getByArea("北京");
//        dump($rows);
//        echo $obj->getLastSql();

        //使用高级模型动态查询2
//        $obj=D("Article");
//        $rows=$obj->getFieldByArea("北京","id");
//        dump($rows);
//        echo $obj->getLastSql();

        //使用高级模型动态查询3
//        $obj=D("Article");
//        $rows=$obj->top5();
//        dump($rows);
//        echo $obj->getLastSql();
    }
}

参考资料:《PHP MVC 开发实战》

时间: 2024-10-07 05:51:01

ThinkPHP 学习笔记 ( 四 ) 数据库操作之关联模型 ( RelationMondel ) 和高级模型 ( AdvModel )的相关文章

ThinkPHP 学习笔记 ( 三 ) 数据库操作之数据表模型和基础模型 ( Model )

//TP 恶补ing... 一.定义数据表模型 1.模型映射 要测试数据库是否正常连接,最直接的办法就是在当前控制器中实例化数据表,然后使用 dump 函数输出,查看数据库的链接状态.代码: public function testdb(){ $obj=M("User"); dump($obj); } 此时浏览器输出: object(Model)#5 (20) { ["_extModel:private"] => NULL ["db:protecte

Symfony2学习笔记之数据库操作

数据库和Doctrine让我们来面对这个对于任何应用程序来说最为普遍最具挑战性的任务,从数据库中读取和持久化数据信息.幸运的是,Symfony和Doctrine进行了集成,Doctrine类库全部目标就是给你一个强大的工具,让你的工作更加容易. Doctrine是完全解耦与Symfony的,所以并不一定要使用它. 一个简单例子:一个产品,我们首先来配置数据库,创建一个Product对象,持久化它到数据库并把它读回来. 首先我们需要创建一个bundle: $php app/console gene

thinkphp学习笔记4—眼花缭乱的配置

1.配置类别 ThinkPHP提供了灵活的全局配置功能,ThinkPHP会依次加载管理配置>项目配置>调试配置>分组配置>扩展配置>动态配置,所以后面的配置权限要大于前面的,因为后面的配置会覆盖前面同名配置,同事会生辰配置缓存文件无需重复解析,减小开销. 惯例配置:在惯例配置内对大多数常用参数进行默认配置,因为惯例配置最先加载,优先级别最低,如果不需要做特殊配置的话,完全可以保持默认值,惯例配置位于ThinkPHP/Conf/convention.php,内容摘抄如下: &l

ThinkPHP学习笔记 事务处理

事务处理是数据库数据处理中经常用到的一个功能,特别是商务之类的应用,比如a给b打了钱,数据库中a的钱数应该减少,b的钱数应该增加, 若a数据操作成功,而b的数据因某些原因操作失败,这时数据就会有问题.这种相关的系列操作需要进行事务处理. 事务是DBMS得执行单位.一般来说,事务是必须满足4个条件(ACID): 1.  原子性(Autmic):        事务在执行性,要做到"要么不做,要么全做!",不允许事务部分执行. 2.  一致性(Consistency): 事务得操作应该使使

Linux学习笔记四:Linux的文件搜索命令

1.文件搜索命令  which 语法:which [命令名称] 范例:$which ls  列出ls命令所在目录 [[email protected] ~]$ which ls alias ls='ls --color=auto' /bin/ls 另外一个命令:whereis [名称名称],也可以列出命令所在目录. [[email protected] ~]$ whereis ls ls: /bin/ls /usr/share/man/man1/ls.1.gz /usr/share/man/ma

Thinkphp学习笔记------- RBAC

1.首先去extends扩展包里找到RBAC类 2.复制里面创建四张表的SQL语句放到mysql里执行,得到四张表. 3.需要自己创建一个user表,字段随意,一般是username password之类存储用户登录信息. 4.RBAC一般就是六个方法:依次为-->用户列表   角色列表   节点列表  添加用户  添加角色  添加节点 5.操作顺序是-->添加角色-->添加节点-->给角色分配节点-->添加用户-->给用户指定角色 6.对角色表(role)进行添加和L

thinkphp学习笔记5—模块化设计

1.模块结构 完整的ThinkPHP用用围绕模块/控制器/操作设计,并支持多个入口文件盒多级控制.ThinkPHP默认PATHINFO模式,如下: http://serverName/index.php(或者其他应用入口文件)/模块/控制器/操作/[参数名/参数值...] 应用:由同一个入口文件访问的项目称为一个应用,在完整版的代码中就是Application 模块:一个应用下面可以包含多个模块,每个模块对应独立的目录,在完整版的代码中有Admin,Home,Common,Runtime四个模块

thinkphp学习笔记10—看不懂的路由规则

路由这部分貌似在实际工作中没有怎么设计过,只是在用默认的设置,在手册里面看到部分,艰涩难懂. 1.路由定义 要使用路由功能需要支持PATH_INFO,PATH_INFO是什么呢?手册中提到“要使用路由功能,前提是你的URL支持PATH_INFO(或者兼容URL模式也可以,采用普通URL模式的情况下不支持路由功能),” , url支持path_info,不是apache要支持path_info么,度娘讲的还算清楚一点,见下文: pathinfo(PHP 4 >= 4.0.3, PHP 5)path

thinkphp学习笔记6—url模式

原文:thinkphp学习笔记6-url模式 入口文件是应用的唯一入口,因为可以多入口,每个应用可以对应一个入口文件,系统会从rul参数中解析当前请求的模块,控制器,操作.ThinkPHP是区分大小写的,考虑到linux是区分大小写的,所以在ThinkPHP中模块,控制器,模型等都是区分大小写的,并且使用驼峰命名规则. 如果我们直接访问入口文件index.php,url中没有给出模块,控制器,操作,系统会默认访问Home模块下的Index控制器下的index操作,因此下面的两种访问方法得到的结果