第7章 數據庫訪問與ORM 慕課網微信小程序開發學習筆記

第7章 數據庫訪問與ORM

 

目錄:

  • 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等數據庫的支持。php

 

配置數據庫鏈接信息:

默認是在application\database.php裏配置的,mysql

 

可使用多個數據庫鏈接,使動態定義鏈接信息用

動態定義鏈接信息:

 Db::connect($config)->query('select * from think_user where id=:id',['id'=>8]); sql

 $config是一個單獨的數據庫配置,支持數組和字符串,也能夠是一個數據庫鏈接的配置參數名。thinkphp

或者使用字符串方式:數據庫

 Db::connect('mysql://root:1234@127.0.0.1:3306/thinkphp#utf8');json

例子:api

 $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,操做數據庫的方式

  1. 使用原生的sql語句查詢數據庫.
  2. 使用構造器來查詢查詢數據庫.
  3. 使用模型以及關連模型來查詢數據庫

1.使用原生的sql語句查詢數據庫.

配置了數據庫鏈接信息後,咱們就能夠直接使用數據庫運行原生SQL操做了,支持query(查詢操做)和execute(寫入操做)方法,而且支持參數綁定。

1 Db::query('select * from think_user where id=?',[8]);
2 Db::execute('insert into think_user (id, name) values (?, ?)',[8,'thinkphp']);

也支持命名佔位符綁定,例如:

1 Db::query('select * from think_user where id=:id',['id'=>8]);
2 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'=>8,'name'=>'thinkphp']);

 

 1 <?php
 2 namespace app\index\controller;
 3 use \think\Controller;    
 4 use \think\Db; 
 5 
 6 class Index extends Controller
 7 {
 8     public function index()
 9     {
10         $data=Db::query('select * from sys_user where id=?',[1]);
11         dump($data);
12     }
13 }

實例:

要實現的功能:

控制器調用model層,從表裏查出數據,model層將查出來的結果傳給控制器,

控制器再返回json模式的數據

app\api\controller\v1\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 
25         (new IDMustBePostiveInt())->goCheck(); //驗證$id是否爲正整數
26         $banner = BannerModel::getBannerById($id);//調用model
27         if (!$banner){
28            throw new BannerMissException(); //判斷結果不存在,拋出異常
29         }
30         return json($banner,200);//返回json格式的結果, 默認就是200狀態碼,可不寫
31     }
32 }

app\api\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 
11 
12 use think\Db;
13 
14 class Banner
15 {
16     public static function getBannerById($id){
17         //TODO 根據Banner 的 ID號 獲取Banner信息
18         $result=Db::query('select * from banner_item where banner_id = ?',[$id]);
19         return $result;
20 
21     }
22 }

訪問結果:

查出了四條數據

z.com/api/v1/banner/1?XDEBUG_SESSION_START=13378

 


7-2 從一個錯誤瞭解Exception的繼承關係 13:23

 


7-3 TP5數據庫中間層架構解析 23:06

常見模式:

鏈接上數據庫後,直接寫增刪改查(不白,不推薦)

框架弄的模式(推薦)

Db的做用:

  1. 是數據庫操做的一入口文件,
  2. 用來鏈接數據庫.

總結:

若是使用原生的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裏有不少鏈式方法:

 

  1. 不相同的連式方法是沒有前後順序的.
  2. 相同的鏈式方法,它們的前後順序可能會獲得不一樣的結果.例若有兩個order.
  3. 一次Db在調用select()這樣的執行sql語句的方法後,它的狀態就會被清除了.
  4. 非鏈式調用的方法,直到調用select()這樣的執行sql語句的方法後,它的狀態纔會被清除了
 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 
12 class Banner
13 {
14     public static function getBannerById($id){
15         //TODO 根據Banner 的 ID號 獲取Banner信息
16         //原生sql語句方法(不建議使用,這樣就失去了tp5框架sql和build構造sql的意義了)
17             //$result = Db::query('select * from banner_item where banner_id = ?',[$id]);
18         //table調用
19             //$result = Db::table('banner_item')->where('banner_id','=',$id)->select();
20         //db助手函數方法
21             //$result = db('banner_item')->where('banner_id','=',$id)->select();
22         //非鏈式操做方法
23             Db::table('banner_item');
24             Db::where('banner_id',$id);
25             $result = Db::select(); //直接這一步纔會清除query對象
26 
27         return $result;
28 
29     }
30 }

 執行結果:

 


7-6 查詢構造器 三 11:12

查詢表達式

手冊:

https://www.kancloud.cn/manual/thinkphp5/135182

查詢表達式支持大部分的SQL查詢語法,也是ThinkPHP查詢語言的精髓,查詢表達式的使用格式:

1 where('字段名','表達式','查詢條件');
2 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 時間比較

 

 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 
12 class Banner
13 {
14     public static function getBannerById($id){
15         //TODO 根據Banner 的 ID號 獲取Banner信息
16         //原生sql語句方法(不建議使用,這樣就失去了tp5框架sql和build構造sql的意義了)
17             //$result = Db::query('select * from banner_item where banner_id = ?',[$id]);
18         //table調用
19             //$result = Db::table('banner_item')->where('banner_id','=',$id)->select();
20         //db助手函數方法
21             //$result = db('banner_item')->where('banner_id','=',$id)->select();
22         //非鏈式操做方法
23 //            Db::table('banner_item');
24 //            Db::where('banner_id',$id);
25 //            $result = Db::select(); //直接這一步纔會清除query對象
26 
27         //構造query對象的三種方法:(表達式,數組,閉包)
28             //表達式 (建議使用這種)
29 //                $result = db('banner_item')->where('banner_id','=',$id)->select();
30             //數組
31 //                $result = db('banner_item')->where(['banner_id'=>$id])->select();
32             //閉包
33             $order='id desc';
34             $result = Db::select(function($query) use($id,$order){
35                             $query->table('banner_item')
36                                 ->where('banner_id','=',$id)
37                                 ->order($order)
38                                 ->limit(2);
39                         });
40         return $result;
41 
42     }
43 }

執行結果:

 


7-7 開啓SQL日誌記錄 16:07

fetchSql用於直接返回SQL而不是執行查詢,適用於任何的CURD操做方法。 例如:

返回要執行的sql語句

1  //數組
2  $result = db('banner_item')
3            ->where(['banner_id'=>$id])
4            ->fetchSql() //返回要執行的sql語句
5            ->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

  1. 模型返回的結果就是一個對象
  2. 模型都須要繼承think\Model的
  3. 當業務比較簡單的時候,一般是一個模型對應着一張表的
  4. 大一些業務會是一個模型對應着多張表的
  5. 默認model的類名(也就是模型層)是對應庫裏同名的表名的(tp5就知道他們以前是有映色的關係).
  6. 數據庫裏的每張表看着做一個對象.

在數據庫表裏有主表和從表的概念.如何把主從表的概念應射到咱們如今的orm對象當中來的這種方式f?

tp5就是用關聯模式的方案對應表裏的主從表.


7-11 靜態調用仍是實例對象調用 09:59


7-12 幾種查詢動詞的總結與ORM性能問題的探討 16:47

相關文章
相關標籤/搜索