连接数据库
字符串连接的定义格式为:
数据库类型://用户名:密码@数据库地址:数据库端口/数据库名#字符集
配置文件
database.php
方法配置
Db::connect方法动态配置数据库连接信息
* 动态连接数据库的connect
方法仅对当次查询有效。
Db::connect('db_config1')->table('user')->find();
这种方式的动态连接和切换数据库比较方便,经常用于多数据库连接的应用需求。
模型类定义
<?php
namespace app\index\model;
use think\Model;
class User extends Model
{
// 直接使用配置参数名
protected $connection = 'db_config1';
}
查询构造器
助手函数
db
方法的第一个参数的作用和name
方法一样,如果需要使用不同的数据库连接,可以使用:
db('user','db_config1')->where('id', 1)->find();
table()和name()
table方法必须指定完整的数据表名
如果你的数据表没有设置表前缀的话,那么
name
和table
方法效果一致。
查询数据
查询单个数据
find() | 查询结果不存在,返回 null,否则返回结果数组 |
findOrFail() | 没有找到数据,抛出一个think\db\exception\DataNotFoundException异常 |
findOrEmpty() | 查询不存在的时候返回空数组(V5.1.23+) |
查询多个数据(数据集)
select() | 查询结果是一个二维数组,如果结果不存在,返回空数组 |
selectOrFail() | 没有查找到数据,抛出一个think\db\exception\DataNotFoundException 异常 |
值和列查询
value('字段名') | 返回某个字段的值,查询结果不存在,返回 null |
column('字段名') | 返回数组,查询结果不存在,返回空数组 |
column('字段名','id') | 指定id字段值作为索引 |
column('*','id') | 指定id字段的值作为索引 返回所有数据 |
添加数据
添加一条数据
insert($data) | 添加数据成功返回添加成功的条数,通常情况返回 1 |
data($data)->insert() | 数据表里面没有$data中的字段,会抛出异常 |
strict(false)->insert($data) | 不存在的字段的值将会直接抛弃 |
insert($data,true) | 支持replace 写入(需要设置唯一索引) |
insertGetId($data) | 添加数据成功返回添加数据的自增主键 |
添加多条数据
insertAll($data) | 成功返回添加成功的条数 |
insertAll($data,true) | 支持replace 写入(MySQL)(需要设置唯一索引) |
data($data)->insertAll() | 确保要批量添加的数据字段是一致的 |
strict(false)->insertAll($data) | 不存在的字段的值将会直接抛弃 |
data($data)->limit(100)->insertAll() | 分批写入 每次最多100条数据 |
更新数据
更新数据
where($where)->update($data) | 返回影响数据的条数,没修改任何数据返回 0 |
data($data) ->update() | 如果update 方法和data 方法同时传入更新数据,则会进行合并 |
update($data) | 数据中包含主键,可以直接使用 |
where($where) ->inc('read_time') ->dec('score',3) ->exp('name','UPPER(name)') ->update() | 使用SQL 函数 |
where('id', 1) ->update([ 'name' => Db::raw('UPPER(name)'), 'score' => Db::raw('score-3'), 'read_time' => Db::raw('read_time+1') ]) | V5.1.7+ 版本以后,支持使用raw 方法进行数据更新,适合在数组更新的情况 |
更新字段值
setField('字段名','字段值') | 返回影响数据的条数,没修改任何数据字段返回 0 |
setInc/setDec | 自增或自减一个字段的值( 如不加第二个参数,默认步长为1)返回影响数据的条数 |
删除数据
delete(1)/delete([1,2,3]) | 根据主键删除,返回影响数据的条数,没有删除返回 0 |
where($where)->delete() | 条件删除,返回影响数据的条数,没有删除返回 0 |
delete(true) | 无条件删除所有数据 |
查询表达式
查询表达式的使用格式:
where('字段名','表达式','查询条件');
whereOr('字段名','表达式','查询条件');
5.1
新的查询方法:
whereField('表达式','查询条件');
whereOrField('表达式','查询条件');
* Field
使用字段的驼峰命名方式。
表达式
表达式 | 含义 | 快捷查询方法 | 例子 |
---|---|---|---|
= | 等于 | where('id','=',100) where('id',100) | |
<> | 不等于 | where('id','<>',100) | |
> | 大于 | where('id','>',100) | |
>= | 大于等于 | where('id','>=',100) | |
< | 小于 | where('id','<',100) | |
<= | 小于等于 | where('id','<=',100) | |
[NOT] LIKE | 模糊查询 | whereLike/whereNotLike | where('name','like','thinkphp%') where('name','like',['%think','php%'],'OR') whereLike('name','thinkphp%') whereNotLike('name','thinkphp%') |
[NOT] BETWEEN | (不在)区间查询 | whereBetween/whereNotBetween | where('id','between','1,8') where('id','between',[1,8]) whereBetween('id','1,8') whereNotBetween('id','1,8') |
[NOT] IN | (不在)IN 查询 | whereIn/whereNotIn | where('id','in','1,5,8') where('id','in',[1,5,8]) whereIn('id','1,5,8') whereNotIn('id','1,5,8') |
[NOT] NULL | 查询字段是否(不)是NULL | whereNull/whereNotNull | where('email','null') whereNull('name') whereNotNull('name') |
[NOT] EXISTS | EXISTS查询 | whereExists/whereNotExists | |
[NOT] REGEXP | 正则(不)匹配查询(仅支持Mysql) | ||
[NOT] BETWEEM TIME | 时间区间比较 | whereBetweenTime | |
> TIME | 大于某个时间 | whereTime | |
< TIME | 小于某个时间 | whereTime | |
>= TIME | 大于等于某个时间 | whereTime | |
<= TIME | 小于等于某个时间 | whereTime | |
EXP | 表达式查询,支持SQL语法 | whereExp | where('id','exp',' IN (1,3,8) ') |
时间查询
使用where
方法
// 大于某个时间
where('create_time', '> time', '2016-1-1');
// 小于某个时间
where('create_time', '<= time', '2016-1-1');
// 时间区间查询
where('create_time', 'between time', ['2015-1-1', '2016-1-1']);
第三个参数可以传入任何有效的时间表达式,会自动识别你的时间字段类型,支持的时间类型包括
timestamps
、datetime
、date
和int
。
使用whereTime
方法
// 大于某个时间
>whereTime('birthday', '>=', '1970-10-1')
whereTime('birthday', '1970-10-1')
// 小于某个时间
whereTime('birthday', '<', '2000-10-1')
// 时间区间查询
whereTime('birthday', 'between', ['1970-10-1', '2000-10-1'])
whereTime('birthday', ['1970-10-1', '2000-10-1'])
// 不在某个时间区间
whereTime('birthday', 'not between', ['1970-10-1', '2000-10-1'])
// 查询2017年6月1日注册的用户(查询某天)
whereTime('create_time',['2017-06-01', '2017-06-02'])
使用whereBetweenTime快速方法
// 查询2017年上半年注册的用户
whereBetweenTime('create_time', '2017-01-01', '2017-06-30')
// 查询2017年6月1日注册的用户
whereBetweenTime('create_time', '2017-06-01')
* 没有指定结束时间的话,表示查询当天
使用whereBetweenTimeField方法
whereBetweenTimeField('start_time','end_time')
//相当于
whereTime('start_time', '<=', time())
->whereTime('end_time', '>=', time())
时间表达式
// 获取今天的博客
whereTime('create_time', 'today')
whereTime('create_time', 'd')
// 获取昨天的博客
whereTime('create_time', 'yesterday')
// 获取本周的博客
whereTime('create_time', 'week')
whereTime('create_time', 'w')
// 获取上周的博客
whereTime('create_time', 'last week')
// 获取本月的博客
whereTime('create_time', 'month')
whereTime('create_time', 'm')
// 获取上月的博客
whereTime('create_time', 'last month')
// 获取今年的博客
whereTime('create_time', 'year')
whereTime('create_time', 'y')
// 获取去年的博客
whereTime('create_time', 'last year')
// 查询两个小时内的博客
whereTime('create_time','-2 hours')
高级查询
快捷查询
一种多字段相同查询条件的简化写法,在多个字段之间用|
分割表示OR
查询,用&
分割表示AND
查询
where('name|title','like','thinkphp%')
区间查询
一种同一字段多个查询条件的简化写法
where('name', ['like', '%thinkphp%'], ['like', '%kancloud%'], 'or')
where('id', ['>', 0], ['<>', 10], 'and')
* 区间查询的查询条件必须使用数组定义方式,支持所有的查询表达式。
批量(字段)查询
where([
['name', 'like', 'thinkphp%'],
['title', 'like', '%thinkphp'],
['id', '>', 0],
['status', '=', 1],
])
where([
['name', 'like', 'thinkphp%'],
['title', 'like', '%thinkphp'],
['id', 'exp', Db::raw('>score')],
['status', '=', 1],
])
* V5.1.7+
版本数组方式如果使用exp
查询的话,一定要用raw
方法。
$map = [
['name', 'like', 'thinkphp%'],
['title', 'like', '%thinkphp'],
['id', '>', 0],
];
Db::table('think_user')
->where([ $map ])
->where('status',1)
->select();
SELECT * FROM `think_user` WHERE ( `name` LIKE 'thinkphp%' AND `title` LIKE '%thinkphp' AND `id` > 0 ) AND `status` = '1'
* 相同的字段的多次查询条件可能会合并
快捷方法
方法 | 作用 |
---|---|
whereOr | 字段OR查询 |
whereXor | 字段XOR查询 |
whereNull | 查询字段是否为Null |
whereNotNull | 查询字段是否不为Null |
whereIn | 字段IN查询 |
whereNotIn | 字段NOT IN查询 |
whereBetween | 字段BETWEEN查询 |
whereNotBetween | 字段NOT BETWEEN查询 |
whereLike | 字段LIKE查询 |
whereNotLike | 字段NOT LIKE查询 |
whereExists | EXISTS条件查询 |
whereNotExists | NOT EXISTS条件查询 |
whereExp | 表达式查询 |
whereColumn | 比较两个字段 |
whereColumn('name','=','nickname')
whereColumn([
['title', '=', 'name'],
['update_time', '>=', 'create_time'],
])
动态查询
动态查询 | 描述 | 例子 |
---|---|---|
whereFieldName | 查询某个字段的值 | whereNickName('like', '%流年%') |
whereOrFieldName | 查询某个字段的值 | |
getByFieldName | 根据某个字段查询 | getByNickName('流年') |
getFieldByFieldName | 根据某个字段获取某个值 | getFieldByNickName('流年', 'email') |
子查询
使用fetchSql
方法
不进行查询而只是返回构建的SQL语句
$subQuery = Db::table('think_user')
->field('id,name')
->where('id', '>', 10)
->fetchSql(true)
->select();
使用buildSql
构造子查询
调用buildSql方法后不会进行实际的查询操作,而只是生成该次查询的SQL语句(为了避免混淆,会在SQL两边加上括号),然后我们直接在后续的查询中直接调用。
$subQuery = Db::table('think_user')
->field('id,name')
->where('id', '>', 10)
->buildSql();
Db::table($subQuery . ' a')
->where('a.name', 'like', 'thinkphp')
->order('id', 'desc')
->select();
原生查询
query
方法
用于执行SQL
查询操作,如果数据非法或者查询错误则返回false,否则返回查询结果数据集
Db::query("select * from think_user where status=1");
如果你当前采用了分布式数据库,并且设置了读写分离的话,query方法始终是在读服务器执行,因此query方法对应的都是读操作,而不管你的SQL语句是什么。
execute
方法
用于更新和写入数据的sql操作,如果数据非法或者查询错误则返回false
,否则返回影响的记录数
Db::execute("update think_user set name='thinkphp' where status=1");
如果你当前采用了分布式数据库,并且设置了读写分离的话,execute方法始终是在写服务器执行,因此execute方法对应的都是写操作,而不管你的SQL语句是什么。
聚合查询
方法 | 说明 |
---|---|
count | 统计数量,参数是要统计的字段名(可选) |
max | 获取最大值,参数是要统计的字段名(必须) max('name',false) 最大值不是一个数值,可以使用第二个参数关闭强制转换 |
min | 获取最小值,参数是要统计的字段名(必须) |
avg | 获取平均值,参数是要统计的字段名(必须) |
sum | 获取总分,参数是要统计的字段名(必须) |
* 聚合方法如果没有数据,默认都是0,聚合查询都可以配合其它查询条件
链式操作
where
表达式查询 | where('id','>',1) | |
数组条件 | 关联数组 | where([ where([
|
索引数组 | where([ $map[] = ['name','=','thinkphp']; | |
字符串条件 | where('type=1 AND status=1') |
table
table方法指定的数据表需要完整的表名,但可以采用name
方式简化数据表前缀的传入
对多表进行操作
table('think_user user,think_role role')
table(['think_user'=>'user','think_role'=>'role'])
alias
table('think_user')
->alias('a')
->join('think_dept b ','b.user_id= a.id')
table('think_user')
->alias(['think_user'=>'user','think_dept'=>'dept'])
->join('think_dept','dept.user_id= user.id')
field
field('id,title,content')
//别名
field('id,nickname as name')
//使用SQL函数
field('id,SUM(score)')
//V5.1.7+版本开始,如果需要使用SQL函数
fieldRaw('id,SUM(score)')
//支持数组
field(['id','title','content'])
//定义别名
field(['id','nickname'=>'name'])
//复杂字段
field(['id','concat(name,"-",id)'=>'truename','LEFT(title,7)'=>'sub_title'])
* 对于带有复杂SQL函数的字段需求必须使用数组方式
//字段排除
field('user_id,content',true)
//或者用
field(['user_id','content'],true)
* 注意的是 字段排除功能不支持跨表和join操作。
strict
// 关闭字段严格检查
strict(false)
order
order('id', 'desc')
order(['order','id'=>'desc'])
//V5.1.7+版本开始,如果你需要在order方法中使用mysql函数
orderRaw("field(name,'thinkphp','onethink','kancloud')")
group
group('user_id')
group('user_id,test_time')
having
having('count(test_time)>3')
join
join ( mixed join [, mixed $condition = null [, string $type = 'INNER']] )
leftJoin ( mixed join [, mixed $condition = null ] )
rightJoin ( mixed join [, mixed $condition = null ] )
fullJoin ( mixed join [, mixed $condition = null ] )
distinct
distinct(true)
lock
Lock
方法是用于数据库的锁机制,如果在查询或者执行操作的时候使用:
Db::name('user')->where('id',1)->lock(true)->find();
force
force 方法用于数据集的强制索引操作,例如:
Db::table('think_user')->force('user')->select();
failException
failException
设置查询数据为空时是否需要抛出异常,如果不传入任何参数,默认为开启,用于select
和find
方法,例如:
// 数据不存在的话直接抛出异常
Db::name('blog')
->where('status',1)
->failException()
->select();
// 数据不存在返回空数组 不抛异常
Db::name('blog')
->where('status',1)
->failException(false)
->select();
或者可以使用更方便的查空报错
// 查询多条
Db::name('blog')
->where('status', 1)
->selectOrFail();
// 查询单条
Db::name('blog')
->where('status', 1)
->findOrFail();
事务
// 启动事务
Db::startTrans();
try {
Db::table('think_user')->find(1);
Db::table('think_user')->delete(1);
// 提交事务
Db::commit();
} catch (\Exception $e) {
// 回滚事务
Db::rollback();
}
* 在事务操作的时候,确保你的数据库连接使用的是同一个。
数据集
数据集对象是think\Collection,
提供了和数组无差别用法,并且另外封装了一些额外的方法。
方法 | 描述 |
---|---|
isEmpty | 是否为空 |
toArray | 转换为数组 |
all | 所有数据 |
merge | 合并其它数据 |
diff | 比较数组,返回差集 |
flip | 交换数据中的键和值 |
intersect | 比较数组,返回交集 |
keys | 返回数据中的所有键名 |
pop | 删除数据中的最后一个元素 |
shift | 删除数据中的第一个元素 |
unshift | 在数据开头插入一个元素 |
reduce | 通过使用用户自定义函数,以字符串返回数组 |
reverse | 数据倒序重排 |
chunk | 数据分隔为多个数据块 |
each | 给数据的每个元素执行回调 |
filter | 用回调函数过滤数据中的元素 |
column | 返回数据中的指定列 |
sort | 对数据排序 |
shuffle | 将数据打乱 |
slice | 截取数据中的一部分 |