# ThinkPHP6 数据库操作
* `PDO` 预处理
* 要使用Db类必须使用门面方式( `think\facade\Db` )调用
* 数据库操作统一入口: `Db::`
---
### 一、执行原生 `MySql`
#### 1、`query` 方法用于执行 `MySql` 查询操作
```php
示例:
namespace app\index\controller;
use app\BaseController;
use think\facade\Db;
class Index extends BaseController{
public function index(){
$query = Db::query("select * from user where status=1");
print_r($query);
}
}
```
#### 2、`execute` 方法用户执行 `MySql` 新增和修改操作
```php
示例:
namespace app\index\controller;
use app\BaseController;
use think\facade\Db;
class Index extends BaseController{
public function index(){
$execute = Db::execute("insert into user set `phone`='13211111111',`u_name`='一灯大师' ");
print_r($execute);
$execute = Db::execute("update user set `u_name`='武三通' where `uid`=6 ");
print_r($execute);
}
}
```
---
### 二、查询
> 1、单条数据查询 `find`
* `find` 方法查询结果不存在,返回 `null`,否则返回结果数组
```php
示例:
namespace app\index\controller;
use app\BaseController;
use think\facade\Db;
class Index extends BaseController{
public function index(){
$find = Db::table('user')->where('uid',1)->find();
print_r($find);
}
}
```
> 2、多条数据查询 `select`
* `select` 方法查询结果是一个二维数组,如果结果不存在,返回空数组
```php
示例:
$select = Db::table('user')->where('status',1)->select();
print_r($select);
```
> 3、查询某个字段的值 `value`
* `value` 方法查询结果不存在,返回 null
```php
示例:
$value = Db::table('user')->where('uid',1)->value('u_name');
print_r($value);
```
> 4、查询某一列的值 `column`
* `column` 方法查询结果不存在,返回空数组
```php
示例:
$column = Db::table('user')->where('uid',1)->column('u_name');
print_r($column);
$column = Db::table('user')->where('uid',1)->column('u_name','uid');
print_r($column);
```
---
### 三、添加
> 1、添加一条数据 `insert`
* `insert` 方法添加数据成功返回添加成功的条数,通常情况返回 1
```php
示例:
# 添加数据
$data = ['phone'=>'13355555555','u_name'=>'穆念慈','sex'=>2];
$insert = Db::table('user')->insert($data);
print_r($insert);
```
> 2、添加、修改一条数据 `save`
* `save` 方法统一写入数据,自动判断是新增还是更新数据(以写入数据中是否存在主键数据为依据)。
```php
示例:
# 添加数据
$data = ['phone'=>'13355555555','u_name'=>'黄药师','sex'=>1];
$save = Db::table('user')->save($data);
print_r($save);
# 修改数据
$data = ['uid'=>6,'phone'=>'13366666666','u_name'=>'黄药师','sex'=>1];
$save = Db::table('user')->save($data);
print_r($save);
```
> 3、添加一条数据 `insertGetId`
* `insertGetId` 方法添加数据成功返回添加数据的自增主键
```php
示例:
# 添加数据,返回增加的数据主键ID
$data = ['phone'=>'13377777777','u_name'=>'洪七公','sex'=>1];
$insert = Db::table('user')->insertGetId($data);
print_r($insert);
```
> 4、添加多条数据 `insertAll`
* `insertAll` 方法添加数据成功返回添加成功的条数
```php
示例:
# 增加三条数据
$data = [
['phone'=>'13388888888','u_name'=>'段智兴','sex'=>1],
['phone'=>'13399999999','u_name'=>'周伯通','sex'=>1],
['phone'=>'13300000000','u_name'=>'瑛姑','sex'=>2],
['phone'=>'13400000000','u_name'=>'欧阳锋','sex'=>1],
['phone'=>'13411111111','u_name'=>'王重阳','sex'=>1]
];
$insert = Db::table('user')->insertAll($data);
print_r($insert);
```
---
### 四、修改
> 1、修改数据 `update`
* `update` 方法返回影响数据的条数,没修改任何数据返回 0
```php
示例:
# 修改数据
$data = ['phone'=>'13422222222','u_name'=>'一灯大师'];
$update = Db::table('user')->where('uid',9)->update($data);
print_r($update);
```
> 2、添加、修改一条数据 `save`
* `save` 方法统一写入数据,自动判断是新增还是更新数据(以写入数据中是否存在主键数据为依据)。
```php
示例:
# 修改数据
$data = ['phone'=>'13433333333','u_name'=>'中神通周伯通'];
$save = Db::table('user')->where('uid',10)->save($data);
print_r($save);
```
> 3、自增 `inc`
* `inc` 方法自增一个字段的值
```php
示例:
# 字段的值增加1
$inc = Db::table('user')->where('uid',6)->inc('age')->update();
print_r($inc);
# 字段的值增加5
$inc = Db::table('user')->where('uid',7)->inc('age',5)->update();
print_r($inc);
```
> 4、自减 `dec`
* `dec` 方法自减一个字段的值
```php
示例:
# 字段的值减去1
$dec = Db::table('user')->where('uid',8)->dec('age')->update();
print_r($dec);
# 字段的值减去5
$dec = Db::table('user')->where('uid',9)->dec('age',5)->update();
print_r($dec);
```
---
### 五、删除
> 1、删除数据 `delete`
* `delete` 方法返回影响数据的条数,没有删除返回 0
```php
示例:
# 根据条件删除数据
$delete = Db::table('user')->where('uid',1)->delete();
print_r($delete);
# 删除主键为2的数据
$delete = Db::table('user')->delete(2);
print_r($delete);
# 删除整表数据
$delete = Db::name('user')->delete(true);
print_r($delete);
```
> 2、软删除 `useSoftDelete`
* 业务数据不建议真实删除数据,TP系统提供了软删除机制
```php
示例:
# 软删除
$delete = Db::name('user')->useSoftDelete('status',2)->delete();
print_r($delete);
```
---
### 备注
> 增删查改是常规操作
> 下面的教程 在增删查改基础上 增加更多功能
---
### 六、查询表达式
**表达式**|**含义**|**快捷查询方法**
---|---|---|---
=|等于|
<>|不等于|
>|大于|
>=|大于等于|
<|小于|
<=|小于等于|
[NOT] LIKE|模糊查询|`whereLike/whereNotLike`
[NOT] BETWEEN|区间查询|`whereBetween/whereNotBetween`
[NOT] IN|IN 查询|`whereIn/whereNotIn`
[NOT] NULL|查询字段是否为NULL|`whereNull/whereNotNull`
* > < >= <= 是给数字使用
* = <> 可以给字符串使用,也可以用在数字
> 1、表达式
* 表达式是SQL语句的条件
* 表达式不分大小写
* 表达式写在where里
```php
示例:
# 等于(=)
$select = Db::table('user')->where('uid','=','1')->select();
print_r($select);
# 不等于(<>)
$select = Db::table('user')->where('uid','<>','2')->select();
print_r($select);
# 大于(>)
$select = Db::name('user')->where('uid','>','3')->select();
print_r($select);
# 大于等于(>=)
$select = Db::name('user')->where('uid','>=','4')->select();
print_r($select);
# 小于(<)
$select = Db::name('user')->where('uid','<','5')->select();
print_r($select);
# 小于等于(<=)
$select = Db::name('user')->where('uid','<=','6')->select();
print_r($select);
# LIKE
$select = Db::name('user')->where('u_name','like','欧阳%')->select();
print_r($select);
$select = Db::name('user')->whereLike('u_name','欧阳%')->select();
print_r($select);
# NOT LIKE
$select = Db::name('user')->where('u_name','not like','欧阳%')->select();
print_r($select);
$select = Db::name('user')->whereNotLike('u_name','欧阳%')->select();
print_r($select);
# BETWEEN
$select = Db::name('user')->where('uid','between','4,7')->select();
print_r($select);
$select = Db::name('user')->whereBetween('uid','4,7')->select();
print_r($select);
# NOT BETWEEN
$select = Db::name('user')->where('uid','not between','4,7')->select();
print_r($select);
$select = Db::name('user')->whereNotBetween('uid','4,7')->select();
print_r($select);
# IN
$select = Db::name('user')->where('uid','in','4,7')->select();
print_r($select);
$select = Db::name('user')->whereIn('uid','4,7')->select();
print_r($select);
# NOT IN
$select = Db::name('user')->where('uid','not in','4,7,10')->select();
print_r($select);
$select = Db::name('user')->whereNotIn('uid','4,7')->select();
print_r($select);
# NULL
$select = Db::name('user')->where('u_name',null)->select();
$select = Db::name('user')->where('u_name','null')->select();
$select = Db::name('user')->where('u_name','=','null')->select(); // 字符串不为空
print_r($select);
$select = Db::name('user')->whereNull('u_name')->select();
print_r($select);
# NOT NULL
$select = Db::name('user')->where('u_name','not null')->select();
print_r($select);
$select = Db::name('user')->whereNotNull('u_name')->select();
print_r($select);
```
---
### 七、链式查询
**连贯操作**|**作用**|**支持的参数类型**
---|---|---|---
where|用于AND查询|字符串、数组和对象
table|用于定义要操作的数据表名称|字符串和数组
alias|用于给当前数据表定义别名|字符串
field|用于定义要查询的字段(支持字段排除)|字符串和数组
order|用于对结果排序|字符串和数组
limit|用于限制查询结果数量|字符串和数字
page|用于查询分页(内部会转换成limit)|字符串和数字
join|用于对查询的join支持|字符串和数组
union|用于对查询的union支持|字符串、数组和对象
distinct|用于查询的distinct支持|布尔值
> 1、`where` 方法主要用于数据库查询条件
* 普通查询、表达式查询、快捷查询、区间查询、组合查询
```php
示例:
# 字符串查询:
$select = Db::table('user')->where('status=1')->select();
print_r($select);
# 表达式查询:官方推荐使用的查询方式
$select = Db::table('user')
->where('uid','>',1)
->where('u_name','黄蓉')
->select();
print_r($select);
# 数组条件:数组条件,会有更复杂的查询
$select = Db::table('user')->where([
'u_name' => '杨康',
'status'=> 1
])->select();
print_r($select);
```
> 2、`table` 方法主要用于指定操作的数据表
```php
示例:
# 单表查询
$select = Db::table('user')->where('status=1')->select();
print_r($select);
# 多表查询
$select = Db::table('user u,orders o')->where('u.status=1')->select();
print_r($select);
# 数组多表查询
$select = Db::table([
'user' => 'u',
'orders' => 'o'
])->where('u.status=1')->select();
print_r($select);
```
> 3、`alias` 方法主要用于设置当前数据表的别名
```php
示例:
$select = Db::table('user')->alias('u')->where('status=1')->select();
print_r($select);
```
> 4、`field` 方法主要作用是标识要返回或者操作的字段,可以用于查询和写入操作
* `withoutField` 字段排除
* `fieldRaw` 使用mysql函数
```php
示例:
# 返回三个字段
$select = Db::table('user')->field('uid,phone,u_name')->select();
print_r($select);
# 返回字段改名
$select = Db::table('user')->field('uid,phone,u_name as n')->select();
print_r($select);
# 数组
$select = Db::table('user')->field(['uid','phone','u_name'])->select();
print_r($select);
# 字段排除
$select = Db::table('user')->withoutField('uid,status')->select();
print_r($select);
# 使用mysql函数
$select = Db::table('user')->fieldRaw('MAX(age)')->select();
print_r($select);
```
> 5、`order` 方法用于对操作的结果排序或者优先级限制
* 如果没有指定 `desc` 或者 `asc` 排序规则的话,默认为 `asc`
```php
示例:
# 年龄倒序
$select = Db::table('user')->field('uid,phone,u_name,age')->where('status=1')->order('age','desc')->select();
print_r($select);
# 排序数组
$select = Db::table('user')->field('uid,phone,u_name,age')->where('status=1')->order([
'age' => 'desc'
])->select();
print_r($select);
```
> 6、`limit` 方法主要用于指定查询和操作的数量
```php
示例:
# 查询3条数据
$select = Db::table('user')->field('uid,phone,u_name,age')->where('status=1')->order('age','desc')->limit(3)->select();
print_r($select);
# 从第3条开始查询出10条数据
$select = Db::table('user')->field('uid,phone,u_name,age')->where('status=1')->order('age','desc')->limit(3,10)->select();
print_r($select);
```
> 7、`page` 方法主要用于分页查询
```php
示例:
# 从第0条开始查询出10条数据
$select = Db::table('user')->field('uid,phone,u_name,age')->where('status=1')->order('age','desc')->page(0,10)->select();
print_r($select);
# page 组合 limit
$select = Db::table('user')->field('uid,phone,u_name,age')->where('status=1')->order('age','desc')->limit(5)->page(3)->select();
print_r($select);
```
> 8、`join` 方法用于根据两个或多个表中的列之间的关系,从这些表中查询数据。join通常有下面几种类型,不同类型的join操作会影响返回的数据结果
**链式**|**说明**|**示例**
---|---|---
join|内连接,等同于 JOIN(默认的JOIN类型),如果表中有至少一个匹配,则返回行|`join ( mixed join [, mixed $condition = null [, string $type = 'INNER']] )`
leftJoin|左连接,即使右表中没有匹配,也从左表返回所有的行|`leftJoin ( mixed join [, mixed $condition = null ] )`
rightJoin|右连接,即使左表中没有匹配,也从右表返回所有的行|`rightJoin ( mixed join [, mixed $condition = null ] )`
fullJoin|只要其中一个表中存在匹配,就返回行|`fullJoin ( mixed join [, mixed $condition = null ] )`
**参数**|**说明**
---|---
join|要关联的(完整)表名以及别名
condition|关联条件。可以为字符串或数组, 为数组时每一个元素都是一个关联条件
type|关联类型。可以为:`INNER`、`LEFT`、`RIGHT`、`FULL`,不区分大小写,默认为`INNER`
```php
示例:
# 内连接
$select = Db::table('user u')->join('orders o','o.uid = u.uid')->select();
print_r($select);
# 左连接
$select = Db::table('user u')->leftJoin('orders o','o.uid = u.uid')->select();
print_r($select);
# 右连接
$select = Db::table('user u')->rightJoin('orders o','o.uid = u.uid')->select();
print_r($select);
```
* 备:fullJoin操作比较麻烦,使用UNION代替
> 9、`union` 操作用于合并两个或多个 SELECT 语句的结果集
* `union` 内部的 `SELECT` 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 `SELECT` 语句中的列的顺序必须相同
```php
示例:
$select = Db::field('u_name')->table('user')->union('SELECT `u_name` FROM user1')->select();
print_r($select);
```
> 10、`distinct` 方法用于返回唯一不同的值
```php
示例:
$select = Db::table('user')->distinct(true)->select();
print_r($select);
```
---
### 八、聚合查询
**方法**|**功能**
---|---
count|统计数量,参数是要统计的字段名(可选)
max|获取最大值,参数是要统计的字段名(必须)
min|获取最小值,参数是要统计的字段名(必须)
avg|获取平均值,参数是要统计的字段名(必须)
sum|获取总数,参数是要统计的字段名(必须)
```php
示例:
// 统计数量,参数是要统计的字段名(可选)
$select = Db::table('user')->count();
print_r($select);
// 获取最大值,参数是要统计的字段名(必须)
$select = Db::table('user')->max('age');
print_r($select);
// 获取最小值,参数是要统计的字段名(必须)
$select = Db::table('user')->min('age');
print_r($select);
// 获取平均值,参数是要统计的字段名(必须)
$select = Db::table('user')->avg('age');
print_r($select);
// 获取总数,参数是要统计的字段名(必须)
$select = Db::table('user')->sum('age');
print_r($select);
```
---
### 九、分页查询
* `paginate` 分页方法
* 注:`thinkphp` 分页样式是用 `bootstrap`
```php
php示例:
$select = Db::table('user')->paginate(10);
View::assign([
'select' => '$select'
]);
return View::fetch();
```
```html
html示例:
{volist name='select' id='vo'}
<div>{$vo.u_name}</div>
{/volist}
{$list|raw}
```
* 单独获取分页
```php
php示例:
$select = Db::table('user')->paginate(10);
$page = $select->render();
View::assign([
'select' => $select,
'page' => $page,
]);
return View::fetch();
```
```html
html示例:
{volist name='select' id='vo'}
<div>{$vo.u_name}</div>
{/volist}
{$page|raw}
```
* 获取总页数
```php
php示例:
$select = Db::table('user')->paginate(10);
$count = $select->total();
View::assign([
'select' => $select,
'count' => $count,
]);
return View::fetch();
```
```html
html示例:
{volist name='select' id='vo'}
<div>{$vo.u_name}</div>
{/volist}
{$count}
```
```css
bootstrap示例:
.pagination {
display: inline-block;
padding-left: 0;
margin: 20px 0;
border-radius: 4px;
}
.pagination > li {
display: inline;
}
.pagination > li > a,
.pagination > li > span {
position: relative;
float: left;
padding: 6px 12px;
margin-left: -1px;
line-height: 1.42857143;
color: #337ab7;
text-decoration: none;
background-color: #fff;
border: 1px solid #ddd;
}
.pagination > li:first-child > a,
.pagination > li:first-child > span {
margin-left: 0;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
}
.pagination > li:last-child > a,
.pagination > li:last-child > span {
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
}
.pagination > li > a:hover,
.pagination > li > span:hover,
.pagination > li > a:focus,
.pagination > li > span:focus {
z-index: 2;
color: #23527c;
background-color: #eee;
border-color: #ddd;
}
.pagination > .active > a,
.pagination > .active > span,
.pagination > .active > a:hover,
.pagination > .active > span:hover,
.pagination > .active > a:focus,
.pagination > .active > span:focus {
z-index: 3;
color: #fff;
cursor: default;
background-color: #337ab7;
border-color: #337ab7;
}
.pagination > .disabled > span,
.pagination > .disabled > span:hover,
.pagination > .disabled > span:focus,
.pagination > .disabled > a,
.pagination > .disabled > a:hover,
.pagination > .disabled > a:focus {
color: #777;
cursor: not-allowed;
background-color: #fff;
border-color: #ddd;
}
```
---
### 十、`SQL` 调试
* `getLastSql` 输出上次执行的sql语句
```php
// 获取总数,参数是要统计的字段名(必须)
$select = Db::table('user')->sum('age');
print_r($select);
echo Db::getLastSql();
```
* `getLastSql` 方法只能获取最后执行的 `SQL` 记录
```php
// 获取总数,参数是要统计的字段名(必须)
$select = Db::table('user')->fetchSql()->sum('age');
echo $select;
```
* `fetchSql` 方法直接返回当前的 `SQL` 而不执行
---
### 十一、动态配置数据库
* `connect` 方法动态配置数据库连接信息
```php
# 字符串配置
# 格式:数据库类型://用户名:密码@数据库地址:数据库端口/数据库名#字符集
$data = Db::connect('mysql://root:root@127.0.0.1:3306/huangrong#utf8')->table('admin')->find();
print_r($data);
# 数组配置
$data = Db::connect([
// 数据库类型
'type' => 'mysql',
// 数据库连接DSN配置
'dsn' => '',
// 服务器地址
'hostname' => '127.0.0.1',
// 数据库名
'database' => 'huangrong',
// 数据库用户名
'username' => 'root',
// 数据库密码
'password' => 'root',
// 数据库连接端口
'hostport' => '3306',
// 数据库连接参数
'params' => [],
// 数据库编码默认采用utf8
'charset' => 'utf8',
// 数据库表前缀
'prefix' => '',
])->table('admin')->find();
print_r($data);
```
> connect 方法必须在查询的最开始调用,而且必须紧跟着调用查询方法,否则可能会导致部分查询失效或者依然使用默认的数据库连接。
* `config` 目录多数据库配置
```php
return [
// 数据库类型
'type' => 'mysql',
// 服务器地址
'hostname' => '127.0.0.1',
// 数据库名
'database' => 'thinkphp',
// 数据库用户名
'username' => 'root',
// 数据库密码
'password' => '',
// 数据库连接端口
'hostport' => '',
// 数据库连接参数
'params' => [],
// 数据库编码默认采用utf8
'charset' => 'utf8',
// 数据库表前缀
'prefix' => '',
//数据库配置1
'db_config1' => [
// 数据库类型
'type' => 'mysql',
// 服务器地址
'hostname' => '127.0.0.1',
// 数据库名
'database' => 'huangrong',
// 数据库用户名
'username' => 'root',
// 数据库密码
'password' => 'root',
// 数据库编码默认采用utf8
'charset' => 'utf8',
// 数据库表前缀
'prefix' => '',
],
//数据库配置2
'db_config2' => 'mysql://root:root@127.0.0.1:3306/huangrong#utf8',
];
```
```php
Db::connect('db_config1')->table('user')->find();
```
- 序言
- PHP基础
- 认识PHP
- 环境安装
- PHP语法
- 流程控制
- PHP数组
- PHP函数
- PHP类与对象
- PHP命名空间
- PHP7新特性
- PHP方法库
- PHP交互
- 前后端交互
- 项目常规开发流程
- MySQL数据库
- 会话控制
- Ajax分页技术
- 细说函数
- 类与对象
- 对象进阶
- 类与对象进阶
- OOP面向对象
- 设计模式
- 路由与模板引擎
- 异常类
- PHP爬虫
- PHP抓取函数
- PHP匹配函数
- 正则表达式
- PHP字符串函数
- 抓取实战
- PHP接口
- 了解接口
- PHP插件
- PHPSpreadsheet
- ThinkPHP6
- 安装
- 架构
- 数据库
- 数据库操作
- 视图
- 模版
- 模型
- 杂项
- 命令行
- 交互
- 微信小程序
- 介绍
- 配置
- 组件
- 交互
- API
- 其他知识
- 百度小程序
- 介绍
- 配置
- 组件
- 交互
- API
- 其他知识
- Linux
- 服务器上线流程
- 安装svn
- MySQL
- 认识MySQL
- MySQL函数
- 杂项
- composer依赖管理工具