Table: exams テーブル
id | user_id | math | english | physics |
1 | 1 | 49 | 36 | 56 |
2 | 2 | 45 | 48 | 42 |
3 | 3 | 72 | 80 | 91 |
function exam_total() { $users = $this->User->find('all'); foreach ($users as $user) { $total[$user['User']['id']] = 0; $total[$user['User']['id']] = $user['Exam']['math'] + $user['Exam']['english'] + $user['Exam']['physics']; } $this->set('users', $users); $this->set('total', $total); $this->set('graph_path', './exam_total_graph'); } function exam_total_graph() { /* JpGraph を使用する */ App::import('Vendor', 'jpgraph/jpgraph'); App::import('Vendor', 'jpgraph/jpgraph_bar'); /* DB から値を取得 */ $users = $this->User->find('all'); $y1data = array(); $y2data = array(); $zerodata = array(); $a = array(); /* 合計計算 */ foreach ($users as $user) { $total = 0; $total = $user['Exam']['math'] + $user['Exam']['english'] + $user['Exam']['physics']; array_push($y1data, $user['Exam']['math']); array_push($y2data, $total); array_push($zerodata, 0); array_push($a, $user['User']['username']); } /* グラフ作成 */ $graph = new Graph(350, 250, "auto"); $graph->SetScale("textlin", 0, 100); $graph->SetY2Scale("lin", 0, 300); /* 右側の Y 軸で値が全部表示できないのでグラフを表示する場所の * margin を指定する */ $graph->img->SetMargin(30, 30, 30, 30); /* X軸項目追加 */ $graph->xaxis->SetTickLabels($a); /* plot作成 */ $bplot1 = new BarPlot($y1data); $bplot1->value->Show(); $bplot1->value->SetFormat('%d'); $bplot2 = new BarPlot($y2data); $bplot2->value->Show(); $bplot2->value->SetFormat('%d'); /* 単純に bplot1, bplot2 を表示するとグラフが重なってしまうので * $zerodata のダミーを間に挟んでグループ化して * bplot1, bplot2 が並んでいるように表示する */ $bplotzero = new BarPlot($zerodata); $bgplot1 = new GroupBarPlot(array($bplot1, $bplotzero)); $bgplot2 = new GroupBarPlot(array($bplotzero, $bplot2)); /* グラフ上に描画 */ $graph->Add($bgplot1); $graph->AddY2($bgplot2); /* グラフ表示 */ $graph->Stroke(); }この中で DB にアクセスして値を格納し、各人の合計得点を計算する箇所が重複している
$users = $this->User->find('all'); foreach ($users as $user) { $total[$user['User']['id']] = 0; $total[$user['User']['id']] = $user['Exam']['math'] + $user['Exam']['english'] + $user['Exam']['physics']; }Cache 機能を使うことで DB へのアクセスを減らすことが可能となる。
Cache::read($key, $config = null); Cache::write($key, $value, $config = null); Cache::delete($key, $config = null);
- write() で $key に入力した文字列に $value の値を関連付けて保存する。
- read() で $key に関連付けられた値を読み込む。
- delete() で $key の値を cache から削除する。
function exam_total() { $users = $this->User->find('all'); foreach ($users as $user) { $total[$user['User']['id']] = 0; $total[$user['User']['id']] = $user['Exam']['math'] + $user['Exam']['english'] + $user['Exam']['physics']; } $this->set('users', $users); $this->set('total', $total); Cache::write('users', $users); Cache::write('total', $total); } function exam_total_graph() { /* JpGraph を使用する */ App::import('Vendor', 'jpgraph/jpgraph'); App::import('Vendor', 'jpgraph/jpgraph_bar'); /* Cache に保存された値を読み込む */ $users = Cache::read('users'); $total = Cache::read('total'); Cache::delete('users'); Cache::delete('total'); $y1data = array(); $y2data = array(); $zerodata = array(); $a = array(); foreach ($users as $user) { array_push($y1data, $user['Exam']['math']); array_push($y2data, $total[$user['User']['id']]); array_push($zerodata, 0); array_push($a, $user['User']['username']); } (以下略)
- exam_total() の最後で $users, $total を Cache に保存しておき、exam_total() の後に呼び出される exam_total_graph() では cache のデータを利用するように変更して DB へのアクセス回数を減らすことができる。
- Cache::write() により app/tmp/cache 以下に cake_total, cake_users というファイルが生成される。これを exam_total_graph() 関数で Cache::read() により読み出し、読み出し後は Cache::delete() で削除する。
0 件のコメント:
コメントを投稿