ThinkPHP视图查询详解


Posted in PHP onJune 30, 2014

ThinkPHP提供的视图查询应用功能十分强大,用户利用视图查询功能可以将多个数据表的字段内容按需要进行指定和筛选,组织成一个基于这些数据表的视图模型,然后就可以通过该模型直接进行多表联合查询,非常方便和简单。

例如在项目中,我们定义有三个表:

user          用户基础表,
user_info   用户详细信息表,
dept          部门分类表

现在我们需要获取某个用户信息,
该信息要包括用户的帐号名称和相关资料与及所在部门的名称,
这时候我们可以利用视图查询进行处理。

下面举例加以说明:

1.构建一个新项目并进行相关配置(可参考前面的教程,这里省略)
2.创建一个数据库tpview,并添加这三个表
(1) 用户表

CREATE TABLE `think_user` (
 `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID编号',
 `name` varchar(20) NOT NULL COMMENT '帐户',
 `password` varchar(32) NOT NULL COMMENT '密码',
 `dept_id` smallint(6) unsigned NOT NULL,
 `status` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT '开放状态',
 PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='会员表' AUTO_INCREMENT=2 ;
INSERT INTO `think_user` (`id`, `name`, `password`, `dept_id`, `status`) VALUES
(1, 'zzguo28', '123456', 2, 1);

(2)用户信息表

CREATE TABLE `think_user_info` (
 `user_id` int(11) NOT NULL COMMENT '用户id',
 `nick_name` varchar(30) NOT NULL COMMENT '用户昵称',
 `email` varchar(100) NOT NULL COMMENT '邮箱地址',
 `address` varchar(100) NOT NULL COMMENT '详细地址',
 `gender` tinyint(1) NOT NULL DEFAULT '0' COMMENT '性别',
 `mobile` varchar(100) NOT NULL COMMENT '手机号码',
 `telephone` varchar(100) NOT NULL COMMENT '电话号码',
 KEY `user_id` (`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='用户信息表';
INSERT INTO `think_user_info` (`user_id`, `nick_name`, `email`, `address`, `gender`, `mobile`, `telephone`) VALUES
(1, '国', 'zzguo28@163.com', 'TP路think街1.6号', 1, '12345678901', '123456');

(3) 部门分类表

CREATE TABLE `think_dept` (
 `id` smallint(3) NOT NULL AUTO_INCREMENT,
 `name` varchar(50) NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;
INSERT INTO `think_dept` (`id`, `name`) VALUES
(1, '开发部'),
(2, '销售部'),
(3, '财务部');

3.在项目/Lib/Model下创建这三个表的基础模型Model
  本示例没涉及到验证等其它功能,所以只要简单定义测可,例如

<?php
  class UserModel extends Model {
  }
 ?>

其实视图模型对应的数据表并非一定要有相应的的基础模型,但是建议您创建,这样单表和视图都可以操作。

4.创建视图模型,代码如下,详细注解见其后:

(附注:最新svn上已增加动态扩展模型功能,使用新版需要将protected属性改为public属性,建议使用动态扩展功能去使用视图查询,而不再是本教程的继承方式。那样使用会更灵活。)

<?php
import('ViewModel');
class UserViewModel extends ViewModel{
  protected $viewFields = array(
    'User'   =>array('id','name','_as'=>'u','_type'=>'left'),
    'UserInfo' =>array('email','mobile','_as'=>'ui','_on'=>'ui.user_id=u.id'),
    'Dept'   =>array('name'=>'dept','_on'=>'u.dept_id=Dept.id'),
  );
}
?>

对上述代码解释如下:

在第2行代码中,由于自TP1.6版开始已将视图查询分离出原Model类,因此这里需要使用import方法引入了视图模型类。

第3行代码中,定义了该模型名称为UserViewModel,视图模型的名称Model前的命名是随意的,只是为了有别于其它模型,通常我们会以xxxViewModel这样的方式去命名。并且一定要继承ViewModel。(ThinkPHP1.6版无需再设置模型的viewModel属性为true,只要继承ViewModel则可)

第4行代码$viewFields 属性表示视图模型包含的字段,每个元素定义了各个数据表或者模型所需的字段。
格式是

protected $viewFields = array(
    '表名'=>array('所需字段','_as'=>'别名定义','_on'=>'筛选条件','_type'=>'指定join类型,支持right,inner,left三种'),
);

注意到第7行代码中的'name'=>'dept',因为User模型里面已经存在了一个name字段,所以我们通过这种方式把Dept模型的name字段映射为dept字段,如果有多个字段,可以使用同样的方式添加。

定义完毕后,我们在Action中进行测试,代码如下

<?php
class IndexAction extends Action{
  public function index(){
    $dao = D('UserView');
    $where['u.id'] = 1;
    dump($dao->where($where)->find());
    dump($dao->getLastSql());
  }
}
?>

然后访问该操作,可以看到我们成功取得所需的查询内容:

array(1) {
 [0] => array(5) {
  ["id"] => string(1) "1"
  ["name"] => string(7) "zzguo28"
  ["email"] => string(17) "zzguo28@163.com"
  ["mobile"] => string(11) "12345678901"
  ["dept"] => string(9) "销售部"
 }
}

并可以看到使用的sql如下

"SELECT u.id AS id,u.name AS name,ui.email AS email,ui.mobile AS mobile,Dept.name AS dept FROM think_user u LEFT JOIN think_user_info ui ON ui.user_id=u.id JOIN think_dept Dept ON u.dept_id=Dept.id WHERE ( u.id = 1 ) LIMIT 1 "

视图模型在查询上和普通单表并没有多大分别,可以使用我们所熟悉的各种连贯操作,例如order,limit等等。

PHP 相关文章推荐
生成静态页面的PHP类
Jul 15 PHP
php 分库分表hash算法
Nov 12 PHP
php将会员数据导入到ucenter的代码
Jul 18 PHP
如何在smarty中增加类似foreach的功能自动加载数据
Jun 26 PHP
php调整服务器时间的方法
Apr 03 PHP
PHP中filter函数校验数据的方法详解
Jul 31 PHP
PHP Static延迟静态绑定用法分析
Mar 16 PHP
PHP7.1实现的AES与RSA加密操作示例
Jun 15 PHP
PHP通过调用新浪API生成t.cn格式短网址链接的方法详解
Feb 20 PHP
PHP实现单文件、多个单文件、多文件上传函数的封装示例
Sep 02 PHP
php文件后缀不强制为.php的实操方法
Sep 18 PHP
详解PHP用mb_string处理windows中文字符
May 26 PHP
php中eval函数的危害与正确禁用方法
Jun 30 #PHP
PHP登录环节防止sql注入的方法浅析
Jun 30 #PHP
PHP获取时间排除周六、周日的两个方法
Jun 30 #PHP
PHP网页游戏学习之Xnova(ogame)源码解读(十六)
Jun 30 #PHP
PHP网页游戏学习之Xnova(ogame)源码解读(十五)
Jun 30 #PHP
解析PHP强制转换类型及远程管理插件的安全隐患
Jun 30 #PHP
PHP数字和字符串ID互转函数(类似优酷ID)
Jun 30 #PHP
You might like
整理的9个实用的PHP库简介和下载
2010/11/09 PHP
PHP几个数学计算的内部函数学习整理
2011/08/06 PHP
php 伪静态之IIS篇
2014/06/02 PHP
yii中widget的用法
2014/12/03 PHP
Laravel使用支付宝进行支付的示例代码
2017/08/16 PHP
Nginx实现反向代理
2017/09/20 Servers
PHP7新功能总结
2019/04/14 PHP
PHP7导出Excel报ERR_EMPTY_RESPONSE解决方法
2019/04/16 PHP
javascript读取RSS数据
2007/01/20 Javascript
Javascript技术技巧大全(五)
2007/01/22 Javascript
JavaScript 继承详解(二)
2009/07/13 Javascript
使用jQuery简化Ajax开发 Ajax开发入门
2009/10/14 Javascript
高性能JavaScript 重排与重绘(2)
2015/08/11 Javascript
如何判断出一个js对象是否一个dom对象
2016/11/24 Javascript
js实现简单的网页换肤效果
2017/01/18 Javascript
微信小程序实战之登录页面制作(5)
2020/03/30 Javascript
用JavaScript做简易的购物车的代码示例
2017/10/20 Javascript
解决vue select当前value没有更新到vue对象属性的问题
2018/08/30 Javascript
基于javascript的拖拽类封装详解
2019/04/19 Javascript
详解vue-template-admin三级路由无法缓存的解决方案
2020/03/10 Javascript
Python实现矩阵加法和乘法的方法分析
2017/12/19 Python
利用Python写一个爬妹子的爬虫
2018/06/08 Python
使用numpy和PIL进行简单的图像处理方法
2018/07/02 Python
Django框架文件上传与自定义图片上传路径、上传文件名操作分析
2019/05/10 Python
解析python的局部变量和全局变量
2019/08/15 Python
PyCharm 2019.3发布增加了新功能一览
2019/12/08 Python
日本航空官方网站:JAL
2019/06/19 全球购物
文化活动实施方案
2014/03/28 职场文书
三月学雷锋月活动总结
2014/04/28 职场文书
力学专业求职信
2014/07/23 职场文书
农行心得体会
2014/09/02 职场文书
2014年国庆节庆祝建国65周年比赛演讲稿
2014/09/21 职场文书
求职信范文怎么写
2015/03/19 职场文书
教师思想工作总结2015
2015/05/13 职场文书
python 爬取豆瓣网页的示例
2021/04/13 Python
Redis延迟队列和分布式延迟队列的简答实现
2021/05/13 Redis