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 相关文章推荐
linux下 C语言对 php 扩展
Dec 14 PHP
PHP面向对象学习笔记之一 基础概念
Oct 06 PHP
php页面缓存ob系列函数介绍
Oct 18 PHP
使用 PHPMAILER 发送邮件实例应用
Nov 07 PHP
PHP应用JSON技巧讲解
Feb 03 PHP
使用Smarty 获取当前日期时间和格式化日期时间的方法详解
Jun 18 PHP
使用HMAC-SHA1签名方法详解
Jun 26 PHP
php实现获取局域网所有用户的电脑IP和主机名、及mac地址完整实例
Jul 18 PHP
Thinkphp实现站点静态化的方法详解
Mar 21 PHP
php封装db类连接sqlite3数据库的方法实例
Dec 19 PHP
PHP设计模式之状态模式定义与用法详解
Apr 02 PHP
阿里云服务器搭建Php+Apache运行环境的详细过程
May 15 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
如何用phpmyadmin设置mysql数据库用户的权限
2012/01/09 PHP
ubuntu下配置nginx+php+mysql详解
2015/09/10 PHP
yii2 RBAC使用DbManager实现后台权限判断的方法
2016/07/23 PHP
php通过会话控制实现身份验证实例
2016/10/18 PHP
任意位置显示html菜单
2007/02/01 Javascript
JavaScript之Getters和Setters 平台支持等详细介绍
2012/12/07 Javascript
jquery实现简单的拖拽效果实例兼容所有主流浏览器
2013/06/21 Javascript
如何在父窗口中得知window.open()出的子窗口关闭事件
2013/10/15 Javascript
Jqgrid表格随窗口大小改变而改变的简单实例
2013/12/28 Javascript
用Node.js通过sitemap.xml批量抓取美女图片
2015/05/28 Javascript
js实现仿微博滚动显示信息的效果
2015/12/21 Javascript
Node.js项目中调用JavaScript的EJS模板库的方法
2016/03/11 Javascript
Javascript 普通函数和构造函数的区别
2016/11/05 Javascript
js array数组对象操作方法汇总
2019/03/18 Javascript
微信小程序自定义多列选择器使用详解
2019/06/21 Javascript
JS数组方法reduce的用法实例分析
2020/03/03 Javascript
微信小程序实现登录注册功能
2020/12/29 Javascript
Python实现递归遍历文件夹并删除文件
2016/04/18 Python
Python中selenium实现文件上传所有方法整理总结
2017/04/01 Python
Django ORM多对多查询方法(自定义第三张表&amp;ManyToManyField)
2019/08/09 Python
python base64库给用户名或密码加密的流程
2020/01/02 Python
python读取tif图片时保留其16bit的编码格式实例
2020/01/13 Python
使用Python求解带约束的最优化问题详解
2020/02/11 Python
python GUI编程(Tkinter) 创建子窗口及在窗口上用图片绘图实例
2020/03/04 Python
基于python3.7利用Motor来异步读写Mongodb提高效率(推荐)
2020/04/29 Python
Python使用socketServer包搭建简易服务器过程详解
2020/06/12 Python
Python getattr()函数使用方法代码实例
2020/08/10 Python
Mio Skincare英国官网:身体紧致及孕期身体护理
2018/08/19 全球购物
技术副厂长岗位职责
2013/12/26 职场文书
任命书范本大全
2014/06/06 职场文书
国企干部对照检查材料
2014/08/22 职场文书
公司授权委托书格式样本
2014/10/01 职场文书
道歉信范文
2015/05/12 职场文书
拔河比赛队名及霸气口号
2015/12/24 职场文书
干部理论学习心得体会
2016/01/21 职场文书
Vue3.0写自定义指令的简单步骤记录
2021/06/27 Vue.js