thinkphp学习 -- 数据库
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')