勾股OA在线文档

高级查询

快捷查询

快捷查询方式是一种多字段相同查询条件的简化写法,可以进一步简化查询条件的写法,在多个字段之间用|分割表示OR查询,用&分割表示AND查询,可以实现下面的查询,例如:

Db::name('Admin')
    ->where('name|title','like','勾股OA%')
    ->where('create_time&update_time','>',0)
    ->find();

生成的查询SQL是:

SELECT * FROM `oa_admin` WHERE ( `name` LIKE '勾股OA%' OR `title` LIKE '勾股OA%' ) AND ( `create_time` > 0 AND `update_time` > 0 ) LIMIT 1

快捷查询支持所有的查询表达式。

批量(字段)查询

可以进行多个条件的批量条件查询定义,例如:

Db::name('Admin')
    ->where([
        ['name', 'like', '勾股OA%'],
        ['title', 'like', '%勾股OA'],
        ['id', '>', 0],
        ['status', '=', 1],
    ])
    ->select();

生成的SQL语句为:

SELECT * FROM `oa_admin` WHERE `name` LIKE '勾股OA%' AND `title` LIKE '%勾股OA' AND `id` > 0 AND `status` = '1'

数组方式如果使用exp查询的话,一定要用raw方法。

Db::name('Admin')
    ->where([
        ['name', 'like', '勾股OA%'],
        ['title', 'like', '%勾股OA'],
        ['id', 'exp', Db::raw('>score')],
        ['status', '=', 1],
    ])
    ->select();

数组查询方式,确保你的查询数组不能被用户提交数据控制,用户提交的表单数据应该是作为查询数组的一个元素传入,如下:

Db::name('Admin')
    ->where([
        ['name', 'like', $name . '%'],
        ['title', 'like', '%' . $title],
        ['id', '>', $id],
        ['status', '=', $status],
    ])
    ->select();

注意,相同的字段的多次查询条件可能会合并,如果希望某一个where方法里面的条件单独处理,可以使用下面的方式,避免被其它条件影响。

$map = [
        ['name', 'like', '勾股OA%'],
        ['title', 'like', '%勾股OA'],
        ['id', '>', 0],
    ];
Db::name('Admin')
    ->where([ $map ])
    ->where('status',1)
    ->select();

生成的SQL语句为:

SELECT * FROM `oa_admin` WHERE ( `name` LIKE '勾股OA%' AND `title` LIKE '%勾股OA' AND `id` > 0 ) AND `status` = '1'

如果使用下面的多个条件组合

$map1 = [
        ['name', 'like', '勾股OA%'],
        ['title', 'like', '%勾股OA'],
    ];

$map2 = [
        ['name', 'like', '勾股CMS%'],
        ['title', 'like', '%勾股CMS'],
    ];
Db::table('think_user')
    ->whereOr([ $map1, $map2 ])
    ->select();

生成的SQL语句为:

SELECT * FROM `oa_admin` WHERE ( `name` LIKE '勾股OA%' AND `title` LIKE '%勾股OA' ) OR ( `name` LIKE '勾股CMS%' AND `title` LIKE '%勾股CMS' )

善用多维数组查询,可以很方便的拼装出各种复杂的SQL语句

闭包查询

$name = '勾股OA';
$id = 10;
Db::name('Admin')->where(function ($query) use($name, $id) {
    $query->where('name', $name)
        ->whereOr('id', '>', $id);
})->select();

生成的SQL语句为:

SELECT * FROM `oa_admin` WHERE ( `name` = '勾股OA' OR `id` > 10 )

每个闭包条件两边也会自动加上括号。

混合查询

可以结合前面提到的所有方式进行混合查询,例如:

Db::name('Admin')
    ->where('name', 'like', '勾股OA%')
    ->where(function ($query) {
        $query->where('id', '<', 10);
    })
    ->select();

生成的SQL语句是:

SELECT * FROM `oa_admin` WHERE  `name` LIKE '勾股OA%' AND ( `id` < 10 )

字符串条件查询

对于一些实在复杂的查询,也可以直接使用原生SQL语句进行查询,例如:

Db::name('Admin')
    ->whereRaw('id > 0 AND name LIKE "勾股OA%"')
    ->select();

为了安全起见,我们可以对字符串查询条件使用参数绑定,例如:

Db::name('Admin')
    ->whereRaw('id > :id AND name LIKE :name ', ['id' => 0, 'name' => '勾股OA%'])
    ->select();

两个字段比较查询

在ThinkPHP6中,可以利用模型或者DB类来进行两个字段比较查询查询。
1、假设有两个字段分别是field1和field2,并且想找出field2字段比field1大于等于10的所有记录,可以采用以下的方式编写查询:

// 闭包形式
Db::name('Admin')->where(function ($query) {
    $query->whereRaw('field2 - field1 >= 10');
})->select();

2、假设有两个字段分别是field1和field2,并且想找出这两个字段值相差不超过10的所有记录,可以采用以下的方式编写查询:

// 使用闭包形式(ThinkPHP6支持链式调用)
Db::name('Admin')->where(function ($query) {
    $query->whereRaw('field1 >= field2 - 10')->whereRaw('field1 <= field2 + 10');
})->select();

// 构造查询条件
Db::name('Admin')->whereRaw('ABS(field1 - field2) <= 10')->select();

// 如果字段都是正数,且无需绝对值判断,当field1和field2都在field2 ± 10范围内时
Db::name('Admin')->whereBetween('field1', ['field2 - 10', 'field2 + 10'])->select();

快捷方法

系统封装了一系列快捷方法,用于简化查询,包括:

方法 作用
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方法的用法。

查询update_time大于create_time的用户数据

Db::name('Admin')->whereColumn('update_time','>','create_time')->select();

生成的SQL语句是:

SELECT * FROM `oa_admin` WHERE ( `update_time` > `create_time` )

查询name和nickname相同的用户数据

Db::name('Admin')->whereColumn('name','=','nickname')->select();

生成的SQL语句是:

SELECT * FROM `oa_admin` WHERE ( `name` = `nickname` )

相同字段条件也可以简化为

Db::name('Admin')->whereColumn('name','nickname')->select();

支持数组方式比较多个字段

Db::name('Admin')->whereColumn([
    ['title', '=', 'name'],
    ['update_time', '>=', 'create_time'],
])->select();

生成的SQL语句是:

SELECT * FROM `oa_admin` WHERE ( `name` = `nickname` AND `update_time` > `create_time` )

动态查询

查询构造器还提供了动态查询机制,用于简化查询条件,包括:

动态查询 描述
whereFieldName 查询某个字段的值
whereOrFieldName 查询某个字段的值
getByFieldName 根据某个字段查询
getFieldByFieldName 根据某个字段获取某个值

其中FieldName表示数据表的实际字段名称的驼峰法表示,假设数据表admin中有email和nick_name字段,我们可以这样来查询。

// 根据邮箱(email)查询用户信息
Db::name('Admin')->whereEmail('hdm58@qq.com')->find();

// 根据昵称(nick_name)查询用户
Db::name('Admin')->whereNickName('like', '%勾股%')->select();

// 根据邮箱查询用户信息
Db::name('Admin')->getByEmail('hdm58@qq.com');

// 根据昵称(nick_name)查询用户信息
Db::name('Admin')->field('id,name,nick_name,email')->getByNickName('勾股');

// 根据邮箱查询用户的昵称
Db::name('Admin')->getFieldByEmail('hdm58@qq.com', 'nick_name');

// 根据昵称(nick_name)查询用户邮箱
Db::name('Admin')->getFieldByNickName('勾股', 'email');

getBygetFieldBy方法只会查询一条记录,可以和其它的链式方法搭配使用

条件查询

查询构造器支持条件查询,例如:

Db::name('Admin')->when($condition, function ($query) {
    // 满足条件后执行
    $query->where('score', '>', 80)->limit(10);
})->select();

并且支持不满足条件的分支查询

Db::name('Admin')->when($condition, function ($query) {
    // 满足条件后执行
    $query->where('score', '>', 80)->limit(10);
}, function ($query) {
    // 不满足条件执行
    $query->where('score', '>', 60);
});

多条件搜索 and 查询

$map = [];

//条件
$map[] = ['status', '=', 1];
$map[] = ['type', '=', $type];
$map[] = ['url', 'like', $url. '%'];
$map[] = ['date', 'between time', [$startTime, $endTime]];

$list = Db::name('message')
    ->where($map)
    ->order($order)
    ->paginate(['list_rows' => $rows, 'query' => $param])
    ->toArray();

多条件搜索 or 查询

$map1 = [];
$map2 = [];

//条件1
$map1[] = ['status', '=', 1];
$map1[] = ['type', '=', $type];
$map1[] = ['date', 'between time', [$startTime, $endTime]];

//条件2
$map2[] = ['status', '=', 0];
$map2[] = ['type', '=', $type];
$map2[] = ['date', '>', $endTime];
$map2[] = ['date', '<', $startTime];

$list = Db::name('Flow')
    ->field('id,name,check_type')
    ->whereOr([$map1,$map2])
    ->order('id desc')
    ->paginate(['list_rows' => $rows, 'query' => $param])
    ->toArray();

多条件搜索 orand 联合查询

例子一:

$map1=[
    ['admin_id','=',$this->uid],
];
$map2=[
    ['director_uid','=',$this->uid],
];
$map3=[
    ['check_uid','=',$this->uid],
];
$where=[['delete_time','=',0],['status','>',0]];
$whereOr =[$map1,$map2,$map3];
$list = Db::name('Project')
->where(function ($query) use($whereOr) {
    if (!empty($whereOr)){
        $query->whereOr($whereOr);
    }
})
->where($where)
->paginate(['list_rows' => $rows, 'query' => $param])
->toArray();

生成的SQL语句是:

SELECT * FROM `oa_project` WHERE (`admin_id` = $this->uid OR `director_uid` = $this->uid OR `check_uid` = $this->uid) and  `delete_time` = 0  and 'status' > 0

例子二:

$list = Db::name('Project')->where(function($query) {
    $query->where('key1', value)->whereor('key1',value1);
})->whereor(function($query){
    $query->where(['key2'=>value2]->whereor(['key3'=>value3]))
})->field('key4')->find();

生成的SQL语句是:

SELECT * FROM `oa_project` WHERE (`key1` = value OR `key1` = value1 ) OR ( `key2` = 'value2' OR `key3` = 'value3')

复杂的FIND_IN_SET查询,且接收变量的查询

例子一

//变量
$type = 1;
$department =1;

//查询条件
$map1 = [];
$map2 = [];
$map1[] = ['status', '=', 1];
$map1[] = ['type', '=', $type];
$map1[] = ['department_ids', '=', ''];

$map2[] = ['status', '=', 1];
$map2[] = ['type', '=', $type];
$map2[] = ['', 'exp', Db::raw("FIND_IN_SET('{$department}',department_ids)")];

$list = Db::name('Flow')
    ->field('id,name,check_type')
    ->whereOr([$map1,$map2])
    ->order('id desc')
    ->paginate(['list_rows' => $rows, 'query' => $param])
    ->toArray();

例子二

$where = array();
$whereOr = array();
if (!empty($param['keywords'])) {
    $where[] = ['id|name|name', 'like', '%' . $param['keywords'] . '%'];
}
if (!empty($param['cate_id'])) {
    $where[] = ['cate_id', '=', $param['cate_id']];
}
$where[] = ['delete_time', '=', 0];
$where[] = ['archive_status', '=', 1];
$uid = $this->uid;
if($uid!=1){
    $whereOr[] =['admin_id|prepared_uid|sign_uid|keeper_uid', '=', $uid];
    $whereOr[] = ['', 'exp', Db::raw("FIND_IN_SET('{$uid}',share_ids)")];
}
$list = Db::name('Flow')
    ->field('id,name,check_type')
    ->where($where)
    ->where(function ($query) use($whereOr) {
        if (!empty($whereOr)){
            $query->whereOr($whereOr);
        }
    })
    ->order('id desc')
    ->paginate(['list_rows' => $rows, 'query' => $param])
    ->toArray();