読者です 読者をやめる 読者になる 読者になる

cakephp1.2 通常のSQLとO/Rマッパーとのselectの結果の違い

cakephp

今更だけどメモ。cakephpでO/Rマッパーというかfindとかした時の結果と、通常のsql(query)を実行した時の結果の違いについて。

通常のsqlを使用した場合
sql

$sql =<<<SQL
select * from users u
inner join posts p on p.user_id = u.id
where u.id=1
SQL;
pr($this->User->query($sql));

結果

Array
(
    [0] => Array
        (
            [u] => Array
                (
                    [id] => 1
                    [user_name] => ユーザー1
                )

            [p] => Array
                (
                    [id] => 1
                    [post_date] => 2016-11-19
                )
        )

    [1] => Array
        (
            [u] => Array
                (
                    [id] => 1
                    [user_name] => ユーザー1
                )

            [p] => Array
                (
                    [id] => 2
                    [post_date] => 2016-11-20
                )
        )
)

O/Rマッパーを使用した場合
sql

$this->User->bindModel(array('hasMany'=>array('Post')));
pr($this->User->findById(1));

結果

Array
(
    [User] => Array
        (
            [id] => 1
            [user_name] => ユーザー1
        )

    [Post] => Array
        (
            [0] => Array
                (
                    [id] => 1
                    [post_date] => 2016-11-19
                )

            [1] => Array
                (
                    [id] => 2
                    [post_date] => 2016-11-20
                )
        )
)

こんな感じでO/Rマッパーを使うと、重複しているUserデータが統合されることで結果がスマートになるという違いがある。

ただ通常のSQLの場合でもGROUP_CONCATとか使えば重複を省くことが可能。

資産形成におすすめのFX口座はこちら。
http://s2fx.com/ranking/856.html

mysql group_concatとfind_in_setのまとめ

mysql

group_concatはgroup byで複数行をまとめた際に、まとめられた列のデータをカンマ区切りで表示する機能。

find_in_setはカンマ区切りのデータを絞り込む機能。

この2つを組み合わせることで、本来なら副問合せ等の複数のSQLに分けないと出来ないようなことが一つのSQLで完結できることが分かった。

ただ速度的なメリットがあるのかどうかは不明。

参考ページの例を使うと以下のようなsqlでmarketとsalesに所属するempを一発で取得できる。

select dept_emp.empid, emp.name, GROUP_CONCAT(dept.name order by dept.id) as dept_n
from dept_emp left join emp on dept_emp.empid=emp.id
left join dept on dept_emp.deptid=dept.id
group by dept_emp.empid
having find_in_set('market', dept_n) and find_in_set('sales', dept_n);

結果

+-------+-------+------------------+
| empid | name  | dept_n           |
+-------+-------+------------------+
|     3 | smith | market,hrm,sales |
+-------+-------+------------------+
1 row in set (0.00 sec)

参考ページ
GROUP_CONCAT関数の便利さは異常 - 開発の風景 〜KKZのSE日記〜
MySQL :: find_in_set() 関数 [Tipsというかメモ]
商品とそれに紐付けされた複数のカテゴリ情報を一つのSQLで取得する - Qiita

bootstrap ハンバーガーメニューを常に表示する方法

bootstrap

bootstrapのハンバーガーメニューをどのサイズでも常に表示させたい場合

Customize and download · Bootstrap
@grid-float-breakpoint
=> 9999pxとか大きい値にする

※9999とか気持ち悪いんだけど他に方法が無さそうだったので仕方なくこうする

widows8.1でIonic1.3のサンプルアプリをブラウザとandroid端末で動作させる手順

ionic

windows8.1環境で確認

Getting Started with Ionic - Ionic Framework
こちらの手順に従う

https://nodejs.org/en/
node.js v6.9.1 インストール

コマンドラインで実行

npm install -g cordova ionic

(終わるのに15分くらいかかる)

ionic start myApp tabs

pcでの動作確認

ionic serve --address localhost

androidでの動作確認

ionic platform add android

エラーが起きたので以下環境変数を設定

ANDROID_HOME
C:\android-sdk

ionic build android

以下エラーが発生したのでJAVA_HOMEの最後のbinを削除
ERROR: JAVA_HOME is set to an invalid directory: C:\Program Files\Java\jdk1.8.0_45\bin

(終わるのに10分くらいかかる)

android端末をpcに繋げる

ionic run android --device

licenses関連でエラーになった。sdkをアップデートしないといけないかも。pcから見れたのでいったん諦める。

CordovaやらIonicやらOnsenUIやらAngularJSやらその辺のまとめ

cordova ionic onsenui angularjs

ここ最近ecサイトをbootstrap&cakephpで作っていて調べものをしている時に表題の技術の事を調べたのでざっくりまとめ。

まずAngularJSって何よ。jQueryでいいじゃん。って昨日までは思っていました。

しかしAngularJSを使うと今までwebサイトの概念として当たり前だったアクセスの度にサーバー側でHTML生成してフルリロード、という概念を変えたSAP(シングルページアプリケーション)という概念のアプリを作ることができるらしい。JSONを使って必要なデータのみをやり取りする、まさにネイティブアプリのような動作にすることができるっぽい。

IonicやOnsenUIはAngularJSと連携していわゆるハイブリッドアプリを作るためのUIフレームワークとなる。HTML5CSSをベースとしたこれまでのWebアプリに近い開発が可能。Cordovaと連携することでワンソースでiosandroid(マテリアルデザイン)用のアプリを生成することが可能。Cordovaはjavscript経由でネイティブに特化したAPIを呼ぶためのプラットフォームのようなもの。

現在bootstrapでモバイルファーストでサイト作成しているとはいえ、いずれアプリ版も出したいし、そうなってくると最初からハイブリッドで作れた方が良いに決まっている。まだ画面設計を始めて1か月足らず。サーバー側の実装もこれからだし、今ならまだ軌道修正ができる。

とはいえ、AngularJSとか今まで触ったことないし、IonicやOnsenUIのお作法も覚える必要があるだろうし、少なく見積もってbootsrapでモバイル用のwebサイトだけ作るのと比較して3か月は余計にかかるんじゃないかと思う。時間に余裕があるのであれば迷うことなくbootstrapを捨てるんだけど、webだけでよいなら今のbootsrapのままで問題無いし、でも後でアプリ出したいってなった時に時間がかかっちゃうよな~。今を優先するかどうするか。

よし、今日だけionic使ってみよう。今日だけ。今日だけ捨てよう。実際に使ってみて時間がかかりそうであれば諦めもつく。今実際に手を動かしてすらいないからメリットが分からないだけで、ecサイトくらいだったらそんなに複雑なことしないし、意外とコピペ中心でガンガン進めることできるかもだし今日残りの時間でionicに移行するか決定しよう。

追記
windowsでionicをひとまず動かしてみた感想。やっぱめんどうくさそうwww。cocos2dxもある程度使えるようになるまで半年くらいかかったけど、似たような空気を感じた。やっぱ素直にbootsrap使ってアプリ対応の余裕ができたらまた考えることにする。

資産形成におすすめのFX口座はこちら。
http://s2fx.com/ranking/856.html

php 例外時のデバッグは__toStringが便利

php

__toString実行しておけばエラーの呼び元とか行数とか出してくれるので便利

サンプル

<?php
try {
  throw new Exception();

} catch (Exception $e) {
  $this->log($e->__toString());
}

sql joinの条件とwhereの条件の違いについて

sql mysql

ケース1

left join t2 on t2.t1_id = t1.id AND t2.status = 'ERROR'

ケース2

left join t2 on t2.t1_id = t1.id
中略
where t2.status = 'ERROR'

ケース1の場合は結合前の条件となるため、ERRORでないt2のデータもNULLとしてデータを取得する。
ケース2の場合は結合後の条件となるため、ERRORでないt2のデータはおろかt1のデータも取得できなくなってしまう。(inner joinならどちらも一緒)

要はleft joinしているテーブルに対する条件はwhereには記述しない方がよいってことか。

俺は何年sqlをやっているんだろう。やっぱり死んだ方がいいな。