21
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

symfony 1.4 メモ(Doctrine)

Last updated at Posted at 2017-03-31
  1. symfony 1.4 メモ(アクション)
  2. symfony 1.4 メモ(context)
  3. symfony 1.4 メモ(モデル)
  4. symfony 1.4 メモ(schemaの書き方)
  5. symfony 1.4 メモ(Doctrine)
  6. symfony 1.4 メモ(フォーム)
  7. symfony 1.4 メモ(コマンド)
  8. symfony 1.4 メモ(ユーティリティ)

WHERE句

WHERE句

where('u.username = ?', 'jwage')

AND WHERE句

whereは前のwhere句をキャンセルしてしまうので、こちらの方がベター

andWhere('u.username = ?', 'jwage')

AND IN

こちらは前の句をキャンセルしない。andWhereInと同じ。

whereIn('u.id', array(1, 2, 3))
andWhereIn('u.id', array(1, 2, 3))

OR IN

orWhereIn('u.id', array(1, 2, 3))

AND NOT IN

whereNotIn('u.id', array(1, 2, 3))
andWhereNotIn('u.id', array(1, 2, 3))

OR NOT IN

orWhereNotIn('u.id', array(1, 2, 3))

OR

orWhere('u.username = ?', 'jwage')

FROM, JOIN

FROM

スペースを空けて別名を指定できる。カンマ区切りで複数指定できる。モデルでリレーションが定義されていれば簡単にJOINできる。

from('User u, u.Phonenumber p')

LEFT JOIN

leftJoin('u.Phonenumber p')

INNER JOIN

innerJoin('u.Profile p')

JOIN

addFrom('u.Phonenumber p')

SELECT

select('u.id, u.username, COUNT(p.id) as num_phonenumbers')

addSelect('u.email_address')

distinct($flag = true)

その他

groupBy('u.id')

addGroupBy('u.username')

having('num_phonenumbers > 0')

addHaving('u.username = ?', 'jwage')

orderBy('u.username')

addOrderBy('u.is_active = ?', 1)

limit(20)

offset(5)

単一オブジェクトの取得

プライマリーキーでの取得

$account = AccountTable::getInstance()->find( $id );
$account = Doctrine::getTable('Account')->find( $id );

プライマリーキー以外での取得

$account = AccountTable::getInstance()->findOneBy( 'login_id', $login_id );
$account = Doctrine::getTable('Account')->findOneBy( 'login_id', $login_id );

複数条件での取得

$account = AccountTable::getInstance()->findOneByLoginIdAndStatus($login_id, "on");
$account = Doctrine::getTable("Account")->findOneByLoginIdAndStatus($login_id, "on");

$account = AccountTable::getInstance()->findOneBy(array('login_id' => $login_id, 'status' => "on")); 
$account = Doctrine::getTable("Account")->findOneBy(array('login_id' => $login_id, 'status' => "on")); 

$q = AccountTable::getInstance()->createQuery("a")
	->where('a.login_id = ?', $login_id)
	->andWhere('a.status = ?', "on");
$account = $q->fetchOne();

$q = Doctrine_Query::create()
	->from('Account a')
	->where('a.created_at > ?', date('Y-m-d H:i:s', time() - 86400 * 30));
$account = $q->fetchOne();

連想配列での取得

$account = $q->fetchOne()->toArray();

Tableクラス内での取得

class AccountTable extends Doctrine_Table
{
	public static function getObjectById( $id )
	{
		return self::getInstance()->find( $id );
	}
}

複数オブジェクトの取得

プライマリーキーでの取得

$accounts = AccountTable::getInstance()->find( array(1, 2) );
$accounts = Doctrine::getTable('Account')->find( array(1, 2) );

プライマリーキー以外での取得

$accounts = AccountTable::getInstance()->findBy( 'status', "on" );
$accounts = Doctrine::getTable('Account')->findBy( 'status', "on" );

並び順の指定

$accounts = AccountTable::getInstance()->findBy( array( 'status' => "on" ), array('label' => 'ASC') );
$accounts = Doctrine::getTable('Account')->findBy( array( 'status' => "on" ), array('label' => 'ASC') );

$q = AccountTable::getInstance()->createQuery("a")
	->where('a.status = ?', "on")
	->orderBy('a.label', 'ASC');
$accounts = $q->execute();

$q = Doctrine_Query::create()
	->from('Account a')
	->where('a.status = ?', "on")
	->orderBy('a.label', 'ASC');
$accounts = $q->execute();

連想配列で取得したい場合

$accounts = $q->fetchArray();

全て取得

$accounts = $q->fetchAll();

プライマリーキーが配列のキーとなる連想配列を取得したい場合

// 戻り値はキーがid、値がラベルの連想配列となる。
$accounts = $q->select("a.id id, a.label label")->execute()->toKeyValueArray('id', 'label');

// こちらはオブジェクト
$user_list = Doctrine_Query::create()->from('User u INDEXBY u.id')->execute();

オブジェクトの更新

// プロパティを変更
$user->username = 'jwage';

//リレーション(hasOne)の値も変更可能
$user->Profile->name = 'Jonathan H. Wage';

//リレーション(hasMany)も
$user->Phonenumbers[]->phonenumber = '6155139185';

//多対多のリレーションも可能
$tag = new Tag;
$tag->name = 'doctrine';
$user->Tags[] = $tag;

// saveで更新
$user->save();

多対多の追加処理をモデルクラスのメソッドに入れておけば、もっとシンプルに書ける

Tag.class.php
class Tag extends BaseTag
{
	public function setName($name)
	{
		$tag = Doctrine::getTable('Tag')->findOneByName($name);
		if ($tag)
		{
			$this->assignIdentifier($tag->identifier());
		}
		else
		{
			$this->_set('name', $name);
		}
	}
}
$blogPost->Tags[]->name = 'doctrine';
$blogPost->save();

オブジェクトの削除

オブジェクトを取得してから削除する場合

オブジェクトが既に生成されている場合はこちらが有効。

$user = Doctrine::getTable('User')->find(1);
$user->delete();

deleteクエリで実行する方法

オブジェクトが生成されていない場合は、オブジェクトを取得するクエリを生成する上記方法よりこちらの方がクエリが1回で済むため効率的。

$deleted = Doctrine_Query::create()
	->delete()
	->from('User u')
	->where('u.id = ?', 1)
	->execute();

生SQLの実行

$query = "SELECT * from something";
$rs = Doctrine_Manager::getInstance()->getCurrentConnection()->fetchAssoc($query);

適当なテーブルからコネクタを取得することも可能

$table_user = Doctrine::getTable('User');
$con = $table_user->getConnection();

$sql = 'UPDATE aaaaa SET status = ?, updated_at = ? WHERE id = ? ';
foreach( $ids as $id )
{
	try
	{
		// prepare メソッドで SQL エスケープすることも可能です
		$stmt = $con->prepare($sql);
		$flag = $stmt->execute( array( 2, $date, $id ) );
		// 開放しないと次の処理でエラーが発生することがある。
		$stmt->closeCursor();
		$stmt = NULL;
	}
	catch (Exception $e)
	{
		// 例外処理
	}
}
// 基本
$statement = $conn->executeQuery('SELECT * FROM users WHERE id = ?', array(1));
$user = $statement->fetch(); // array( "id" => "1", "name" => "bob" )

// update
$count = $conn->executeUpdate('UPDATE users SET name = ? WHERE id = ?', array('smith', 1));
echo $count; // 1

// update 2
$conn->update('users', array('name' => 'smith'), array('id' => 1));

// insert
$conn->insert('users', array('id' => 2, 'name' => 'mike'));

// delete
$conn->delete('users', array('id' => 1));

// select 複数
$results = $conn->fetchAll('SELECT * FROM users');
/*
array
(
	array( "id" => "1", "name" => "bob" ),
	array( "id" => "2", "name" => "mike" )
);

// select 一件
$user = $conn->fetchAssoc('SELECT * FROM users WHERE id = ?', array(1));
// array( "id" => "1", "name" => "bob" )

// select カラム指定
$name = $conn->fetchColumn('SELECT name FROM users WHERE id = ?', array(1));
echo $name; // "bob"

:xx という形式のキーを使って連想配列で指定することも可能。複数に同じ指定をしたい場合はこっちがいいかも。

$sql = 'UPDATE aaaaa SET status = :status, updated_at = :date WHERE id = :id ';
$con->execute( $sql, array( ':status' => 'on', ':date' => $date, ':id' => $id ) );

第三引数でパラメータの型を「配列」と指定してあげれば、IN句に配列を渡すことが出来る。
(他のメソッドでもだいたい最後の引数で指定できるみたい)

$conn->fetchAll(
    'select * from users WHERE id IN (?)',
    array( array(1, 2) ),
    array( \Doctrine\DBAL\Connection::PARAM_INT_ARRAY )
);

サブクエリー

$params = $query->getParams();
$q2 = $query->createSubquery()->select('CONCAT(\',\', GROUP_CONCAT( IF(( rt.event_inside_id = r.id  ),1,0)), \',\') as subj')
			->from('LabelsEventInsideType lt')->leftJoin('lt.RelationEventInsideType rt');
$query->select('r.id, (' . $q2->getDql() . ") scnt")->addOrderBy('scnt ' . $sort[1]);
$query->setParams( $params );
$params = $query->getParams();
$q2 = $query->createSubquery()->select('CONCAT(\',\', GROUP_CONCAT(DISTINCT (CASE WHEN ae.contract_status = "contract" then 3 WHEN ae.contract_status = "temporary" then 2 WHEN ae.contract_status = "my" then 1 END)), \',\') as subj')->from('AssignEvent ae')->where('ae.supply_id = r.supply_id');
$query->select('r.id, (' . $q2->getDql().") scnt")->addOrderBy('scnt ' . $sort[1]);
$query->setParams( $params );

特殊なOrderBy

// 値が NULL のものは後ろになるように
$query->addOrderBy("COALESCE( t.".$sort[0] . ',99999999) ' . $sort[1]);

// concat で文字連結してソート
$query->select('r.id, concat(' . implode(", ",$column ) .") cnt")->addOrderBy('cnt ' . $sort[1]);

// 複数条件を数値化して連結し、ソート
$query->select('r.id, concat(IF(( t.info_public_status = 1 ),1,0), IF(( t.signage_public_status = 1 ),1,0)) pstatus')->addOrderBy('pstatus ' . $sort[1]);
21
18
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
21
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?