[CakePHP] CakePHP ORM의 Query식과 Entity, Table 클래스, Resultset


Study/PHP  2019. 10. 9. 09:00

안녕하세요. 명월입니다.


이 글은 CakePHP에서 데이터 베이스 접속시 사용되는 Query식과 Entity, Table 클래스, Resultset에 대한 설명입니다.


이전에 제가 CakePHP에서 데이터 베이스를 접속하는 방법에 대해서 소개했습니다.

링크 - [PHP] CakePHP에서 데이터 베이스(MariaDB(Mysql))를 연결하는 방법


CakePHP를 이용하면 아주 간단하게 데이터 베이스를 접속할 수 있고 쿼리를 구성할 수 있으며 데이터를 가져올 수 있습니다.

Query 식이라는 것은 그 데이터 베이스 접속시에 사용되는 쿼리를 함수적으로 나타내서 사용하는 방법입니다.


// 테이블 레지스트리를 가져온다.
$table = TableRegistry::get('테이블 명');
// 쿼리 식을 만든다.
$query = $table->find();

$query = $query->select(['컬럼'])
			   ->where(['컬럼 >=' => 조건])
			   ->order(['컬럼' => 'DESC']);
// 결과를 뽑는다.
$result = $query->toList();

위 식을 보니 딱 C#의 Linq와 Java의 stream식과 비슷합니다.

<?php
namespace App\Controller;

use Cake\ORM\TableRegistry;

class HomeController extends AppController
{
  public function index()
  {
    $table = TableRegistry::get('testtable');
    $query = $table->find();

    $query = $query->select(['data'])
          ->where(['idx >=' => 60])
          ->order(['idx' => 'DESC']);
    $result = $query->toList();
    foreach($result as $item){
      var_dump($item->data);
    }
  }
}

사실 제가 「[PHP] CakePHP에서 데이터 베이스(MariaDB(Mysql))를 연결하는 방법」에서도 마지막에 약간 설명헀습니다.

다른 점이라고는 TableRegistry::get와 connection->newQuery()를 사용한 것의 차이이지만 거의 비슷합니다.


TableRegistry::get와 connection->newQuery() 차이는 이제부터 Table클래스와 Entity클래스를 사용할 것이냐 아닐 것의 차이가 될 것입니다.

사실 Cake에서 데이터 베이스를 쓴다고 하면 TableRegistry::get를 써야 합니다. 그래야 ORM를 제대로 사용할 수 있기 때문입니다. connection->newQuery()의 경우는 단순히 쿼리를 만들어 주는 역할만 하는 것입니다.


그럼 Table 클래스과 Entity 클래스를 만들어 보겠습니다.

먼저 IDE의 디렉토리 Explorer를 보면 Model이라는 폴더 밑에 Entity와 Table의 디렉토리가 보입니다.

먼저 이 Table의 폴더에 디비 테이블명 + 'Table'로 클래스를 작성합니다. 저의 경우는 디비 테이블명이 TestTable이라 TestTableTable이라고 되어 버렸네요. 클래스 명을 바꾸어도 상관은 없지만 뒤에 반드시 Table은 붙어야 합니다.

그리고 이 Table클래스를 만듭니다.

<?php
namespace App\Model\Table;

use Cake\ORM\Table;

class TestTableTable extends Table
{
  public function initialize(array $config)
  {
    // 데이터 베이스 테이블 명 설정
    $this->table('testtable');
    // 기본 키 설정
    $this->primaryKey('idx');
    // 연결 될 Entity 클래스
    $this->entityClass('App\Model\Entity\TestTable');
  }
}

그리고 이번에는 Entity 클래스를 만들어야 하는데 Entity 폴더 밑에 생성합니다. 이 Entity의 클래스 명의 어미에는 아무것도 붙지 않습니다.

<?php
namespace App\Model\Entity;

use Cake\ORM\Entity;

class TestTable extends Entity
{
  protected function _getFullData()
  {
    return $this->idx . '  ' . $this->data;
  }
}

사실 여기에서는 제가 Entity클래스에 딱히 넣을 것은 없습니다. 원래 Java나 C#에서는 변수를 넣고 get, set를 지정해 주지만 PHP에서는 맴버 변수 선언할 때 따로 자료형이 없기 때문에 get set의 의미가 없습니다.

그래서 선언을 하지 않습니다. 그러나 제가 조금 재미있는 것을 만들었는데 get함수로 full_data를 호출하면 $idx와 $data의 값이 합쳐져서 보이도록 예제를 만들었습니다.

<?php
namespace App\Controller;

use Cake\ORM\TableRegistry;

class HomeController extends AppController
{
  public function index()
  {
    // Table클래스명 여기에는 어미 Table를 뗀다. 즉, TestTableTable인데 Table 어미가 빠진 TestTable이 들어간다.
    $table = TableRegistry::get('TestTable');
    $query = $table->find();

    $query = $query->where(['idx >=' => 60])
                   ->order(['idx' => 'DESC']);
    $result = $query->toList();
    // entity로 잘 받아와 지는지 full_data를 불러 보았다.
    foreach($result as $item){
      echo 'idx:'. $item->idx . ' data:' . $item->data . ' full:'.$item->full_data;
      echo '<br />';
    }
  }
}

결과가 $result의 객체 $item을 보면 full_data의 값이 잘 나오네요. 그 뜻은 Table클래스를 통해서 Entity 클래스가 선언되어 나온 결과입니다.


마지막으로 ResultSet으로는 toList가 있고 first와 count가 있습니다.

ToList는 결과를 리스트로 내보내는 것이고 first는 한개의 첫번째 데이터가 되겠네요. count는 총 컬럼 개수입니다.

<?php
namespace App\Controller;

use Cake\ORM\TableRegistry;

class HomeController extends AppController
{
  public function index()
  {
    $table = TableRegistry::get('TestTable');
    $query = $table->find();

    $query = $query->where(['idx >=' => 60])
          ->order(['idx' => 'DESC']);
    // 데이터의 리스트를 반환한다.
    $result = $query->toList();
    foreach($result as $item){
      echo 'idx:'. $item->idx . ' data:' . $item->data . ' full:'.$item->full_data;
      echo '<br />';
    }
    // 한 개의 데이터를 반환한다.
    $item = $query->first();
    var_dump($item);
    // 데이터의 개수를 반환한다.
    var_dump($query->count());
  }
}

그 밖에 여러 가지가 많기는 하는데 자주 사용하는 것은 저 3타입이지 않을까 싶습니다.


참조 - https://book.cakephp.org/3.0/en/orm/query-builder.html

참조 - https://book.cakephp.org/3.0/en/orm/table-objects.html

참조 - https://book.cakephp.org/3.0/en/orm/entities.html

참조 - https://book.cakephp.org/3.0/en/orm/retrieving-data-and-resultsets.html


여기까지 CCakePHP에서 데이터 베이스 접속시 사용되는 Query식과 Entity, Table 클래스에 대한 글이었습니다.


궁금한 점이나 잘못된 점이 있으면 댓글 부탁드립니다.