質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JOIN

これはSQL文のJOINに関するタグです。リレーショナルデータベースシステムの二つ以上のテーブルを結合する際に、この構文が利用されます。

Symfony

Symfony はPHPで記述されたWebアプリケーションフレームワークです。よく利用するコーディングをテンプレーティングするなど、Webアプリケーション開発の効率化を目的として設計されています。

EC-CUBE

EC-CUBEは、主に日本国内で開発されているECコンテンツ管理システムです。ロックオン社のECKitを元にしてオープンソース化され、商品管理・受注管理・顧客管理・売上集計などECに特化した様々な機能を備えています。

Q&A

0回答

2383閲覧

EC-CUBE4/Symfony4:エンティティ間のリレーションの設定法が間違っていないかをチェックしてください(記法の確認のみ)

q_pix

総合スコア3

JOIN

これはSQL文のJOINに関するタグです。リレーショナルデータベースシステムの二つ以上のテーブルを結合する際に、この構文が利用されます。

Symfony

Symfony はPHPで記述されたWebアプリケーションフレームワークです。よく利用するコーディングをテンプレーティングするなど、Webアプリケーション開発の効率化を目的として設計されています。

EC-CUBE

EC-CUBEは、主に日本国内で開発されているECコンテンツ管理システムです。ロックオン社のECKitを元にしてオープンソース化され、商品管理・受注管理・顧客管理・売上集計などECに特化した様々な機能を備えています。

0グッド

0クリップ

投稿2021/10/06 05:28

編集2021/10/06 06:52

EC-CUBE4に新規テーブルを加えて既存テーブルとリレーションさせ、Joinして出力させたいと思っています。開発環境はwindows10、xamppのバージョンは7.4.23、PHPは7です。

しかし、リポジトリからJoin文を発行してもうまく認識してくれません。
連携の手順が間違っているのかと思い、文法や前準備の手順の確認をお願いしようと思います。

連携の手順

CustomerエンティティとCustomerRankエンティティを用意。
CustomerとCustomerRankは1:1関係。CustomerのidとCustomerRankのcustomer_id
両方のentityの中に以下を書き込む

####Customer
エンティティの設定

  • indexesで外部キーを設定。INDEX(name="〇〇"はDBに登録されたキー名。columns={"カラム名"}),

※上の理解は正しいか?

  • @ORM\Entity(repositoryClass="Customerエンティティ用のリポジトリのパス"

※一つだけしか指定できないか?

/** * Customer * * @ORM\Table(name="dtb_customer", uniqueConstraints={@ORM\UniqueConstraint(name="secret_key", columns={"secret_key"})}, indexes={@ORM\Index(name="dtb_customer_buy_times_idx", columns={"buy_times"}),(中略)) * @ORM\InheritanceType("SINGLE_TABLE") * @ORM\DiscriminatorColumn(name="discriminator_type", type="string", length=255) * @ORM\HasLifecycleCallbacks() * @ORM\Entity(repositoryClass="Customize\Repository\CustomerRepository") */

プロパティの設定

  • joinする予定のカラムの真下にリレーションの設定を書く。
  • targetEntityはCustomize\もしくはEccube\から始まる連携先エンティティへのパスを書く、で正しいか。パスを書く際にはUSEで何らかのクラスを呼んでおく必要はあるか。
  • mappedByで指定されている名前(自分を指す)は何か。これは自分の「クラス名」なのか、それとも何らかの変数名やエイリアスなのか(ここが多くの記事やサンプルコードで触れられていない)。
  • 最後の変数はprivate $ProductClasses;のように複数形(クラス名と異なる名前)になっているものもあるが、名前は任意か。
  • ここで宣言された変数にはどこで何を代入するのか。既存のクラスではconstructで$this->ProductClasses = new \Doctrine\Common\Collections\ArrayCollection();のように空のコレクションクラスを代入して、そこにfunction copyで値を入れているようだが…
/** * @var integer * * @ORM\Column(name="id", type="integer", options={"unsigned":true}) * @ORM\Id * @ORM\GeneratedValue(strategy="IDENTITY") */ private $id; /** * @var \Doctrine\Common\Collections\Collection * @ORM\OneToOne(targetEntity="Customize\Entity\CustomerRank", mappedBy="Customer", cascade={"remove"}) */ private $CustomerRank;

コンストラクタの設定

  • ここでArrayCollectionを代入するだけでよいのか。ほかにしておくことはないか。
public function __construct(){ $this->CustomerFavoriteProducts = new \Doctrine\Common\Collections\ArrayCollection(); $this->CustomerAddresses = new \Doctrine\Common\Collections\ArrayCollection(); $this->customerRank = new \Doctrine\Common\Collections\ArrayCollection(); //↑の行追加 $this->setBuyTimes(0); $this->setBuyTotal(0); }

####CustomerRank
Joinのリレーションの設定。

  • InversedByで指定されているのはmappedByと同じようにクラス名か、それとも何らかの変数名やエイリアスか。
  • JoinColumn内のnameは何を指定するのか。下では@ORM\Column(name="customer_id"で指定した名前を書いているが正しいか。
  • 同様に、referencedColumnNameはCusotmerの@ORM\Column(name="id",に合わせてあるがこれでよいか。
/** * @var integer * @ORM\Column(name="customer_id",type="integer",options={"unsigned":true}) * @ORM\Id */ private $customer_id; /** * @ORM\OneToOne(targetEntity="Customize\Entity\Customer",inversedBy="CustomerRank") * @ORM\JoinColumn(name="customer_id",referencedColumnName="id") */ private $customer_rank

CustomerRepository

リポジトリでentityとRepositoryを呼び出す

クラス呼び出し

  • 念のために並べたが不要のものもあるかもしれない。絶対必要なものはどれか。
use Customize\Entity\Customer use Customize\Entity\CustomerRank use Customize\Entity\CustomerRankRepository

コンストラクタ

  • 親クラスのコンストラクタにはクラスは一つしか渡せない、でよいか。
  • ここで渡したクラスが下のSQLでcreateQueryBuilderの対象となる、でよいか。
public function __construct(RegistryInterface $registry){ parent::__construct($registry, Customer::class); }

SQL

  • leftJoin('c.CustomerRank','cr')の、c.CustomerRankはCustomerエンティティのCustomerRankプロパティにエイリアスをつけているのか。
  • このメソッドが正しく動くためには、CustomerRankにはそれまでに何を代入しておく必要があるか。
$qp=$this->createQueryBuilder('c') ->select('c','cr')//取得するデータ ->leftJoin('c.CustomerRank','cr')//ここの指定が正しいか不安 ->where('c.id=:id')->setParameter('id',$id) ->setParameter('id', $id); $result = $qb->getQuery()->getSingleResult(); return $result;

その他

  • Joinを呼び出す前に、どこかにこれらの関係性を認識させるなどの手順は必要か。
  • また、リレーションを利用するために必要な(useすべき)クラスはあるか。

質問ばかり多くて済みませんが、多くの解説も公式ドキュメントすらわりと説明を端折っている部分が多く、わからない部分・不安な部分を書きだしたところこれだけになりました。

お手数ですが、よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問