视图查询

视图查询可以实现不依赖数据库视图的多表查询,并不需要数据库支持视图,例如:

Db::view('User','id,name')
->view('Profile','truename,phone,email','Profile.user_id=User.id')
->view('Score','score','Score.user_id=Profile.id')
->where('score','>',80)
->select();

生成的SQL语句类似于:

SELECT User.id,User.name,Profile.truename,Profile.phone,Profile.email,Score.score 
FROM think_user User
INNER JOIN think_profile Profile ON Profile.user_id=User.id
INNER JOIN think_socre Score ON Score.user_id=Profile.id
WHERE Score.score > 80

  注意,视图查询无需调用 table 和 join 方法,并且在调用 where 和 order 方法的时候只需要使用字段名而不需要加表名。

默认使用INNER join查询,如果需要更改,可以使用:

Db::view('User','id,name')
->view('Profile','truename,phone,email','Profile.user_id=User.id','LEFT')
->view('Score','score','Score.user_id=Profile.id','RIGHT')
->where('score','>',80)
->select();

生成的SQL语句类似于:

SELECT User.id,User.name,Profile.truename,Profile.phone,Profile.email,Score.score 
FROM think_user User
LEFT JOIN think_profile Profile ON Profile.user_id=User.id
RIGHT JOIN think_socre Score ON Score.user_id=Profile.id
WHERE Score.score > 80

可以使用别名:

Db::view('User',['id'=>'uid','name'=>'account'])
->view('Profile','truename,phone,email','Profile.user_id=User.id')
->view('Score','score','Score.user_id=Profile.id')
->where('score','>',80)
->select();

生成的SQL语句变成:

SELECT User.id AS uid,User.name AS account,Profile.truename,Profile.phone,Profile.email,Score.score 
FROM think_user User
INNER JOIN think_profile Profile ON Profile.user_id=User.id
INNER JOIN think_socre Score ON Score.user_id=Profile.id
WHERE Score.score > 80

可以使用数组的方式定义表名以及别名,例如:

Db::view(['think_user'=>'member'],['id'=>'uid','name'=>'account'])
->view('Profile','truename,phone,email','Profile.user_id=member.id')
->view('Score','score','Score.user_id=Profile.id')
->where('score','>',80)
->select();

生成的SQL语句变成:

SELECT member.id AS uid,member.name AS account,Profile.truename,Profile.phone,Profile.email,Score.score 
FROM think_user member
INNER JOIN think_profile Profile ON Profile.user_id=member.id
INNER JOIN think_socre Score ON Score.user_id=Profile.id
WHERE Score.score > 80

子查询

首先构造子查询SQL,可以使用下面三种的方式来构建子查询。

1、使用 select 方法

当select方法的参数为false的时候,表示不进行查询只是返回构建SQL,例如:

$subQuery = Db::table('think_user')
->field('id,name')
->where('id','>',10)
->select(false);

生成的subQuery结果为:

SELECT `id`,`name` FROM `think_user` WHERE `id` > 10

2、使用 fetchSql 方法

fetchSql方法表示不进行查询而只是返回构建的SQL语句,并且不仅仅支持select,而是支持所有的CURD查询。

$subQuery = Db::table('think_user')
->field('id,name')
->where('id','>',10)
->fetchSql(true)
->select();

生成的subQuery结果为:

SELECT `id`,`name` FROM `think_user` WHERE `id` > 10

3、使用 buildSql 构造子查询

$subQuery = Db::table('think_user')
->field('id,name')
->where('id','>',10)
->buildSql();

生成的subQuery结果为:

( SELECT `id`,`name` FROM `think_user` WHERE `id` > 10 )

调用buildSql方法后不会进行实际的查询操作,而只是生成该次查询的SQL语句(为了避免混淆,会在SQL两边加上括号),然后我们直接在后续的查询中直接调用。

  需要注意的是,使用前两种方法需要自行添加‘括号’。

然后使用子查询构造新的查询:

Db::table($subQuery.' a')
->where('a.name','like','thinkphp')
->order('id','desc')
->select();

生成的SQL语句为:

SELECT * FROM ( SELECT `id`,`name` FROM `think_user` WHERE `id` > 10 ) a WHERE a.name LIKE 'thinkphp' ORDER BY `id` desc

4、使用闭包构造子查询

IN/NOT IN 和 EXISTS/NOT EXISTS 之类的查询可以直接使用闭包作为子查询,例如:

Db::table('think_user')
->where('id','IN',function($query){
$query->table('think_profile')->where('status',1)->field('id');
})
->select();

生成的SQL语句是

SELECT * FROM `think_user` WHERE `id` IN ( SELECT `id` FROM `think_profile` WHERE `status` = 1 )
Db::table('think_user')
->where(function($query){
$query->table('think_profile')->where('status',1);
},'exists')
->find();

生成的SQL语句为

SELECT * FROM `think_user` WHERE EXISTS ( SELECT * FROM `think_profile` WHERE `status`= 1 )

原生查询

Db 类支持原生 SQL 查询操作,主要包括下面两个方法:

query 方法

query 方法用于执行 SQL 查询操作,如果数据非法或者查询错误则返回false,否则返回查询结果数据集(同 select 方法)。

使用示例:

Db::query("select * from think_user where status=1");

  如果你当前采用了分布式数据库,并且设置了读写分离的话,query方法始终是在读服务器执行,因此query方法对应的都是读操作,而不管你的SQL语句是什么。

execute 方法

execute用于更新和写入数据的sql操作,如果数据非法或者查询错误则返回false ,否则返回影响的记录数。

使用示例:

Db::execute("update think_user set name='thinkphp' where status=1");

  如果你当前采用了分布式数据库,并且设置了读写分离的话,execute方法始终是在写服务器执行,因此execute方法对应的都是写操作,而不管你的SQL语句是什么。

参数绑定

支持在原生查询的时候使用参数绑定,包括问号占位符或者命名占位符,例如:

Db::query("select * from think_user where id=? AND status=?",[8,1]);
// 命名绑定
Db::execute("update think_user set name=:name where status=:status",['name'=>'thinkphp','status'=>1]);

ThinkPHP 数据库操作(七) : 视图查询、子查询、原生查询的更多相关文章

  1. ThinkPHP 数据库操作(三) : 查询方法、查询语法、链式操作

    查询方法 条件查询方法 where 方法 可以使用 where 方法进行 AND 条件查询: Db::table('think_user') ->where('name','like','%th ...

  2. ThinkPHP 数据库操作(四) : 聚合查询、时间查询、高级查询

    聚合查询 在应用中我们经常会用到一些统计数据,例如当前所有(或者满足某些条件)的用户数.所有用户的最大积分.用户的平均成绩等等,ThinkPHP为这些统计操作提供了一系列的内置方法,包括: 用法示例: ...

  3. thinkPHP数据库操作

    thinkPHP如果要对数据库操作,一般来说首先要做的是在配置文件中链接数据库,然后用M方法实例化一张表,然后就是对表的操作了 可以开启调试功能查看程序执行的sql语句: 1.开启调试功能(默认是已经 ...

  4. ThinkPHP 数据库操作(五) : 存储过程、数据集、分布式数据库

    存储过程 5.0支持存储过程,如果我们定义了一个数据库存储过程 sp_query ,可以使用下面的方式调用: $result = Db::query('call sp_query(8)'); 返回的是 ...

  5. ThinkPHP 数据库操作(一) : 连接数据库

    ThinkPHP内置了抽象数据库访问层,把不同的数据库操作封装起来,我们只需要使用公共的Db类进行操 作,而无需针对不同的数据库写不同的代码和底层实现,Db类会自动调用相应的数据库驱动来处理.采用 P ...

  6. 扣出thinkphp数据库操作类

    假如你是一位thinkphp的使用者,想必你会觉得thinkphp操作数据库非常方便.现在在你面前有一个非常小的作业,小到完全没有必要用thinkphp去完成它.但是你又觉得不用thinkphp的话, ...

  7. ThinkPHP 数据库操作之数据表模型和基础模型 ( Model )

    一.定义数据表模型 1.模型映射 要测试数据库是否正常连接,最直接的办法就是在当前控制器中实例化数据表,然后使用 dump 函数输出,查看数据库的链接状态.代码: public function te ...

  8. ThinkPHP 数据库操作(六) : 查询事件、事务操作、监听SQL

    查询事件 查询事件(V5.0.4+) 从 5.0.4+ 版本开始,增加了数据库的CURD操作事件支持,包括: 查询事件仅支持 find . select . insert . update 和 del ...

  9. MYSQL数据库学习七 视图的操作

    7.1 视图 视图使程序员只关心感兴趣的某些特定数据和他们所负责的特定任务.提高了数据库中数据的安全性. 视图的特点如下: 视图的列可以来自不同的表,是表的抽象和在逻辑意义上建立的新关系. 视图是由基 ...

随机推荐

  1. __builtin_expect — 分支预测优化

    1.引言 在很多源码如Linux内核.Glib等,我们都能看到likely()和unlikely()这两个宏,通常这两个宏定义是下面这样的形式. #define likely(x) __builtin ...

  2. python3和grpc的微服务探索实践

    对于微服务的实践,一般都是基于Java和Golang的,博主最近研究了下基于Python的微服务实践,现在通过一个简单的服务来分析Python技术栈的微服务实践 技术栈:Python3 + grpc ...

  3. 实验二《Java面向对象程序设计》实验报告

    一.实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设计模式 二.实验步骤 (一)单元测试 1.三种代码:伪代码.测 ...

  4. NOI2017总结

    时光剥离你我像一袭华美衣衫 却要被追悔爬满 退役之战,去得匆匆,看得蒙蒙. 第三次全国赛,曾经的APIO初二选手也走到了时间的尽头. 第一次走向全国舞台的激动与忐忑,第一次在大赛中失利的沮丧与绝望,第 ...

  5. IntelliJ IDEA之UML类图

    IntelliJ IDEA之UML类图 生成方法 Show Diagrams 选中需要的类,右键单击Diagrams,之后点击Show Diagrams,或者快捷键Ctrl+Alt+Shift+U 生 ...

  6. python 迭代器,生成器

    在 python 中我们常用 for in 来遍历 list, set, dict, str 等. for in 的本质就干了两件事: 调用 __iter__() 获取迭代器; 调用 next() 直 ...

  7. IE控件cab包手动安装

    一.XP系统 第1步:先解压cab包,在解压的文件中找到*.inf文件,然后右击,选择安装,此时会把解压文件拷到C:Windows\System32文件夹下.第2步:注册拷到上述文件夹下的ocx文件. ...

  8. 大数据计算框架Hadoop, Spark和MPI

    转自:https://www.cnblogs.com/reed/p/7730338.html 今天做题,其中一道是 请简要描述一下Hadoop, Spark, MPI三种计算框架的特点以及分别适用于什 ...

  9. 漏测BUG借鉴

    2. websocket: 用户频繁刷新,后台每次请求新的排队,内存溢出 1. websocket: 北京中心连接正常,外地中心,连接超时,应考虑到外地延迟问题

  10. [LeetCode] Leaf-Similar Trees 叶结点相似的树

    Consider all the leaves of a binary tree.  From left to right order, the values of those leaves form ...