0x01 数据库与模型
数据库连接
thinkphp数据库基于pdo模式,可以对不同数据库进行封装处理
在config下的database.php设置数据库连接信息 数据库配置信息
// 数据库类型
\'type\' => \'mysql\',
// 服务器地址
\'hostname\' => \'127.0.0.1\',
// 数据库名
\'database\' => \'tp5.1\',
// 用户名
\'username\' => \'root\',
// 密码
\'password\' => \'root\',
// 端口
\'hostport\' => \'3306\',
// 连接dsn
\'dsn\' => \'\',
// 数据库连接参数
\'params\' => [],
// 数据库编码默认采用utf8
\'charset\' => \'utf8\',
// 数据库表前缀
\'prefix\' => \'tp_\',
// 数据库调试模式
\'debug\' => true,
输出信息
class DataTest extends Controller
{
public function getNoModelDate(){
//$data = Db::Table(\'tp_user\')->select();
$data = Db::Name(\'user\')->select();
return json($data);
}
}
table为表名 name比table多加了数据库前缀
模型输出
在 controller 同级目录下新建 Model 文件 在其中新建 表名.php
<?php
namespace app\test\Model;
use think\Model;
class User extends Model{
}
public function getModelDate(){
$data = User::select();
return json($data);
}
开启应用Trace config->app.php \'app_trace\' => true,
0x02 查询数据
find()
查询一条数据 Db::table(\'tp_user\')->find();
getLastSql()
查询最近一条的原生语句 Db::getLastSql()
where()
查询指定数据 Db::table(\'tp_user\')->where(\'id\', 27)->find 没数据时返回null
findOrFail()
在没有数据时抛出一个异常,而不是null Db::table(\'tp_user\')->where(\'id\', 1)->findOrFail()
findOrEmpty()
在没有数据时抛出空 Db::table(\'tp_user\')->where(\'id\', 1)->findOrEmpty()
db()
助手函数 db,方便查询 Db(\'user\')->select();
value()
查询指定字段的值(单个),没有数据返回 null Db::name(\'user\')->where(\'id\', 27)->value(\'username\');
column()
查询指定列的值(多个),没有数据返回空数组 Db::name(\'user\')->column(\'username\');
指定索引查询 Db::name(\'user\')->column(\'username\', \'id\')
0x03 链式查询
使用 -> 多次连续查询称之为链式查询 当使用 Db::table(\'tp_user\') 返回值为数据库对象
可以将实例保存下来进行反复调用 $user = Db::name(\'user\');
public function test1(){
$user = Db::name(\'user\');
$data1 = $user->where(\'id\', 19)->order(\'id\', \'desc\')->select();
$data2 = $user->select();
var_dump(json($data2));
return Db::getLastSql();
}
可以看到在第二次使用 $user 时还保存第一次的结果
使用removeOption()清理上次保留查询值
$user->removeOption(\'where\')->removeOption(\'order\');
0x04 增删改
新增数据
insert()
使用 insert() 方法新增一条数据
public function insert(){
$data = [
\'username\' => \'灰太狼\',
\'password\' => \'123\',
\'gender\' => \'男\',
\'email\' => \'huitailang@qq.com\',
\'price\' => 90,
\'details\' => \'123\',
\'create_time\' => date(\'Y-m-d H:i:s\')
];
return Db::name(\'user\')->insert($data);
}
添加成功 返回值为1 1为影响的行数
使用 data()方法来设置添加的数据数组 Db::name(\'user\')->data($data)->insert();
在新增成功后返回当前数据 ID Db::name(\'user\')->insertGetId($data);
insertAll()
使用 insertAll() 方法新增多条数据
public function insert(){
$data = [
[
\'username\' => \'灰太狼\',
\'password\' => \'123\',
\'gender\' => \'男\',
\'email\' => \'huitailang@qq.com\',
\'price\' => 90,
\'details\' => \'123\',
\'create_time\' => date(\'Y-m-d H:i:s\')
],
[
\'username\' => \'喜羊羊\',
\'password\' => \'123\',
\'gender\' => \'男\',
\'email\' => \'xiyangyang@qq.com\',
\'price\' => 100,
\'details\' => \'123\',
\'create_time\' => date(\'Y-m-d H:i:s\')
]
];
return json(Db::name(\'user\')->insertAll($data));
}
修改数据
update()
使用 update() 更新数据
public function update(){
$data = [
\'username\' => \'懒羊羊\'
];
$update = Db::name(\'user\')->where(\'id\', 235)->update($data);
返回值为1 更新成功 影响数据数为1
同时使用update 果两边都传入会合并 $update = Db::name(\'user\')->where(\'id\', 235)->data($data)->update([\'password\'=>\'456\']);
如果修改数组中包含主键,那么可以直接修改
public function update(){
$data = [
\'id\' => 21,
\'username\' => \'懒羊羊\'
];
$update = Db::name(\'user\')->update($data);
return $update;
}
inc()/dec()
inc()方法可以对字段增值, dec()方法可以对字段减值
echo Db::name(\'user\')->where(\'id\', 21)->value(\'price\');
$update = Db::name(\'user\')->inc(\'price\', 1)->dec(\'price\', 3)->update($data);
echo Db::name(\'user\')->where(\'id\', 21)->value(\'price\');
可以发现 增值和减值如果同时操作,前面一个会失效
exp()
使用exp()方法可以对字段使用mysql函数 Db::name(\'user\')->exp(\'email\', \'UPPER(email)\')->update($data);
raw()
使用 raw()方法修改更新,更加容易方便
$data1 = [
\'username\' => \'懒羊羊\',
\'email\' => Db::raw(\'UPPER(email)\'),
\'price\' => Db::raw(\'price - 3\'),
\'id\' => 21
];
Db::name(\'user\')->update($data);
setField()
使用 setField()方法可以更新一个字段值
Db::name(\'user\')->where(\'id\', 21)->setField(\'username\', \'喜羊羊\');
setInc()/setDec()
增值/减值的简单做法 setInc()/setDec() 默认步长为1
Db::name(\'user\')->where(\'id\', 38)->setInc(\'price\');
删除数据
delete()
极简删除 根据主键直接删除 返回影响行数
删除单条记录 Db::name(\'user\')->delete(21);
删除多条数据 Db::name(\'user\')->delete([21,22,23]);
正常删除
根据where删除 Db::name(\'user\')->where(\'id\',21)->delete();
删除所有数据 Db::name(\'user\')->delete(true);
0x05 查询表达式
| 表达式 | 含义 | 快捷查询方法 |
|---|---|---|
| = | 等于 | |
| <> | 不等于 | |
| > | 大于 | |
| >= | 大于等于 | |
| < | 小于 | |
| <= | 小于等于 | |
| [NOT] LIKE | 模糊查询 | whereLike/whereNotLike |
| [NOT] BETWEEN | (不在)区间查询 | whereBetween/whereNotBetween |
| [NOT] IN | (不在)IN 查询 | whereIn/whereNotIn |
| [NOT] NULL | 查询字段是否(不)是NULL | whereNull/whereNotNull |
| [NOT] EXISTS | EXISTS查询 | whereExists/whereNotExists |
| [NOT] REGEXP | 正则(不)匹配查询(仅支持Mysql) | |
| [NOT] BETWEEM TIME | 时间区间比较 | whereBetweenTime |
| > TIME | 大于某个时间 | whereTime |
| < TIME | 小于某个时间 | whereTime |
| >= TIME | 大于等于某个时间 | whereTime |
| <= TIME | 小于等于某个时间 | whereTime |
| EXP | 表达式查询,支持SQL语法 | whereExp |
比较查询
$res = Db::name(\'user\')->where(\'id\', \'<>\', 25)->select(); 不等于
模糊查询
Db::name(\'user\')->where(\'username\', \'like\', \'张%\')->select();
Db::name(\'user\')->where(\'username\', \'like\', [\'张%\',\'李%\'], \'OR\')->select();
Db::name(\'user\')->whereLike(\'username\', \'like\', \'张%\')->select();
Db::name(\'user\')->whereNotLike(\'username\', \'like\', \'张%\')->select();
区间查询
Db::name(\'user\')->where(\'id\',\'between\',\'19,25\')->select();
Db::name(\'user\')->where(\'id\',\'between\',[19, 25])->select();
Db::name(\'user\')->whereBetween(\'id\',[19, 25])->select();
Db::name(\'user\')->whereNotBetween(\'id\',[19, 25])->select();
范围查询
Db::name(\'user\')->where(\'id\',\'in\', \'19,21,25\')->select();
Db::name(\'user\')->whereIn(\'id\',\'19,21,25\')->select();
Db::name(\'user\')->whereNotIn(\'id\',\'19,21,25\')->select();
null查询
Db::name(\'user\')->where(\'uid\',\'null\')->select();
Db::name(\'user\')->where(\'uid\',\'not null\')->select();
Db::name(\'user\')->whereNull(\'uid\')->select();
Db::name(\'user\')->whereNotNull(\'uid\')->select();
时间查询
传统方式
使用>、<、>=、<=来筛选匹配时间的数据
Db::name(\'user\')->where(\'create_time\', \'> time\', \'2018-1-1\')->select();
between 关键字来设置时间的区间
Db::name(\'user\')->where(\'create_time\', \'between time\', [\'2018-1-1\', \'2019-12-31\'])->select(); Db::name(\'user\')->where(\'create_time\', \'not between time\', [\'2018-1-1\', \'2019-12-31\'])->select();
快捷查询
whereTime 直接使用>、<、>=、<= 默认大于
Db::name(\'user\')->whereTime(\'create_time\', \'>\', \'2018-1-1\')->select();
between 和 not between
Db::name(\'user\')->whereBetween(\'create_time\', [\'2018-1-1\', \'2019-12-31\'])->select();
whereBetweenTime(),如果只有一个参数就表示一天
Db::name(\'user\')->whereBetweenTime(\'create_time\', \'2018-1-1\', \'2019-12-31\')->select();
固定查询
| 关键词 | 说明 |
|---|---|
| today 或 d | 今天 |
| yesterday | 昨天 |
| week 或 w | 本周 |
| last week | 上周 |
| month 或 m | 本月 |
| last month | 上月 |
| year 或 y | 今年 |
| last year | 去年 |
查询三年内的 Db::name(\'user\')->whereTime(\'create_time\',\'-3 year\')->select();
其他查询
查询是否在有效期内
Db::name(\'event\')->whereBetweenTimeField(\'start_time\',\'end_time\')->select();
等效于
Db::name(\'event\')
->whereTime(\'start_time\', \'<=\', time())
->whereTime(\'end_time\', \'>=\', time())
->select();
聚合查询
| 方法 | 说明 |
|---|---|
| count | 统计数量,参数是要统计的字段名(可选) |
| max | 获取最大值,参数是要统计的字段名(必须) |
| min | 获取最小值,参数是要统计的字段名(必须) |
| avg | 获取平均值,参数是要统计的字段名(必须) |
| sum | 获取总分,参数是要统计的字段名(必须) |
count()
count()方法,求出所查询数据的数量 Db::name(\'user\')->count();
指定 id 空值(Null) 不计算数量 Db::name(\'user\')->count(\'uid\');
max()/min()
max()/min()方法,求出所查询数据字段的最大/小值 Db::name(\'user\')->max(\'price\'); 100
如果不是数值 强制转换 Db::name(\'user\')->max(\'price\', false); 100.00
avg()
avg()方法,求出所查询数据字段的平均值 Db::name(\'user\')->avg(\'price\');
sum()
sum()方法,求出所查询数据字段的总和 Db::name(\'user\')->sum(\'price\');
子查询
fetchSql()
fetchSql方法表示不进行查询而只是返回构建的SQL语句,并且不仅仅支持select,而是支持所有的CURD查询
Db::name(\'one\')->fetchSql()->select();
buildSql()
调用buildSql方法后不会进行实际的查询操作,而只是生成该次查询的SQL语句(为了避免混淆,会在SQL两边加上括号)
Db::name(\'one\')->buildSql();
普通查询
$subQuery = Db::name(\'two\')->field(\'uid\')->where(\'gender\', \'男\')->buildSql(true);
$result = Db::name(\'one\')->where(\'id\',\'exp\', \'IN \'.$subQuery)->select();
闭包查询
$result = Db::name(\'one\')->where(\'id\', \'in\', function ($query) {
$query->name(\'two\')->where(\'gender\', \'男\')->field(\'uid\');
})->select();
原生查询
query()
query方法用于执行SQL查询操作,如果数据非法或者查询错误则返回false,否则返回查询结果数据集(同select方法)。
Db::query(\'select * from tp_user\');
execute()
execute用于更新和写入数据的sql操作,如果数据非法或者查询错误则返回false,否则返回影响的记录数。
Db::execute(\'update tp_user set username="喜羊羊" where id=25\')