视图定义

视图通常是指数据库的视图,视图是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含一系列带有名称的列和行数据。但是,视图并不在数据库中以存储的数据值集形式存在。行和列数据来自由定义视图的查询所引用的表,并且在引用视图时动态生成。对其中所引用的基础表来说,视图的作用类似于筛选。定义视图的筛选可以来自当前或其它数据库的一个或多个表,或者其它视图。分布式查询也可用于定义使用多个异类源数据的视图。如果有几台不同的服务器分别存储组织中不同地区的数据,而您需要将这些服务器上相似结构的数据组合起来,这种方式就很有用。 视图在有些数据库下面并不被支持,但是ThinkPHP模拟实现了数据库的视图,该功能可以用于多表联合查询。非常适合解决HAS_ONE 和 BELONGS_TO 类型的关联查询。

要定义视图模型,只需要继承Think\Model\ViewModel,然后设置viewFields属性即可。

大理石平台规格

例如下面的例子,我们定义了一个BlogView模型对象,其中包括了Blog模型的id、name、title和User模型的name,以及Category模型的title字段,我们通过创建BlogView模型来快速读取一个包含了User名称和类别名称的Blog记录(集)。

  1. namespace Home\Model;
  2. use Think\Model\ViewModel;
  3. class BlogViewModel extends ViewModel {
  4. public $viewFields = array(
  5. 'Blog'=>array('id','name','title'),
  6. 'Category'=>array('title'=>'category_name', '_on'=>'Blog.category_id=Category.id'),
  7. 'User'=>array('name'=>'username', '_on'=>'Blog.user_id=User.id'),
  8. );
  9. }

我们来解释一下定义的格式代表了什么。

$viewFields 属性表示视图模型包含的字段,每个元素定义了某个数据表或者模型的字段。

例如:

  1. 'Blog'=>array('id','name','title');

表示BlogView视图模型要包含Blog模型中的id、name和title字段属性,这个其实很容易理解,就和数据库的视图要包含某个数据表的字段一样。而Blog相当于是给Blog模型对应的数据表定义了一个别名。

默认情况下会根据定义的名称自动获取表名,如果希望指定数据表,可以使用:

  1. '_table'=>"test_user"
  2. // 3.2.2版本以上还可以使用简化定义(自动获取表前缀)
  3. '_table'=>"__USER__"

如果希望给当前数据表定义另外的别名,可以使用

  1. '_as'=>'myBlog'

BlogView视图模式除了包含Blog模型之外,还包含了Category和User模型,下面的定义:

  1. 'Category'=>array('title'=>'category_name');

和上面类似,表示BlogView视图模型还要包含Category模型的title字段,因为视图模型里面已经存在了一个title字段,所以我们通过

  1. 'title'=>'category_name'

把Category模型的title字段映射为category_name字段,如果有多个字段,可以使用同样的方式添加。

可以通过_on来给视图模型定义关联查询条件,例如:

  1. '_on'=>'Blog.category_id=Category.id'

理解之后,User模型的定义方式同样也就很容易理解了。

  1. Blog.categoryId=Category.id AND Blog.userId=User.id

最后,我们把视图模型的定义翻译成SQL语句就更加容易理解视图模型的原理了。假设我们不带任何其他条件查询全部的字段,那么查询的SQL语句就是

  1. Select
  2. Blog.id as id,
  3. Blog.name as name,
  4. Blog.title as title,
  5. Category.title as category_name,
  6. User.name as username
  7. from think_blog Blog JOIN think_category Category JOIN think_user User
  8. where Blog.category_id=Category.id AND Blog.user_id=User.id

视图模型的定义并不需要先单独定义其中的模型类,系统会默认按照系统的规则进行数据表的定位。如果Blog模型并没有定义,那么系统会自动根据当前模型的表前缀和后缀来自动获取对应的数据表。也就是说,如果我们并没有定义Blog模型类,那么上面的定义后,系统在进行视图模型的操作的时候会根据Blog这个名称和当前的表前缀设置(假设为Think_ )获取到对应的数据表可能是think_blog。

ThinkPHP还可以支持视图模型的JOIN类型定义,我们可以把上面的视图定义改成:

  1. public $viewFields = array(
  2. 'Blog'=>array('id','name','title','_type'=>'LEFT'),
  3. 'Category'=>array('title'=>'category_name','_on'=>'Category.id=Blog.category_id','_type'=>'RIGHT'),
  4. 'User'=>array('name'=>'username','_on'=>'User.id=Blog.user_id'),
  5. );

需要注意的是,这里的_type定义对下一个表有效,因此要注意视图模型的定义顺序。Blog模型的

  1. '_type'=>'LEFT'

针对的是下一个模型Category而言,通过上面的定义,我们在查询的时候最终生成的SQL语句就变成:

  1. Select
  2. Blog.id as id,
  3. Blog.name as name,
  4. Blog.title as title,
  5. Category.title as category_name,
  6. User.name as username
  7. from think_blog Blog LEFT JOIN think_category Category ON Blog.category_id=Category.id RIGHT JOIN think_user User ON Blog.user_id=User.id
复制代码

 

我们可以在试图模型里面定义特殊的字段,例如下面的例子定义了一个统计字段

  1. 'Category'=>array('title'=>'category_name','COUNT(Blog.id)'=>'count','_on'=>'Category.id=Blog.category_id'),

视图查询

接下来,我们就可以和使用普通模型一样对视图模型进行操作了 。

  1. $Model = D("BlogView");
  2. $Model->field('id,name,title,category_name,username')->where('id>10')->order('id desc')->select();

看起来和普通的模型操作并没有什么大的区别,可以和使用普通模型一样进行查询。如果发现查询的结果存在重复数据,还可以使用group方法来处理。

  1. $Model->field('id,name,title,category_name,username')->order('id desc')->group('id')->select();

我们可以看到,即使不定义视图模型,其实我们也可以通过方法来操作,但是显然非常繁琐。

  1. $Model = D("Blog");
  2. $Model->table('think_blog Blog,think_category Category,think_user User')
  3. ->field('Blog.id,Blog.name,Blog.title,Category.title as category_name,User.name as username')
  4. ->order('Blog.id desc')
  5. ->where('Blog.category_id=Category.id AND Blog.user_id=User.id')
  6. ->select();

而定义了视图模型之后,所有的字段会进行自动处理,添加表别名和字段别名,从而简化了原来视图的复杂查询。如果不使用视图模型,也可以用连贯操作的JOIN方法实现相同的功能。

 

thinkphp 视图定义的更多相关文章

  1. ThinkPHP视图查询详解

    ThinkPHP视图查询详解 参考http://www.jb51.net/article/51674.htm   这篇文章主要介绍了ThinkPHP视图查询,需要的朋友可以参考下     ThinkP ...

  2. 由于物化视图定义为on commit导致update更新基表慢的解决方案

    由于物化视图定义为on commit导致update更新基表慢的解决方案 以下是模拟和解决测试过程: (模拟update慢的过程) 1.首先基于基表创建物化视图日志: create materiali ...

  3. mysql视图定义、原理、创建、使用

    定义: 视图是一个虚拟表,其内容由查询定义.同真实的表一样,视图包含一系列带有名称的列和行数据.但是视图并不在数据库中以存储的数据值集形式存在.行和列数据来自由定义视图的查询所引用的表,并在引用视图时 ...

  4. SQL Server查看视图定义总结

      在SQL Server中如何查看数据库视图的定义呢? 其实官方文档已经有一个较详细的总结了,这里在官方文档的基础上,我们再深入展开分析一下,例如如何获取系统视图的定义.知其然知其所以然吗. 1:使 ...

  5. 获取物化视图定义语句的SQL

    老系统里总有人用物化视图,然后新同事们就得去FixBug 然后就遇到怎么查看物化视图定义语句的问题了 分享下,祝顺利! DBA权限下执行: select dbms_metadata.get_ddl(' ...

  6. 第6章—渲染web视图—使用Apache Tiles视图定义布局

    使用Apache Tiles视图定义布局   Tiles是一个免费的开源模板Java应用程序的框架.基于复合模式简化的用户界面的构建.对于复杂的网站仍是最简单.最优雅的方式与任何MVC技术一起工作.S ...

  7. ThinkPHP视图查询

    ThinkPHP视图查询 一.总结 1.这里的视图查询和多表查询很像,当然多表查询的话肯定要支持左右链接查询 2.view:视图的使用,关键字是view 3.sql视图功能支持:thinkphp支持视 ...

  8. 【SQL server基础】SQL视图加密,永久隐藏视图定义的文本

    SQL可以对视图进行加密.也就是,可永久隐藏视图定义的文本. 注意   此操作不可逆.加密视图后,无法再修改它,因为无法再看到视图定义.如果需要修改加密视图,则必须删除它并重新创建另一个视图. 示例代 ...

  9. thinkphp 视图(二)变量输出、赋值和替换

    view下的html文件会编译成php文件 编译的文件在runtime 下的temp目录 <p>{$email}</p> 会编译成 <?php echo $email; ...

随机推荐

  1. iOS开发静态库冲突——如何查看静态库(.O)中方法名

    1.bug产生 应用第三方静态库之后提示冲突错误: 2.bug分析 一般会提示哪两个库冲突: CameraShowGLView.o是自己创建的类编译生成的: libLechangeSDK.a是添加的静 ...

  2. 2018北京网络赛 G The Mole /// 分块暴力 点线距离

    题目大意: 给定n段线段 编号为1~n 接下来m个询问 给定一点 输出离该点最近的线段的最小编号(距离相等时取编号小的) 题解 大致就是 1.坐标范围为(0,2^16-1) 将坐标系划分为2^8*2^ ...

  3. 【python】并集交集

    set是用来去重的. 在list里使用union函数.这种方式不适用于元素为字典的. list(set(a)^set(b)) 这是求差集 所以交集就是并集和ab的差集. import random d ...

  4. 更改idea启动内存信息

    1.到idea的安装目录的bin下,找idea64.exe.vmoptions 文件 2.更改参数 对应的参数解释: -Xms1024m    设置IDEA初时的内存大小,提高Java程序的启动速度. ...

  5. 2019-8-31-C#-通过编程的方法在桌面创建回收站快捷方式

    title author date CreateTime categories C# 通过编程的方法在桌面创建回收站快捷方式 lindexi 2019-08-31 16:55:58 +0800 201 ...

  6. 在 Mac 上使用 `sed` 命令的几个坑

    不可忽略的备份格式 sed -i 's/hello/world/g' hello.text 上面这行代码,可以在 linux 上运行,作用是将找到的 hello 替换为 world,并且直接保存修改到 ...

  7. JS对象 四舍五入round() round() 方法可把一个数字四舍五入为最接近的整数。 语法: Math.round(x)

    四舍五入round() round() 方法可把一个数字四舍五入为最接近的整数. 语法: Math.round(x) 参数说明: 注意: 1. 返回与 x 最接近的整数. 2. 对于 0.5,该方法将 ...

  8. JS对象 String 字符串对象定义字符串的方法就是直接赋值。比如: var mystr = "I love JavaScript!"

    String 字符串对象 在之前的学习中已经使用字符串对象了,定义字符串的方法就是直接赋值.比如: var mystr = "I love JavaScript!" 定义mystr ...

  9. Bugs Integrated, Inc.

    Bugs Integrated, Inc. 给出一个\(n\times m\)的矩形网格图,给出其中K个障碍物的位置,求其中最多能摆的\(2\times 3\)的矩形的个数,\(n\leq 150,m ...

  10. layui实现已知被选中的option,怎样渲染

    在项目中用到layui实现第几个option 实现,在select中渲染出需要展示的option 代码: $("#period option[value="+res.data.se ...