第7章 数据库访问与ORM 慕课网微信小程序开发学习笔记
第7章 数据库访问与ORM
https://coding.imooc.com/learn/list/97.html
目录:
- 7-1 数据库操作三种方式之原生SQL 19:09
- 7-2 从一个错误了解Exception的继承关系 13:23
- 7-3 TP5数据库中间层架构解析 23:06
- 7-4 查询构造器 一 13:28
- 7-5 查询构造器 二 13:20
- 7-6 查询构造器 三 11:12
- 7-7 开启SQL日志记录 16:07
- 7-8 ORM与模型 10:19
- 7-9 初识模型 17:47
- 7-10 模型定义总结 08:33
- 7-11 静态调用还是实例对象调用 09:59
- 7-12 几种查询动词的总结与ORM性能问题的探讨 16:47
7-1 数据库操作三种方式之原生SQL 19:09
thinkphp5支持的数据类型:
目前包含了Mysql、SqlServer、PgSQL、Sqlite等数据库的支持。
配置数据库连接信息:
默认是在application\database.php里配置的,

可以使用多个数据库连接,使动态定义连接信息用
动态定义连接信息:
Db::connect($config)->query('select * from think_user where id=:id',['id'=>8]);
$config是一个单独的数据库配置,支持数组和字符串,也可以是一个数据库连接的配置参数名。
或者使用字符串方式:
Db::connect('mysql://root:1234@127.0.0.1:3306/thinkphp#utf8');
例子:
$user=\think\Db::connect('mysql://root:root@127.0.0.1:3306/tp5#utf8')->query('select * from user where id=?',[$id]);
字符串连接的定义格式为:
数据库类型://用户名:密码@数据库地址:数据库端口/数据库名#字符集
详细参考说明文档:
https://www.kancloud.cn/manual/thinkphp5/118059
thinkphp5,操作数据库的方式
- 使用原生的sql语句查询数据库.
- 使用构造器来查询查询数据库.
- 使用模型以及关连模型来查询数据库
1.使用原生的sql语句查询数据库.
配置了数据库连接信息后,我们就可以直接使用数据库运行原生SQL操作了,支持query(查询操作)和execute(写入操作)方法,并且支持参数绑定。
Db::query('select * from think_user where id=?',[8]);
Db::execute('insert into think_user (id, name) values (?, ?)',[8,'thinkphp']);
也支持命名占位符绑定,例如:
Db::query('select * from think_user where id=:id',['id'=>8]);
Db::execute('insert into think_user (id, name) values (:id, :name)',['id'=>8,'name'=>'thinkphp']);
这样就不需要use think\Db; 这句了。
think\Db::query('select * from think_user where id=?',[8]);
Db::query('select * from think_user where name like :name',['name'=>'%德华%']);
Db::execute('insert into think_user (id, name) values (:id, :name)',['id'=>,'name'=>'thinkphp']);
<?php
namespace app\index\controller;
use \think\Controller;
use \think\Db; class Index extends Controller
{
public function index()
{
$data=Db::query('select * from sys_user where id=?',[1]);
dump($data);
}
}
实例:
要实现的功能:
控制器调用model层,从表里查出数据,model层将查出来的结果传给控制器,
控制器再返回json模式的数据
app\api\controller\v1\Banner.php控制器里:
<?php
/**
* Created by PhpStorm.
* User: Haima
* Date: 2018/7/8
* Time: 15:58
*/ namespace app\api\controller\v1;
use app\api\model\Banner as BannerModel;
use app\api\validate\IDMustBePostiveInt;
use app\lib\exception\BannerMissException; class Banner
{
/**
* 获取指定id的banner信息
* @url /banner/:id
* @http GET
* @id banner的id号
*/
public function getBanner($id)
{ (new IDMustBePostiveInt())->goCheck(); //验证$id是否为正整数
$banner = BannerModel::getBannerById($id);//调用model
if (!$banner){
throw new BannerMissException(); //判断结果不存在,抛出异常
}
return json($banner,200);//返回json格式的结果, 默认就是200状态码,可不写
}
}
app\api\model\Banner.php的模型里:
<?php
/**
* Created by PhpStorm.
* User: Haima
* Date: 2018/7/12
* Time: 1:16
*/ namespace app\api\model; use think\Db; class Banner
{
public static function getBannerById($id){
//TODO 根据Banner 的 ID号 获取Banner信息
$result=Db::query('select * from banner_item where banner_id = ?',[$id]);
return $result; }
}
访问结果:
查出了四条数据
z.com/api/v1/banner/1?XDEBUG_SESSION_START=13378


7-2 从一个错误了解Exception的继承关系 13:23

7-3 TP5数据库中间层架构解析 23:06
常见模式:
连接上数据库后,直接写增删改查(不白,不推荐)

框架弄的模式(推荐)

Db的作用:
- 是数据库操作的一入口文件,
- 用来连接数据库.
总结:
如果使用原生的SQL语句,Db就就可以使用Collection(连接器类)直接去操作数据库了.
如果使用的Query语句,那么就需要使用Buider编译为原生的SQL语句再通过Collection直接去操作数据库了
Drivers
根据配置文件里找到对应的数据库连接类型,从而操作数据库.

同一个标准的Query查询器,调用不同的Buidle生成器来解析Query查询器,从而来适配不同的数据库

7-4 查询构造器 一 13:28
7-5 查询构造器 二 13:20

table()和where()叫作链式方法或者辅助方法,它不会真正执行sql语句,
它会得到一个query对象,然后再调用里面的执行sql语句方法
select()和find()是查询方法,是真正的执行sql语句方法
执行sql语句方法还有update(),delete(),insert();
tp5里有很多链式方法:

- 不相同的连式方法是没有先后顺序的.
- 相同的链式方法,它们的先后顺序可能会得到不同的结果.例如有两个order.
- 一次Db在调用select()这样的执行sql语句的方法后,它的状态就会被清除了.
- 非链式调用的方法,直到调用select()这样的执行sql语句的方法后,它的状态才会被清除了
<?php
/**
* Created by PhpStorm.
* User: Haima
* Date: 2018/7/12
* Time: 1:16
*/ namespace app\api\model;
use think\Db; class Banner
{
public static function getBannerById($id){
//TODO 根据Banner 的 ID号 获取Banner信息
//原生sql语句方法(不建议使用,这样就失去了tp5框架sql和build构造sql的意义了)
//$result = Db::query('select * from banner_item where banner_id = ?',[$id]);
//table调用
//$result = Db::table('banner_item')->where('banner_id','=',$id)->select();
//db助手函数方法
//$result = db('banner_item')->where('banner_id','=',$id)->select();
//非链式操作方法
Db::table('banner_item');
Db::where('banner_id',$id);
$result = Db::select(); //直接这一步才会清除query对象 return $result; }
}
执行结果:

7-6 查询构造器 三 11:12
查询表达式
手册:
https://www.kancloud.cn/manual/thinkphp5/135182
查询表达式支持大部分的SQL查询语法,也是ThinkPHP查询语言的精髓,查询表达式的使用格式:
where('字段名','表达式','查询条件');
whereOr('字段名','表达式','查询条件');
表达式不分大小写,支持的查询表达式有下面几种,分别表示的含义是:
| 表达式 | 含义 |
|---|---|
| EQ、= | 等于(=) |
| NEQ、<> | 不等于(<>) |
| GT、> | 大于(>) |
| EGT、>= | 大于等于(>=) |
| LT、< | 小于(<) |
| ELT、<= | 小于等于(<=) |
| LIKE | 模糊查询 |
| [NOT] BETWEEN | (不在)区间查询 |
| [NOT] IN | (不在)IN 查询 |
| [NOT] NULL | 查询字段是否(不)是NULL |
| [NOT] EXISTS | EXISTS查询 |
| EXP | 表达式查询,支持SQL语法 |
| > time | 时间比较 |
| < time | 时间比较 |
| between time | 时间比较 |
| notbetween time | 时间比较 |
<?php
/**
* Created by PhpStorm.
* User: Haima
* Date: 2018/7/12
* Time: 1:16
*/ namespace app\api\model;
use think\Db; class Banner
{
public static function getBannerById($id){
//TODO 根据Banner 的 ID号 获取Banner信息
//原生sql语句方法(不建议使用,这样就失去了tp5框架sql和build构造sql的意义了)
//$result = Db::query('select * from banner_item where banner_id = ?',[$id]);
//table调用
//$result = Db::table('banner_item')->where('banner_id','=',$id)->select();
//db助手函数方法
//$result = db('banner_item')->where('banner_id','=',$id)->select();
//非链式操作方法
// Db::table('banner_item');
// Db::where('banner_id',$id);
// $result = Db::select(); //直接这一步才会清除query对象 //构造query对象的三种方法:(表达式,数组,闭包)
//表达式 (建议使用这种)
// $result = db('banner_item')->where('banner_id','=',$id)->select();
//数组
// $result = db('banner_item')->where(['banner_id'=>$id])->select();
//闭包
$order='id desc';
$result = Db::select(function($query) use($id,$order){
$query->table('banner_item')
->where('banner_id','=',$id)
->order($order)
->limit(2);
});
return $result; }
}
执行结果:

7-7 开启SQL日志记录 16:07
fetchSql用于直接返回SQL而不是执行查询,适用于任何的CURD操作方法。 例如:
返回要执行的sql语句
//数组
$result = db('banner_item')
->where(['banner_id'=>$id])
->fetchSql() //返回要执行的sql语句
->select();

开启thinkphp5默认的sql全局日志保存功能:
database.php里
// 开启数据库调试模式
config里开启调试模试:


type=File全局日志保存记录
LOG_PATH 定义的是
defined('LOG_PATH') or define('LOG_PATH', RUNTIME_PATH . 'log' . DS);
运行会产生log日志
model里
访问一下接口
产生日志:
下面我们自定义全局sql日志:
思路,:所有的请求,都会经过public/index.php,所以在这里初始化自定义sql的全局日志
这里datebase.php里的开启数据库调试模式为ture
config.php里开启debug调适
log里type='test',关闭全局的
path路径设置好日志生成的路径
level等级为sql

public/index.php里
16行,设义修改log日志保存的地方

再访问接口就会生成sql的log日志

在项目的根目录log里的就会产生sql日志
7-8 ORM与模型 10:19
7-9 初识模型 17:47
db属于数据库访问层
model模型不是数据库的访问层,它是建立在数据库访问层之上一个更加抽象的处理业务逻辑的模型层.
use think\Model;
class Banner extends Model //在model的控制器里继承Model以后,Banner就变成一个模型层了
Model层里,banner.php的代码
1 <?php
2 /**
3 * Created by PhpStorm.
4 * User: Haima
5 * Date: 2018/7/12
6 * Time: 1:16
7 */
8
9 namespace app\api\model;
10 use think\Db;
11 use think\Model;
12
13 class Banner extends Model //继承Model以后,Banner就变成一个模型层了
14 {
15 public static function getBannerById($id){
16 //TODO 根据Banner 的 ID号 获取Banner信息
17
18 //构造query对象的三种方法:(表达式,数组,闭包)
19
20 //数组
21 $result = db('banner_item')
22 ->where(['banner_id'=>$id])
23 // ->fetchSql() //返回要执行的sql语句
24 ->select();
25
26 return $result;
27
28 }
29 }
控制器层,Banner.php代码
1 <?php
2 /**
3 * Created by PhpStorm.
4 * User: Haima
5 * Date: 2018/7/8
6 * Time: 15:58
7 */
8
9 namespace app\api\controller\v1;
10 use app\api\model\Banner as BannerModel;
11 use app\api\validate\IDMustBePostiveInt;
12 use app\lib\exception\BannerMissException;
13
14 class Banner
15 {
16 /**
17 * 获取指定id的banner信息
18 * @url /banner/:id
19 * @http GET
20 * @id banner的id号
21 */
22 public function getBanner($id)
23 {
24 (new IDMustBePostiveInt())->goCheck(); //验证$id是否为正整数
25
26 //调用model层的方法:
27 //方法一:静态调用(当控制器和类名一样时用别名引入)
28 // 这样调用model层,model的类不需要继承Model类,
29 //但是调用的方法里需要自己个方法,在方法里写代码对库里的表进行操作
30 // $banner = BannerModel::getBannerById($id);//调用model
31
32 //方法二:
33 //这样调用model层,model层里的类要继承Model类
34 //model层里不用自己再写方法和代码对库里的表进行操作了
35 $banner= BannerModel::get($id);
36 if (!$banner){
37 throw new BannerMissException(); //判断结果不存在,抛出异常
38 }
39 return json($banner,200);//返回json格式的结果, 默认就是200状态码,可不写
40 }
41 }
方法一,Db返回的是一个数组
方法二,模型的方法返回的是一个模型的对象,属于orm查询,它是以对象的方式来思考数据库,以对象的方式来调用数据库,结果也是以对象的方式返回

这里要注意的是使用orm模型的方式,去查询, 返回的结果,tp5会自动把结果序列化,不需要再return json($result)了
这里需要注意的是返回的是一上一条记录,说明一个模型对应该它同名的表,这里查出来的是banner表里的数据,所以只查出来的一条结果
config.php 里需要配置一下输出类型为json:
// 默认输出类型
'default_return_type' => 'json',

访问返回的结果依然是json形式的:

7-10 模型定义总结 08:33
- 模型返回的结果就是一个对象
- 模型都需要继承think\Model的
- 当业务比较简单的时候,通常是一个模型对应着一张表的
- 大一些业务会是一个模型对应着多张表的
- 默认model的类名(也就是模型层)是对应库里同名的表名的(tp5就知道他们之前是有映色的关系).
- 数据库里的每张表看着作一个对象.
在数据库表里有主表和从表的概念.如何把主从表的概念应射到我们现在的orm对象当中来的这种方式f?
tp5就是用关联模式的方案对应表里的主从表.
7-11 静态调用还是实例对象调用 09:59
7-12 几种查询动词的总结与ORM性能问题的探讨 16:47
第7章 数据库访问与ORM 慕课网微信小程序开发学习笔记的更多相关文章
- 第1-5章 慕课网微信小程序开发学习笔记
第1章 前言:不同的时代,不同的Web --微信小程序商城构建全栈应用 http://note.youdao.com/noteshare?id=a0e9b058853dbccf886c1a890594 ...
- 第6章 AOP与全局异常处理6.5-6.11 慕课网微信小程序开发学习笔记
https://coding.imooc.com/learn/list/97.html 目录: 第6章 AOP与全局异常处理6-1 正确理解异常处理流程 13:236-2 固有的处理异常的思维模式与流 ...
- 第6章 AOP与全局异常处理6.1-6.4 慕课网微信小程序开发学习笔记
第6章 AOP与全局异常处理 https://coding.imooc.com/learn/list/97.html 目录: 第6章 AOP与全局异常处理6-1 正确理解异常处理流程 13:236-2 ...
- 慕课网 微信小程序商城构建全栈应用 tp5【总结】
1.异常处理: [代码越抽象,复用性越高] [封装性越好,适应代码变化的能力越强] [] <?php/** * Created by PhpStorm. * User: 14155 * Date ...
- 慕课网-Linux达人养成计划学习笔记
mkdir -p [目录]创建目录-p 递归创建ls 查看当前目录下的文件和目录等其他文件 cd [目录]命令英文愿意:change directory切换所在目录简化操作cd ~ 进入当前用户的家目 ...
- 慕课网,我的yii2学习笔记(基础篇)
一.关于PHP知识点 1.命名空间:存放类文件的空间,可以随便定义,建议与类文件目录一致,方便管理. 注:(1).如果类没有设置命名空间,默认为顶级命名空间,在程序中可以用一下方式实例化. $mode ...
- 基于centos搭建微信小程序服务,配置及数据库等
基于centos搭建小程序, ps:请提前20天准备将域名备案,申请ssl证书 实验上机地址:https://cloud.tencent.com/developer/labs/lab/10004 准备 ...
- 微信小程序对接显示阿里云数据库数据
现实需求 在项目中需求,有时候现场设备发生故障,需要远程的人员知道.除了邮件方式,以微信小程序的方式也很好.今天进行尝试,并制作了一个demo版本. 1.微信小程序申请制作前端 1.1lists文件( ...
- .Net Core ORM选择之路,哪个才适合你 通用查询类封装之Mongodb篇 Snowflake(雪花算法)的JavaScript实现 【开发记录】如何在B/S项目中使用中国天气的实时天气功能 【开发记录】微信小游戏开发入门——俄罗斯方块
.Net Core ORM选择之路,哪个才适合你 因为老板的一句话公司项目需要迁移到.Net Core ,但是以前同事用的ORM不支持.Net Core 开发过程也遇到了各种坑,插入条数多了也特别 ...
随机推荐
- Dedecms标签arclistsg调用单表模型出错的解决方法
使用arclistsg标签调用分类信息等单表模型出错提示Column 'id' in where clause is ambiguous, 修改文件:include\taglib\arclistsg ...
- 移植mavlink到stm32详细教程,后面附快速移植方法
一:准备材料: mavlink源码 stm32串口程序 1.mavlink源码: a.进入mavlink官网(http://qgroundcontrol.org/mavlink/s ...
- SpringBoot的日志管理
SpringBoot的日志管理 SpringBoot关于日志的官方文档 1.简述 SpringBoot官方文档关于日志的整体说明 本博客基于SpringBoot_1.3.6大家请先简单看下这篇英文的官 ...
- es6-异步应用
异步编程对 JavaScript 语言太重要.Javascript 语言的执行环境是“单线程”的,如果没有异步编程,根本没法用,非卡死不可.本章主要介绍 Generator 函数如何完成异步操作. 传 ...
- webpake-node-sass 报错
问题描述: npm run dev 就报错,在安装node-sass错误 解决方法 : 找到node_modules下的node-sass文件,进入,如果没有vendor文件夹,就创建一个空文件夹,命 ...
- 构建第一个Spring Boot2.0应用之项目创建(一)
1.开发环境 IDE: JAVA环境: Tomcat: 2.使用Idea生成spring boot项目 以下是使用Idea生成基本的spring boot的步骤. (1)创建工程第一步 (2)创建工 ...
- 1)实际时间(real time): 从command命令行开始执行到运行终止的消逝时间; 2)用户CPU时间(user CPU time): 命令执行完成花费的用户CPU时间,即命令在用户态中执行时间总和; 3)系统CPU时间(system CPU time): 命令执行完成花费的系统CPU时
1)实际时间(real time): 从command命令行开始执行到运行终止的消逝时间: 2)用户CPU时间(user CPU time): 命令执行完成花费的用户CPU时间,即命令在用户态中执行时 ...
- OpenSSL context 的几个参数
NAME SYNOPSIS DESCRIPTION NOTES BUGS RETURN VALUES EXAMPLES SEE ALSO NAME SSL_CTX_set_verify, SSL_se ...
- LeetCode Move Zeroes (简单题)
题意: 给定一个整型数组nums,要求将其中所有的0移动到末尾,并维护所有非0整数的相对位置不变. 思路: 扫一遍,两个指针维护0与非0的交界,将非0的数向前赋值就行了. C++ class Solu ...
- LeetCode Number of 1 Bits 计算1的个数
题意: 提供一个无符号32位整型uint32_t变量n,返回其二进制形式的1的个数. 思路: 考察二进制的特性,设有k个1,则复杂度为O(k).考虑将当前的数n和n-1做按位与,就会将n的最后一个1去 ...


