Lumen 数据库操作orm

比较常用方法

select 指定字段
from 指定表
join 关联表
where 查询条件
groupBy 分组
having 查询条件
orderBy 排序
find 查询条件加查询
value 值查询
get 列查询
paginate 分页查询
pluck 字段查询,处理成数组
count 个数查询
insert 插入
update 更新
delete 删除
chunk 回调方法处理查询结果
each 回调方法处理查询结果
with 对象关联查询
whereHas 当绑定关系有数据的时候
 

select
设置查询字段

Notice::select('title')->get();
Notice::select(['title', 'content'])->get();

 

selectRaw
查询自定义内容

Notice::selectRaw("count('id') as notice_count")->get();

 

addSelect
在其现有select子句中添加一列查询字段

$query = DB::table('users')->select('name');
$users = $query->addSelect('age')->get();

 

distinct
该distinct方法允许您强制查询返回不同的结果:

$users = DB::table('users')->distinct()->get();

 

from
设置表名属性,table()方法也是通过这个方法设置

DB::table('users')
            ->whereExists(function ($query) {
                $query->select(DB::raw(1))
                      ->from('orders')
                      ->whereRaw('orders.user_id = users.id');
            })
            ->get();

上面的查询其实就是with()方法的原理了,转成sql如下

select * from users
where exists (
    select 1 from orders where orders.user_id = users.id
)

 

join
关联查询,join()方法最后还有两个参数,where, where是关联条件(on,where)
后面的一些join方法(joinWhere,leftJoin,leftJoinWhere,rightJoin,rightJoinWhere,crossJoin)的实现是通过传where调用join()来实现的

$users = DB::table('users')
            ->join('contacts', 'users.id', '=', 'contacts.user_id')
            ->join('orders', 'users.id', '=', 'orders.user_id')
            ->select('users.*', 'contacts.phone', 'orders.price')
            ->get();

cross join(笛卡尔积): mysql的交叉连接,数据分析和统计有时会用得上
cross join相关:https://www.yiibai.com/mysql/cross-join.html
 

joinWhere
join的时候,$where参数的on值换成了where值, 外键关联换成条件

$users = DB::table('users')
            ->joinWhere('contacts', 'contacts.type', '=', '1')
            ->join('orders', 'users.id', '=', 'orders.user_id')
            ->select('users.*', 'contacts.phone', 'orders.price')
            ->get();

 

leftJoin
join的时候,$type参数的inner值换成了left值, 左匹配

$users = DB::table('users')
            ->leftJoin('posts', 'users.id', '=', 'posts.user_id')
            ->get();

 

leftJoinWhere
join的时候,
where参数的on值换成了where值, 外键关联换成条件

$users = DB::table('users')
            ->leftJoinWhere('posts', 'posts.type', '=', '1')
            ->get();

 

rightJoin
同理
 

rightJoinWhere
同理
 

crossJoin
同理
 

where
为了使用方便,where方法提供了多种传值方式, 最后有一个$boolean参数 默认and, 可传or

$user = DB::table('users')->where('name', 'John')->first();
$user = DB::table('users')->where('name', '=', 'John')->first();
$user = DB::table('users')->where([['name', '=', 'John'], ['telephone', '=', '18812341234']])->first();
echo $user->name;

 

orWhere

$users = DB::table('users')
                    ->where('votes', '>', 100)
                    ->orWhere('name', 'John')
                    ->get();

 

groupBy
可传数组或多个参数

Notice::groupBy('title', 'id')->get();
Notice::groupBy(['title', 'id'])->get();

 

having
存在

Notice::having('title', '=', '2')->get();

 

orHaving
或存在

Notice::having('title', '=', '2')->orHaving('title', '=', '1')->get();

 

havingRaw
存在,原生sql

$orders = DB::table('orders')
    ->select('department', DB::raw('SUM(price) as total_sales'))
    ->groupBy('department')
    ->havingRaw('SUM(price) > ?', [2500])
    ->get();

 

orHavingRaw
或存在,原生sql

$orders = DB::table('orders')
    ->select('department', DB::raw('SUM(price) as total_sales'))
    ->groupBy('department')
    ->orHavingRaw('SUM(price) > ?', [2500])
    ->get();

 

orderBy
orderBy只能多个拼接

Notice::orderBy('title')->get();
Notice::orderBy('title')->orderBy('content')->get();

 

orderByDesc
desc排序

Notice::orderByDesc('title')->get();

 

latest
默认按create_at从大到小

public function latest($column = 'created_at')
{
    return $this->orderBy($column, 'desc');
}

 

oldest
默认按create_at从小到大

public function oldest($column = 'created_at')
{
    return $this->orderBy($column, 'asc');
}

 

inRandomOrder
随机排序法 可传参,传同样参数会得到同样的排列

Notice::inRandomOrder()->get();
Notice::inRandomOrder(1)->get();

 

orderByRaw
排序,原生sql

Notice::orderByRaw('title, content')->get();

 

find
注:从源码上看find和findMary是通的,find第一个参数传数组时,会调用findMany方法

Notice::find(1);
Notice::find(1, ['title']);
Notice::find([1,2], ['title']);

 

value
从查询的第一个结果中获取单个列的值

Notice::where('title', 1)->value('title');

 

get
查询列,可指定查询项get(['title', 'content']),

Notice::where('title', 1)->get();

注:该特别注意的是get查询不到结果时返回的是一个空数组,不能直接用!判断
 

paginate
返回指定查询条数的数据,总条数,当前分页之类的

DB::table('notice')->paginate();

 

simplePaginate
同上 返回参数有所删减,数据量较大的查询性能较高

DB::table('notice')->simplePaginate ();

 

cursor
数据量大时,用cursor做遍历会节省很多内存

DB::table('notice')->get();
foreach (DB::table('notice')->cursor() as $notice){
        var_dump($notice);
}

 

chunkById
分次查询,第一个参数是每次查的条数,默认根据id查,如果需定制可在第三个参数传

$noticeArr = [];
$notice = DB::table('notice')->chunkById(10, function($notices) use (&$noticeArr){
    $noticeArr[] = json_decode(json_encode($notices, 256), true);
}, 'notice_id');
var_dump($notice);
var_dump($noticeArr);
exit();

该方法为分页查询,如果涉及更新,需慎用该方法
 

pluck
查询某一个字段,返回该只有该字段的数组集合,第二个参数为指定某个参数为键,返回键值对集合

DB::table('roles')->pluck('title');
DB::table('roles')->pluck('title', 'name');

 

implode
根据查询字段和符号分割

DB::table('notice')->implode('title', ',');//titlea,title2,titlec

 

exists
判断查询记录是否存在

DB::table('notice')->where('status', 1)->exists();//true
DB::table('notice')->where('status', 'a')->exists();//false

 

doesntExist
同exists,返回结果和exists相反

DB::table('notice')->where('status', 1)->exists();//false
DB::table('notice')->where('status', 'a')->exists();//true

 

count
返回个数

DB::table('notice')->where('status', 1)->count();

 

min
最小

DB::table('notice')->min('notice_id');

 

max
最大

DB::table('notice')->max('notice_id');

 

sum
总和

DB::table('notice')->sum('notice_id');

 

avg
平均

DB::table('notice')->avg('notice_id');

 

average
同avg

DB::table('notice')->avg('notice_id');

 

aggregate
查询生成器还提供了各种聚合方法,如计数、max、min、avg和和。您可以在构造查询之后调用这些方法中的任何一种:

DB::table('notice')->aggregate('sum', ['notice_id']);

 

numericAggregate
方法调用aggregate,将结果转数字

DB::table('notice')->numericAggregate('sum', ['notice_id']);

 

insert
插入 返回布尔值

Notice::insert(['title' => 'ad']);
Notice::insert(['title' => 'ad', 'a' => 1]);

 

insertGetId
插入 返回id

Notice::insertGetId(['title' => 'ad']);

 

update
更新 返回布尔值

$notice = Notice::find(1);
$notice->update(['title' => 'ad']);

 

updateOrInsert
更新或插入

Notice::updateOrInsert(['title' => 'ad'], ['content' => 'adcd']);

 

increment
加,字符串会被转成0,然后加1

Notice::increment('title');//该字段加1
Notice::increment('title', 6);//该字段加6

 

decrement
加,字符串会被转成0,然后1

Notice::decrement('title');//该字段减1
Notice::decrement('title', 6);//该字段减6

 

delete
删除

$notice = Notice::find(1);
return $notice->delete();

 

truncate
如果希望截断整个表,该表将删除所有行,并将自动递增ID重置为零,则可以使用截断方法:

DB::table('notice')->truncate();

 

newQuery
获取查询生成器的新实例。

$query = (new Notice())->newQuery();
return $query->find(1);

 

raw
若要创建原始表达式,可以使用Db::raw方法

DB::table('notice')->select(DB::raw('count(*) as notice_count'))->get();

 

__call
当方法不存在时,抛异常

public function __call($method, $parameters)
{
    if (static::hasMacro($method)) {
        return $this->macroCall($method, $parameters);
    }
 
    if (Str::startsWith($method, 'where')) {
        return $this->dynamicWhere($method, $parameters);
    }
 
    $className = static::class;
 
    throw new BadMethodCallException("Call to undefined method {$className}::{$method}()");
}

 

--------------------------------------------分割线----------------------------------------------
 

Illuminate\Database\Query\Builder 加载的代码块

Illuminate\Database\Concerns\BuildsQueries
 

chunk
如果你需要处理成千上万个 Eloquent 结果,可以使用 chunk 命令。chunk 方法会获取一个“组块”的 Eloquent 模型,并将其填充到给定闭包进行处理。使用 chunk 方法能够在处理大量数据集合时能够有效减少内存消耗:

$noticeRes = [
    'success' => 0,
    'fail' => 0,
];
$notice = DB::table('notice')->orderBy('notice_id')->chunk(500, function ($notices) use (&$noticeRes) {
    foreach ($notices as $notice) {
        if($notice->status == 1){
            $noticeRes['success']++;
        }else{
            $noticeRes['fail']++;
        }
    }
});
var_dump($notice);
var_dump($noticeRes);
exit();

 

each
在分组时对每个项执行回调,查询结果为值(value),chunk方法需要循环,each方法内部做了循环

$noticeRes = [
    'success' => 0,
    'fail' => 0,
];
$notice = DB::table('notice')
    ->orderBy('id')
    ->each(function ($notice_value, $notice_key) use (&$noticeRes) {
    if($notice_value->status){
        $noticeRes['success']++;
    }else{
        $noticeRes['fail']++;
    }
}, 500);
var_dump($notice);
var_dump($noticeRes);
exit();

 

--------------------------------------------分割线----------------------------------------------
 

下面是Illuminate\Database\Eloquent\Builder类的大部分方法

 

fromQuery
应该只有复杂查询要写原生的时候才会用到

Notice::fromQuery("select title from notice");
Notice::fromQuery('select title from notice WHERE title = ?', [1]);

 

findMany

Notice::findMany([1,2], ['title']);
Notice::findMany(1, ['title']);

 

findOrFail
这个查不到会直接抛出ModelNotFoundException异常,可以在App\Exceptions\Handler定制异常捕捉

Notice::findOrFail(100);

 

findOrNew
这个查不到会通过newModelInstance方法新建一个模型对象

Notice::findOrNew(100);

 

firstOrNew
这个查不到会通过newModelInstance方法新建一个模型对象,并把参数一(array)values 合为一个数组赋给模型

Notice::firstOrNew(['title' => 14]);
Notice::firstOrNew(['title' => 100], ['content' => 123]);

 

newModelInstance
这个方法在比较后,因为前面有用到,所以先讲下
创建模型,根据传入的数组赋值

Notice::newModelInstance(['title' => 100, 'content' => 123]);

 

firstOrCreate
查询或新建一条记录,第一个参数为查询条件,如果找不到,会把参数一(array)values 合为一个数组赋值,新建一条记录并返回模型

Notice::firstOrCreate(['title' => 14], ['content' => 123]);

 

updateOrCreate
更新或新建一条记录,第一个参数为查询条件,找到则把第二个参数的值赋给查到的model,如果找不到,会先执行firstOrNew(values通过fill($values)赋值再执行save()保存

Notice::UpdateOrCreate(['title' => 14], ['content' => 1234]);

源码:

/**
   * Create or update a record matching the attributes, and fill it with values.
   *
   * @param  array  $attributes
   * @param  array  $values
   * @return \Illuminate\Database\Eloquent\Model
   */
  public function updateOrCreate(array $attributes, array $values = [])
  {
      return tap($this->firstOrNew($attributes), function ($instance) use ($values) {
          $instance->fill($values)->save();
      });
  }

注:tap是laravel内置的一个方法,简单实用 https://segmentfault.com/a/1190000008447747

function tap($value, $callback)
{
   $callback($value);
 
   return $value;
}

 

firstOrFail
查到返回对象,否则抛ModelNotFoundException异常

Notice::firstOrFail();
Notice::where('title', 321)->firstOrFail();

 

firstOr
查询一条,不存在则执行自定义columns = ['*'], Closure callback可以在参数一或参数二传,方法有对第一个参数做实现Closure类的判断

$title = 1;
return Notice::where('title', 100)->firstOr(function() use ($title) {
     return Notice::UpdateOrCreate(['title' => $title], ['content' => 1234]);
});

 

with
表关联查询
model

class Notice{
    public function uploadRelation()
    {
        return $this->hasMany(UploadRelation::class, 'relation_id', 'id')
            ->where('relation_type', '=', UploadRelation::RELATION_TYPE_NOTICE)
            ->select('relation_type','relation_id', 'upload_id');
    }
 
}
 
class UploadRelation{
    public function upload()
    {
        return $this->hasOne(Upload::class, 'id', 'upload_id');
    }   
}

调用关联

Notice::with('uploadRelation')->get();
Notice::with('uploadRelation.upload')->get();       
 
Notice::with([
        'uploadRelation' => function($query){
            $query->select('relation_id', 'upload_id');
        }
    ])->get();
 
Notice::with([
        'uploadRelation' => function($query){
            $query->select('relation_id', 'upload_id')->with([
                'upload' => function($query){
                    $query->select('id', 'path');
                }
            ]);
        }
    ])->get();

 

without
用来注销绑定

Notice::with('uploadRelation')->get();
Notice::with('uploadRelation')->without('uploadRelation')->get();

 

withCount
只获取关联条数

Notice::withCount('uploadRelation')->get();

 

--------------------------------------------分割线----------------------------------------------
 

Illuminate\Database\Query\Builder 加载的代码块

Illuminate\Database\Eloquent\Concerns\QueriesRelationships
 

whereHas
当绑定关系有数据的时候

Notice::whereHas('uploadRelation')->get();

$status = 1;
Notice::whereHas(
    'uploadRelation', function ($query) use ($status) {
    $query->where('status', $status);
})->get();

 


 

你可能感兴趣的:(php)