TP6中數據庫操作


TP6中數據庫操作

要使用Db類必須使用門面方式(think\facade\Db)調用

use think\facade\Db;

一、數據庫連接配置

配置文件位於,config/database.php

或者開發環境 位於根目錄下的 .env 文件

APP_DEBUG = true
[APP]
DEFAULT_TIMEZONE = Asia/Shanghai
[DATABASE]
TYPE = mysql  //數據庫類型  
HOSTNAME = 127.0.0.1 //連接地址
DATABASE = test  //數據庫名稱
USERNAME = username  //數據庫用戶名
PASSWORD = password  //數據庫密碼
HOSTPORT = 3306  //端口
CHARSET = utf8  //字符集
DEBUG = true   //是否開啟debug
[LANG]
default_lang = zh-cn
動態配置數據庫連接查詢

\think\facade\Db::connect('demo')->table('user')->find();
數據模型中定義connection屬性

protected $connection = 'demo';

 

ThinkPHP的數據庫連接是惰性的,只有實際的數據操作的時候才會去連接數據庫。

二、數據庫分布式支持

如果需要支持分布式數據庫,包括讀寫分離,需要設置配置參數 deploy 的值為 1

// 啟用分布式數據庫
'deploy'    =>  1,
'hostname'  => '192.168.1.1,192.168.1.2', //默認情況下第一個地址就是主服務器
// 數據庫用戶名
'username' => 'root,slave,slave',
// 數據庫密碼
'password' => '123456',
關於 hostname,username,password,hostport,database,dsn,charset 要么值相同就配置一個,不然就分別設置

建議使用數組定義參數,例如:

'hostname' =>[ '192.168.1.1','192.168.1.2','192.168.1.3'],
'password' => ['123456','abc,def','hello']

三、數據庫支持讀寫分離

開啟讀寫分類配置:

'rw_separate' => true,
默認第一個是主數據庫,負責寫入數據。如果設置 master_num ,則可以支持多個主服務器寫入。

如果用原生SQL,寫操作必須用 execute 方法,讀操作必須用 query方法

剛寫入數據之后,從庫數據還沒來得及同步完成,你可以使用 master() 進行主庫查詢

Db::name('user')->master(true)->find(1);
也可以開啟:當我們對某個數據表進行了寫操作,那么當前請求的后續所有對該表的查詢都會使用主庫讀取

'read_master' => true,

 

四、鏈式操作

查詢單個數據
Db::table('think_user')->where('id', 1)->find();
查詢為空返回空數組
Db::table('think_user')->where('id', 1)->findOrEmpty();
說明:
如果沒有任何的查詢條件,也沒有調用order方法的話 ,find查詢不會返回任何結果。

查詢結果集:

Db::table('think_user')->where('status', 1)->select();

 select 方法查詢結果是一個數據集對象,如果需要轉換為數組可以使用

Db::table('think_user')->where('status', 1)->select()->toArray();

 查詢一個字段

Db::table('think_user')->where('id', 1)->value('name');

 查詢一列

// 返回數組
Db::table('think_user')->where('status',1)->column('name');
// 指定id字段的值作為索引
Db::table('think_user')->where('status',1)->column('name', 'id');

 添加數據:

$data = ['foo' => 'bar', 'bar' => 'foo'];
Db::name('user')->save($data);
或
Db::name('user')->insert($data);

 使用save方法時,數據中有ID則為更新,沒有ID則為新增

insert 方法添加數據成功返回添加成功的條數,通常情況返回 1
 
如果不希望因為存在數據表中沒有的字段而拋出異常,可以使用以下方法

Db::name('user')->strict(false)->insert($data);

 添加后返回主鍵

$userId = Db::name('user')->strict(false)->insertGetId($data);

 更新數據:

Db::name('user')->save(['id' => 1, 'name' => 'thinkphp']);
或
Db::name('user')->where('id', 1)->update(['name' => 'thinkphp']);

 支持表達式更新

Db::name('user')->where('id',1)->exp('name','UPPER(name)')->update();
或使用raw
Db::name('user')->where('id', 1)->update([
        'name'    =>    Db::raw('UPPER(name)'),
        'score'    =>    Db::raw('score-3'),
        'read_time'    =>    Db::raw('read_time+1')
    ]);

 自增自減

// score 字段加 1
Db::table('think_user')->where('id', 1)->inc('score')->update();
// score 字段加 5
Db::table('think_user')->where('id', 1)->inc('score', 5)->update();
// score 字段減 1
Db::table('think_user')->where('id', 1)->dec('score')->update();
// score 字段減 5
Db::table('think_user')->where('id', 1)->dec('score', 5)->update();
刪除數據:
// 根據主鍵刪除
Db::table('think_user')->delete(1);
Db::table('think_user')->delete([1,2,3]);

// 條件刪除    
Db::table('think_user')->where('id',1)->delete();
Db::table('think_user')->where('id','<',10)->delete();

沒有任何條件調用delete會返回錯誤。如果確實需要刪除所有數據,可以使用

// 無條件刪除所有數據
Db::name('user')->delete(true);

 查詢表達式:

 格式如下:

where('字段名','查詢表達式','查詢條件');
// = 等於
Db::name('user')->where('id','=',100)->select();    
//<> 不等於
Db::name('user')->where('id','<>',100)->select();
//>    大於
Db::name('user')->where('id','>',100)->select();    
//>=    大於等於    
Db::name('user')->where('id','>=',100)->select();
//<    小於
Db::name('user')->where('id', '<', 100)->select();    
<=    小於等於
Db::name('user')->where('id', '<=', 100)->select();
//[NOT] LIKE 模糊查詢
Db::name('user')->where('name', 'like', 'thinkphp%')->select();
//[NOT] BETWEEN    (不在)區間查詢    
Db::name('user')->where('id','between','1,8')->select();
//[NOT] IN    (不在)IN 查詢
Db::name('user')->where('id','in','1,5,8')->select();
或
Db::name('user')->where('id','in',[1,5,8])->select();
//[NOT] NULL :
Db::name('user')->where('name', null)->where('email','null')
->where('name','not null')->select();

 

 鏈式操作示例:

Db::table('think_user')
    ->where('status',1)
    ->order('create_time')
    ->limit(10)
    ->select();
鏈式where條件:

//1、表達式條件
Db::table('think_user')->where('id','>',1)->where('name','thinkphp')->select(); 

//2、數組條件
Db::table('think_user')->where(['name'=>'thinkphp','status'=>1])->select(); 
//3、字符串條件
Db::table('think_user')->whereRaw('type=1 AND status=1')->select(); 
或需要傳入變量,配合預處理機制,確保更加安全
Db::table('think_user')
->whereRaw("id=:id and username=:name", ['id' => 1 , 'name' => 'thinkphp'])
->select();
鏈式table操作

Db::field('user.name,role.title')
->table([
    'think_user'=>'user',
    'think_role'=>'role'
])
->limit(10)->select();
鏈式alias操作,設置表的別名

Db::table('think_user')
->alias('a')
->join('think_dept b ','b.user_id= a.id')
->select();
field操作

Db::table('user')->field('id,title,content')->select();
或使用別名
Db::table('user')->field('id,nickname as name')->select();
或使用SQL函數
Db::table('user')->fieldRaw('id,SUM(score)')->select();
strict操作

提交了非法字段會拋出異常,可以在配置中關閉嚴格字段檢查

'fields_strict'    =>    false,
也可以臨時關閉

// 關閉字段嚴格檢查
Db::name('user')->strict(false)->insert($data);
limit操作

//獲取滿足要求的10個用戶
Db::table('user')->where('status',1)->field('id,name')->limit(10)->select();
//limit方法也可以用於寫操作,例如更新滿足要求的3條數據:
Db::table('user')->where('score',100)->limit(3)->update(['level'=>'A']);

//分頁查詢,查詢從第20行開始的10條數據
Db::table('article')->limit(20,10)->select();
page操作

// 查詢第一頁數據
Db::table('article')->page(1,10)->select(); 
// 查詢第二頁數據
Db::table('article')->page(2,10)->select(); 
order操作

//沒有指定排序規則,默認 asc
Db::table('user')->where('status', 1)->order('id')->select();
//指定排序規則
Db::table('user')->where('status', 1)->order('id', 'desc')->select();
group操作

通常用於結合合計函數,根據一個或多個列對結果集進行分組。

Db::table('user')->field('user_id,username,max(score)')
    ->group('user_id')->select();
對多個字段進行分組
Db::table('user')->field('user_id,test_time,username,max(score)')
    ->group('user_id,test_time')->select();
having操作

Db::table('score')
    ->field('username,max(score)')->group('user_id')
    ->having('count(test_time)>3')->select(); 
join操作

INNER JOIN: 等同於 JOIN(默認的JOIN類型),如果表中有至少一個匹配,則返回行
LEFT JOIN: 即使右表中沒有匹配,也從左表返回所有的行
RIGHT JOIN: 即使左表中沒有匹配,也從右表返回所有的行
FULL JOIN: 只要其中一個表中存在匹配,就返回行
//join 方式
Db::table('think_artist')
->alias('a')
->join('work w','a.id = w.artist_id')
->join('card c','a.card_id = c.id')
->select();
//left join 方式
Db::table('think_user')
->alias('a')
->leftJoin('word w','a.id = w.artist_id')
->select();

 

五、聚合查詢

count:Db::table('think_user')->count();
max:Db::table('think_user')->max('score');
min:Db::table('think_user')->min('score');
avg: Db::table('think_user')->avg('score');
sum: Db::table('think_user')->sum('score');

六、分頁查詢

 控制器代碼:

// 查詢狀態為1的用戶數據 並且每頁顯示10條數據
$list = Db::name('user')->where('status',1)->order('id', 'desc')->paginate(10);
// 獲取分頁顯示
$page = $list->render();
return view('index', ['list' => $list, 'page' => $page]);

 

 HTML代碼:

<div>
<ul>
{volist name='list' id='user'}
    <li> {$user.nickname}</li>
{/volist}
</ul>
</div>
{$page|raw}
獲取總數據

// 獲取總記錄數
$count = $list->total();
分頁后數據處理

$list = Db::name('user')->where('status',1)->order('id', 'desc')
->paginate()->each(function($item, $key){
    $item['nickname'] = 'think';
    return $item;
});
模型中分頁數據處理,無需return

$list = User::where('status',1)->order('id', 'desc')->paginate()->each(function($item, $key){
    $item->nickname = 'think';
});
分頁參數:

$list = Db::name('user')->where('status',1)->paginate([
    'list_rows'=> 20,
    'query'    => $data
]);

七、時間查詢 whereTime

// 大於某個時間
Db::name('user')->whereTime('birthday', '>=', '1970-10-1')->select();
// 小於某個時間
Db::name('user')->whereTime('birthday', '<', '2000-10-1')->select();
// 時間區間查詢
Db::name('user')->whereTime('birthday', 'between', ['1970-10-1', '2000-10-1'])
    ->select();
// 不在某個時間區間
Db::name('user')->whereTime('birthday', 'not between', ['1970-10-1', '2000-10-1'])
    ->select();

八、原生查詢

V6.0.3+版本開始,原生查詢僅支持Db類操作

query方法

Db::query("select * from think_user where status=:id", ['id' => 1]);
//從主庫讀取
Db::query("select * from think_user where status=:id", ['id' => 1], true);
execute方法

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

//問號占位符綁定
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]);
 //注意不支持對表名使用參數綁定

九:事務操作

使用事務處理的話,需要數據庫引擎支持事務處理。比如 MySQL 的 MyISAM 不支持事務處理,需要使用 InnoDB 引擎。

最簡單的事務閉包操作:

Db::transaction(function () {
    Db::table('think_user')->find(1);
    Db::table('think_user')->delete(1);
});
手動運行事務:

// 啟動事務
Db::startTrans();
try {
    Db::table('think_user')->find(1);
    Db::table('think_user')->delete(1);
    // 提交事務
    Db::commit();
} catch (\Exception $e) {
    // 回滾事務
    Db::rollback();
}

十:存儲過程

//數據訪問層調用存儲過程
$resultSet = Db::query('call procedure_name');
foreach ($resultSet as $result) {

}

//存儲過程可以支持輸入和輸出參數,以及進行參數綁定操作。
$resultSet = Db::query('call procedure_name(:in_param1,:in_param2,:out_param)', [
    'in_param1' => $param1,
    'in_param2' => [$param2, PDO::PARAM_INT],
    'out_param' => [$outParam, PDO::PARAM_STR | PDO::PARAM_INPUT_OUTPUT, 4000],
]);

 

數據集:

// 獲取數據集
$users = Db::name('user')->select();
// 直接操作第一個元素
$item  = $users[0];
// 獲取數據集記錄數
$count = count($users);
// 遍歷數據集
foreach($users as $user){
    echo $user['name'];
    echo $user['id'];
}
判斷數據集是否為空,不能直接使用empty判斷,而必須使用數據集對象的isEmpty方法判斷,

$users = Db::name('user')->select();
if($users->isEmpty()){
    echo '數據集為空';
}

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM