Lumenデータベース操作orm

18587 ワード

一般的な方法の比較
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()メソッドには最後に2つのパラメータがあります.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ソート
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はクエリーを分割し、最初のパラメータは1回の検索の数であり、デフォルトではid検索に基づいており、3番目のパラメータパスをカスタマイズする必要がある場合は
$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はフィールドをクエリーし、そのフィールドのみの配列集合を返し、2番目のパラメータはパラメータをキーとして指定し、キー値対集合を返します.
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

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

 
truncateテーブル全体を切断する場合、テーブルはすべてのローを削除し、自動インクリメントIDをゼロにリセットします.切断方法は、次のとおりです.
DB::table('notice')->truncate();

 
新Queryはクエリージェネレータの新しいインスタンスを取得します.
$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}()");
}

 
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
IlluminateDatabaseQueryBuilderロードコードブロック
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();

 
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
次に、IlluminateDatabaseEloquentBuilderクラスのほとんどのメソッドを示します.
 
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異常が直接投げ出され、AppExceptionsHandlerで異常捕捉をカスタマイズできます
Notice::findOrFail(100);

 
findOrNewこれが見つからないとnewModelInstanceメソッドで新しいモデルオブジェクトが作成されます
Notice::findOrNew(100);

 
firstOrNewこれはnewModelInstanceメソッドでモデルオブジェクトを新規作成し、パラメータ1(array)valuesを1つの配列に結合してモデルに割り当てることはできません.
Notice::firstOrNew(['title' => 14]);
Notice::firstOrNew(['title' => 100], ['content' => 123]);

 
NewModelInstanceこの方法は比較後,先に役に立つので,まずモデルを作成し,入力した配列に基づいて値を割り当てる.
Notice::newModelInstance(['title' => 100, 'content' => 123]);

 
firstOrCreateクエリーまたはレコードを新規作成します.最初のパラメータはクエリー条件です.見つからない場合は、パラメータ1(array)valuesを配列に結合し、レコードを新規作成してモデルに戻ります.
Notice::firstOrCreate(['title' => 14], ['content' => 123]);

 
updateOrCreateはレコードを更新または新規作成します.最初のパラメータはクエリー条件で、見つかったら2番目のパラメータの値を検索した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は1つを問合せて、存在しないでカスタムcolumns=['*']を実行して、Closure callbackはパラメータの1あるいはパラメータの2伝で、方法は第1のパラメータに対して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();

 
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
IlluminateDatabaseQueryBuilderロードコードブロック
Illuminate\Database\Eloquent\Concerns\QueriesRelationships  
whereHasバインド関係にデータがある場合
Notice::whereHas('uploadRelation')->get();

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