質問編集履歴

1

内容不足の為、ソース情報などを追記しました。

2016/08/02 01:55

投稿

Smar
Smar

スコア40

test CHANGED
@@ -1 +1 @@
1
- PDOでのFETCH_MODEについて
1
+ PDOでのFETCH_CLASSの際のテーブル結合について
test CHANGED
@@ -1,4 +1,6 @@
1
+ DTOとDAOの形からmapperやactiverecordなどの方に移行してみたい…と、
2
+
1
- DTOとDAOの形からmapperやactiverecordなどの方に移行してみたい…と、勉強も兼ねて以下のサイト様を参考にMapper形式でPDO(表現おかしかったすいません…)にて各種SELECT、INSERTなどを試してみました。
3
+ 勉強も兼ねて以下のサイト様を参考にMapper形式でPDO(表現おかしかったすいません…)にて各種SELECT、INSERTなどを試してみました。
2
4
 
3
5
  http://blog.tojiru.net/article/277021312.html
4
6
 
@@ -8,26 +10,192 @@
8
10
 
9
11
  クラスでテーブルのカラムをデータモデルという形で持ち、PDOにてそのクラスをFETCH_CLASSとすることで制作する、というところは理解できたのですが、
10
12
 
11
- テーブルをJOINなどで結合する際はどのような設計になるのが一般的なのでしょうか?
13
+ テーブルを結合する際はどのような設計になるのが一般的なのでしょうか?
12
-
13
-
14
-
14
+
15
+
16
+
15
- 最初は何も考えずテストとして、IDが紐付いているような
17
+ 最初は何も考えずテストとして、IDが紐付いているような簡単なもので試してみました際にエラーとなり、よくわからずだったのですが、
16
-
17
-
18
-
19
- pdo->query('SELECT tbl_a.name as a_name, tbl_b.name as b_name FROM `tbl_a` LEFT JOIN `tbl_b` ON tbl_a.id = tbl_b.tbl_a_id');
18
+
20
-
21
-
22
-
23
- のような簡単なもので試してみました際にエラーとなり、よくわからずだったのですが、純粋に「PDO::FETCH_CLASS」を「FETCH_ASSOC」とすれば良いのだなと思うと同時に通常は全JOINパターン分のクラスを用意するのだろうか…と疑問になりました。
19
+ 「PDO::FETCH_CLASS」を「PDO::FETCH_ASSOC」とすれば良いのだなと解決すると同時に通常は全JOINパターン分のモデルクラスを用意するのだろうか…と疑問になりました。
24
20
 
25
21
 
26
22
 
27
23
  データベースの内容によってはものすごいことになるのでは…と思ったりしたのですが、通常はそれでも準備するものなのでしょうか?
28
24
 
29
- 同じテーブルでもこの場合はこっちとJOIN、この場合は…みたいになったりすると思っています。
25
+ 同じテーブルでも取得したい場合によって、この場合はこっちとJOIN、この場合は…みたいになったりすると思っています。
26
+
27
+
28
+
30
-
29
+ すいません、記述不足でした為簡単にソースを記載させて頂きます。
30
+
31
-
31
+ (ほぼ、上記サイトでのサンプルそのままですが…)
32
+
33
+
34
+
32
-
35
+ ```PHP
36
+
37
+ // mapperのクラス.
38
+
39
+
40
+
41
+ abstract class DataMapper {
42
+
43
+
44
+
45
+ protected $_pdo;
46
+
47
+
48
+
49
+ function __construct( PDO $pdo ) {
50
+
51
+ $this->_pdo = $pdo;
52
+
53
+ }
54
+
55
+
56
+
57
+ protected function _decorate( PDOStatement $stmt ) {
58
+
59
+ $stmt->setFetchMode( PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, static::MODEL_CLASS );
60
+
61
+ return $stmt;
62
+
63
+ }
64
+
65
+
66
+
67
+ }
68
+
69
+
70
+
71
+ class MemberMapper extends DataMapper {
72
+
73
+
74
+
75
+ const MODEL_CLASS = 'Member';
76
+
77
+
78
+
79
+ function findAll() {
80
+
81
+ $stmt = $this->_pdo->query('SELECT * FROM `member`');
82
+
83
+ return $this->_decorate($stmt);
84
+
85
+ }
86
+
87
+
88
+
89
+ function findAllJoin() {
90
+
91
+ $stmt = $this->_pdo->query('SELECT member.name as a, member_2.name as b FROM `member` LEFT JOIN `member_2` ON member.id = member_2.member_id');
92
+
93
+ return $this->_decorate($stmt);
94
+
95
+ }
96
+
97
+
98
+
99
+ }
100
+
101
+
102
+
103
+ // PDO接続用関数.
104
+
105
+ function fncGetPDO( $env = null ) {
106
+
107
+
108
+
109
+ static $pdo = array();
110
+
111
+
112
+
113
+ if( !isset( $pdo[$env] ) ) {
114
+
115
+
116
+
117
+ $conf = array('dsn'=>'mysql:dbname=xxxxx;host=localhost;charset=utf8','user'=>'xxxxx','pass'=>'xxxxx');
118
+
119
+
120
+
121
+ $pdo[$env] = new PDO(
122
+
123
+ $conf['dsn'],
124
+
125
+ $conf['user'],
126
+
127
+ $conf['pass'],
128
+
129
+ array(
130
+
131
+ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
132
+
133
+ PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_CLASS,
134
+
135
+ )
136
+
137
+ );
138
+
139
+
140
+
141
+ }
142
+
143
+
144
+
145
+ return $pdo[$env];
146
+
147
+
148
+
149
+ }
150
+
151
+
152
+
153
+ // …と別途テーブルのカラムに合わせたモデルクラスがあります。
154
+
155
+
156
+
157
+ // 実行時.
158
+
159
+
160
+
161
+ static $pdo;
162
+
163
+ $pdo = fncGetPDO('local');// ここでのlocalは実際は条件分岐していますが、上記関数内に直接記載しました
164
+
165
+
166
+
167
+ // こちらは問題無し.
168
+
169
+ $member_mapper = new MemberMapper($pdo);
170
+
171
+ $entries = $member_mapper->findAll()->fetchAll();
172
+
173
+ var_dump($entries);
174
+
175
+
176
+
177
+ // こちらはエラー.
178
+
179
+ $member_mapper = new MemberMapper($pdo);
180
+
181
+ $entries = $member_mapper->findAllJoin()->fetchAll();
182
+
183
+ var_dump($entries);
184
+
185
+ ```
186
+
187
+
188
+
33
- JOIN無し場合FETCH_CLASSで有りではFETCH_ASSOC、、、というのコネクション用関数が2つ?みたになり何かしっくり来ない…と思ったりしています。
189
+ ここで問題FETCH_CLASSしてることでモデルに含まれないものをJOINで取得しようとしてるからと思った次第です。
190
+
191
+ (FETCH_ASSOCに書き換えることで実際に動作しました)
192
+
193
+
194
+
195
+ そこで、例えば結合するパターンのものを盛り込んでいく場合に一般的にはどのように構築していくものなのでしょうか…?
196
+
197
+ ・PDO接続用関数をFETCH_CLASS用とFETCH_ASSOC用と2つ持つ?
198
+
199
+ ・そもそもFETCH_CLASSを使わない?
200
+
201
+ …と、浅い考えに至ってしまった為、質問させて頂いております。