まず、この質問が長くなってしまったことをお詫びしたいと思います。多くの背景情報がないと、質問を適切に行う方法がわかりませんでした。我慢してください。
スキルを磨くために使用する単純なアプリケーションを、独自のカスタム データベース アクセス スキーマから Doctrine に変換しています。私が Doctrine を選んだ理由はいくつかありますが、そのうちの 1 つとして、日常の仕事で定期的に使用していることが挙げられます。また、Doctrine が一般的に非常に薄い (見た目の) レイヤーであり、多くの機能を追加しながら邪魔にならないことも気に入っています。
users
データベース内のテーブルのデータ アクセス レイヤーを Doctrine に変換しました。いくつかの細かい点を除いて、非常に目立たない (単にゲッターとセッター)。
- 特定のクエリ用のカスタム リポジトリが必要で、
User
オブジェクトにはArrayCollection
、コンストラクターでインスタンス化され たデフォルトがあります
namespace model\entities;
/**
* @Entity(repositoryClass="model\repositories\UserRepository")
* @Table(name="users")
*/
class User{
/* snip variables */
/**
* @OneToOne(targetEntity="Authentication", mappedBy="user", cascade="persist")
*/
private $authentication;
/**
* @OneToMany(targetEntity="Contact", mappedBy="user", cascade="persist")
*/
private $contacts;
public function __construct() {
$this->contacts = new \Doctrine\Common\Collections\ArrayCollection();
}
/* snip getters and setters */
}
私の古いスキーマには、users
テーブルのサブセットを選択する 2 つのカスタム クエリがありました。
彼らです:
public function search( $term = null ){
if( !$term ){
$sql = "SELECT *
FROM
" . $this->tableName . "
ORDER BY
lname ASC,
fname ASC";
$res = $this->db->q($sql);
}
else{
$sql = "SELECT *
FROM
" . $this->tableName . "
WHERE
lname LIKE ?
OR fname LIKE ?
OR CONCAT(fname, ' ', lname) LIKE ?
ORDER BY
lname ASC,
fname ASC";
$values = array( '%' . $term . '%', '%' . $term . '%', '%' . $term . '%' );
$res = $this->db->qwv( $sql, $values );
}
return $this->wrap( $res );
}
と:
public function getAllWithRestrictions(){
$sql = "SELECT *
FROM
" . $this->tableName . "
WHERE
userid IN
(
SELECT
userid
FROM
" . $this->uiPre . "authentications
WHERE
resetPassword = 1
OR disabled = 1
)";
$res = $this->db->q( $sql );
return $this->wrap($res);
}
where$this->db
は薄いPHP PDO ラッパーであり、ゼロ/単一/複数の行が返され、それらをデータ オブジェクトに変換する$this->wrap
魔法を行います。
さて、これを Doctrine に変換するのはとても簡単だと思いました。の場合は、getAllWithRestrictions
単に->where
、->orWhere
セットですよね?もうわからない。
クエリを作成するために使用したこれらの Stackoverflow の質問を見つけましたが、エラーが次々と発生しており、うさぎの穴のどこまで行く必要があるのか わかりません。
SQL 複数の並べ替えとグループ化
Doctrine を使用した複数の列による並べ替え
Doctrine: 複数 (whereIn OR whereIn) クエリ?
教義 - またはどこで?
現在、私のカスタム リポジトリは次のようになっていますが、長い間いじっていたため、正確に近いとは言えません。これは、機能すると思われるものの寄せ集めにすぎません。
<?php
namespace model\repositories;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query\Expr;
class UserRepository extends EntityRepository{
public function search( $term ){
if( !$term ){
return $this
->_em
->createQuery('SELECT u FROM model\entities\User u')
->addOrderBy( 'u.lname' )
->addOrderBy( 'u.fname' )
->getResult();
}
else{
$qb = $this->_em->createQueryBuilder();
$qb ->select(array('u'))
->from('model\entities\User', 'u')
->where( $qb->expr()->like( 'u.lname', '?1' ) )
->orWhere( $qb->expr()->like( 'u.fname', '?2' ) )
->orWhere( $qb->expr()->like( 'CONCAT(u.fname, \' \', u.lname)', '?3' ) )
->addOrderBy( 'u.lname' )
->addOrderBy( 'u.fname' )
->setParameters(
array(
1 => $term,
2 => $term,
3 => $term
)
);
$query = $qb->getQuery();
return $query->getResult();
}
}
public function getAllWithRestrictions(){
$qb = $this->_em->createQueryBuilder();
$qb ->select(array('u'))
->from('model\entities\User', 'u')
->add('where', $qb->expr()->orx(
$qb->expr()->eq('u.disabled', '1'),
$qb->expr()->eq('u.resetPassword', '1')
));
$query = $qb->getQuery();
return $query->getResult();
}
}
getAllWithRestrictions
編集:間違ったテーブルでクエリを実行していることに気付きました (そうである必要がありauthentications
ます)。ただし、次のようなことを行う方法も知る必要があり、$qb->expr()->eq('u.Authentication.disabled = '1')
DQL が実際にどのように機能するかはわかりません。
私が今得ている特定のエラーは
Fatal error: Uncaught exception 'Doctrine\ORM\Query\QueryException' with message 'SELECT u FROM model\entities\User u WHERE u.lname LIKE ?1 OR u.fname LIKE ?2 OR CONCAT(u.fname, ' ', u.lname) LIKE ?3 ORDER BY u.lname ASC, u.fname ASC'
に続く
Doctrine\ORM\Query\QueryException: [Syntax Error] line 0, col 99: Error: Expected Doctrine\ORM\Query\Lexer::T_CLOSE_PARENTHESIS, got ','
しかし、DQL/Query Builder をどのように構築するかによって、さまざまな問題が発生しました。
繰り返しますが、これら 2 つの SQL クエリは簡単に Doctrine / DQL に変換できると思っていました。Doctrineを介して生のSQLに頼らずにこれを行いたいと思います(私がリンクした受け入れられた回答の多くが示唆しているように)。これは簡単でなければなりません。 エレガントな Doctrine クエリを作成する方法を知っている人はいますか?