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 04 PHP
PHP中exec函数和shell_exec函数的区别
Aug 20 PHP
php中time()与$_SERVER[REQUEST_TIME]用法区别
Nov 19 PHP
php修改上传图片尺寸的方法
Apr 14 PHP
PHP配置把错误日志以邮件方式发送方法(Windows系统)
Jun 23 PHP
postfixadmin忘记密码后的修改密码方法详解
Jul 20 PHP
php set_include_path函数设置 include_path 配置选项
Oct 30 PHP
PHP插件PHPMailer发送邮件功能
Feb 28 PHP
浅谈PHP中类和对象的相关函数
Apr 26 PHP
PHP删除数组中指定值的元素常用方法实例分析【4种方法】
Aug 21 PHP
php使用array_chunk函数将一个数组分割成多个数组
Dec 05 PHP
PHP利用pdo_odbc实现连接数据库示例【基于ThinkPHP5.1搭建的项目】
May 13 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
php通过asort()给关联数组按照值排序的方法
2015/03/18 PHP
PHP使用array_fill定义多维数组的方法
2015/03/18 PHP
php基于自定义函数记录log日志方法
2017/07/21 PHP
PHP 加密 Password Hashing API基础知识点
2020/03/02 PHP
JQuery 简便实现页面元素数据验证功能
2007/03/24 Javascript
js两行代码按指定格式输出日期时间
2011/10/21 Javascript
JavaScript常用的弹出广告及背投广告实现方法
2015/02/06 Javascript
jQuery制作可自定义大小的拼图游戏
2015/03/30 Javascript
JQuery为元素添加样式的实现方法
2016/07/20 Javascript
分类解析jQuery选择器
2016/11/23 Javascript
AngularJS自定义服务与fliter的混合使用
2016/11/24 Javascript
jquery与ajax获取特殊字符实例详解
2017/01/08 Javascript
微信小程序表单验证form提交错误提示效果
2020/06/19 Javascript
node.js的http.createServer过程深入解析
2019/06/06 Javascript
微信小程序基于Taro的分享图片功能实践详解
2019/07/12 Javascript
详解简单易懂的 ES6 Iterators 指南和示例
2019/09/24 Javascript
layer.open 获取不到表单信息的解决方法
2019/09/26 Javascript
three.js利用射线Raycaster进行碰撞检测
2020/03/12 Javascript
Node.js文本文件BOM头的去除方法
2020/11/22 Javascript
[01:54]TI珍贵瞬间系列(五):压力
2020/08/29 DOTA
[35:39]完美世界DOTA2联赛PWL S2 FTD.C vs Rebirth 第二场 11.22
2020/11/24 DOTA
[22:07]DOTA2-DPC中国联赛 正赛 iG vs Magma 选手采访
2021/03/11 DOTA
python实现的系统实用log类实例
2015/06/30 Python
Python语言实现百度语音识别API的使用实例
2017/12/13 Python
Django中的Signal代码详解
2018/02/05 Python
Python堆排序原理与实现方法详解
2018/05/11 Python
python 匹配url中是否存在IP地址的方法
2018/06/04 Python
使用python批量化音乐文件格式转换的实例
2019/01/09 Python
python绘制雪景图
2019/12/16 Python
python中的列表和元组区别分析
2020/12/30 Python
int和Integer有什么区别
2013/05/25 面试题
小学新学期教师寄语
2014/01/18 职场文书
交通安全主题班会
2015/08/12 职场文书
Alexa停服!网站排名将何去何从?目前还没有替代品。
2022/04/15 杂记
Win11 Beta 预览版 22621.575 和 22622.575更新补丁KB5016694发布(附更新内容大全)
2022/08/14 数码科技
Redis实战之Lettuce的使用技巧详解
2022/12/24 Redis