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中设置多级目录session的问题
Aug 08 PHP
使用Apache的htaccess防止图片被盗链的解决方法
Apr 27 PHP
探讨PHP中this,self,parent的区别详解
Jun 08 PHP
ThinkPHP CURD方法之order方法详解
Jun 18 PHP
php实现简单文件下载的方法
Jan 30 PHP
php将HTML表格每行每列转为数组实现采集表格数据的方法
Apr 03 PHP
php开发微信支付获取用户地址
Oct 04 PHP
PHP简单预防sql注入的方法
Sep 27 PHP
PHP中overload与override的区别
Feb 13 PHP
PHP实现深度优先搜索算法(DFS,Depth First Search)详解
Sep 16 PHP
PHP一个简单的无需刷新爬虫
Jan 05 PHP
Laravel配合jwt使用的方法实例
Oct 25 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获取本周,上周,本月,上月,本季度日期的代码
2009/08/05 PHP
php错误级别的设置方法
2013/06/17 PHP
Nigma vs Alliance BO5 第四场2.14
2021/03/10 DOTA
jquery.tmpl JQuery模板插件
2011/10/10 Javascript
基于JQuery实现的Select级联
2014/01/27 Javascript
解决node-webkit 不支持html5播放mp4视频的方法
2015/03/11 Javascript
JavaScript实现弹出DIV层同时页面背景渐变成半透明效果
2016/03/25 Javascript
Vue.js报错Failed to resolve filter问题的解决方法
2016/05/25 Javascript
Javascript 引擎工作机制详解
2016/11/30 Javascript
Bootstrap Scrollspy源码学习
2017/03/02 Javascript
vue.js评论发布信息可插入QQ表情功能
2017/08/08 Javascript
AngularJS 购物车全选/取消全选功能的实现方法
2017/08/14 Javascript
nodejs 图片预览和上传的示例代码
2017/09/30 NodeJs
微信小程序实现点击按钮修改view标签背景颜色功能示例【附demo源码下载】
2017/12/06 Javascript
通过javascript实现段落的收缩与展开
2019/06/26 Javascript
在博客园博文中添加自定义右键菜单的方法详解
2020/02/05 Javascript
vue-router为激活的路由设置样式操作
2020/07/18 Javascript
Vue通过阿里云oss的url连接直接下载文件并修改文件名的方法
2020/12/25 Vue.js
[16:01]夜魇凡尔赛茶话会 第二期01:你比划我猜
2021/03/11 DOTA
纯Python开发的nosql数据库CodernityDB介绍和使用实例
2014/10/23 Python
Python环境变量设置方法
2016/08/28 Python
Python整型运算之布尔型、标准整型、长整型操作示例
2017/07/21 Python
对Python+opencv将图片生成视频的实例详解
2019/01/08 Python
使用python-Jenkins批量创建及修改jobs操作
2020/05/12 Python
使用phonegap操作数据库的实现方法
2017/03/31 HTML / CSS
意大利会呼吸的鞋:Geox健乐士
2017/02/12 全球购物
金牌葡萄酒俱乐部:Gold Medal Wine Club
2017/11/02 全球购物
文言文形式的学生求职信
2013/12/03 职场文书
直接有效的自我评价
2014/01/11 职场文书
幸福家庭事迹材料
2014/02/03 职场文书
医药营销个人求职信范文
2014/02/07 职场文书
活动倡议书范文
2014/05/13 职场文书
法院信息化建设方案
2014/05/21 职场文书
民主生活会对照检查材料范文
2014/10/01 职场文书
长江七号观后感
2015/06/11 职场文书
解析Redis Cluster原理
2021/06/21 Redis