LoginSignup
4
9

More than 5 years have passed since last update.

Cakephp3 QueryBuilderについて

Last updated at Posted at 2017-08-22

はじめに

QueryBuilderを利用すると、SQLを直接利用することなくデータベースにアクセスを行うことができます。
SQL的な記述を極力なくし、PHPのメソッドのメソッド呼び出しを組み合わせること(メソッドチェーン)で、データベースアクセスを行う仕組みとなっています。

それに対して、ConnectionManagerを使えば、直接SQLを発行することができます。

前提

Boardsテーブルに、name,title,contentのカラムが用意されているとします

QueryBuliderとは?

データベースの利用はいかにして検索を組み立てていくことが重要です。
findメソッドを使用することでさまざまな検索を行うことができるが、findの引数に細かく設定情報していくのは可読性があまり良いとはいえないのかなと思います。

QueryBuilderのメソッドは同じくfindですが、このfindでは【Query】というクラスのインスタンスが返されます。
この【Query】というクラスのインスタンスがQueryBuilderのメインになります。

メソッドを連続して呼び出していく書き方で記述します。
この記述方法を一般に【メソッドチェーン】といいます。

例:

$data = $this->Boards
              ->find()
              ->where(['id <='=>$input])
        ->order(['id'=>'DESC']);
            }

nameが等しいレコードを抽出する

src/Template/Boards/index.ctp
<h1>Database サンプル</h1>
<?=$this->Form->create($entity)?>
<fieldset>
    <?=$this->Form->text("input")?>
</fieldset>
<?=$this->Form->button("送信")?>
<?=$this->Form->end() ?>

<table>
    <?php foreach($data as $obj): ?>
    <tr>
        <td><?=$obj ?></td>
    </tr>
    <?php endforeach; ?>
</table>
/src/Controller/BoardsController.php
<?php 
    namespace App\Controller;
    class BoardsController extends AppController {
        public function index($id = null){
            $data = $this->Boards->find();
            if($this->request->is('post')) {
                $input = $this->request->data['input'];
                $data = $this->Boards->find()->where(['name'=>$input]);
            }
            $this->set('data',$data);
            $this->set('entity',$this->Boards->newEntity());
        }

フォームに入力されたID番号よりも小さいレコードを降順で出力する

(不等号でクエリを投げるパターン)

public function index($id = null){
            $data = $this->Boards->find();
            if($this->request->is('post')) {
                $input = $this->request->data['input'];
                $data = $this->Boards
                    ->find()
                    ->where(['id <='=>$input])
           ->order(['id'=>'DESC']);
            }
            $this->set('data',$data);
            $this->set('entity',$this->Boards->newEntity());
        }

その他のクエリーのパターンとして

->offset //指定の位置から取得する
->limit //指定の数だけ取得する

//例
->find()
->offset(5)
->limit(3);

複数のwhere条件

->andWhere(条件);
->orWhere(条件);

selectによる項目の設定

->select(配列);

あいまい検索でのor条件

/src/Controller/BoardsController.php
<?php 
    namespace App\Controller;
    class BoardsController extends AppController {
        public function index($id = null){
            $data = $this->Boards->find();
            if($this->request->is('post')) {
                $input = $this->request->data['input'];
                $data = $this->Boards
                    ->find()
                    ->where(['name like'=>'%'.$input.'%'])
                    ->orWhere(['title like'=>'%'.$input.'%'])
                    ->orWhere(['content like'=>'%'.$input.'%'])
              ->select(['name','title']);
            }
            $this->set('data',$data);
            $this->set('entity',$this->Boards->newEntity());
        }

whereに関数を渡すパターン

下記のように、不等号の演算記号まで含めた値をキーとして用意することもできるが

->where(['id <='=>$input])

whereの引数に関数を指定し、細かい条件設定をするパターンもあります。

->where(
  function($exp,$q) {
     return(Expression);
  }
)

下記は、nameにinputとなっている値とIDが一致していたら、そのレコードを表示する記述です。

<?php 
    namespace App\Controller;
    class BoardsController extends AppController {
        public function index($id = null){
            $data = $this->Boards->find();
            if($this->request->is('post')) {
                $input = $this->request->data['input'];
                $data = $this->Boards
                    ->find()
                    ->where(function($exp,$q) use($input) {
                        return $exp->eq('id',$input);
                    });
            }
            $this->set('data',$data);
            $this->set('entity',$this->Boards->newEntity());
        }

$exp は Expressionクラスのインスタンスです。このExpressionに用意されている条件式に関するメソッドを使用することで
さまざまな条件を作ることができます

eq(項目名,値);// A = B
notEq(項目名,値);// A != B
lt(項目名,値);// A < B
lte(項目名,値);// A <= B
gt(項目名,値);// A > B
gte(項目名,値);// A >= B

ちなみに
lt → less than
gt → greater than
lte → less than equal
gte → greater than equal  の略

4
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
9