大量のデータを扱えますか?

前回のまとめ等

  • 関数
    • 関数を定義するときの書式と意味をきちんと理解する
    • 戻り値(返り値)の型、関数名、引数(仮引数の型と引数名)、関数の本体(処理内容)
  • 前回、説明を省略したもの(そのうち説明する)
    • プロトタイプ宣言
    • 値渡しと参照渡し
    • 再帰呼び出し
    • etc…
  • 課題の解答例

配列を使おう

実行例と同じになるようにプログラムを修正(関数を追加するだけで、元のコードは変更しない)して実行しよう。

BMI算出

元のプログラム: bmi.c

BMIの計算は用意されている関数(calc_bmi)を使う。

三目並べ

三目並べを作ろう。石を同じところに置いた場合のチェックや入力間違いのチェックはしなくてよい。

元のプログラム: tictactoe.c

物足りない人へ

ライフゲームを作ろう。

さらに物足りない人はLangton’s loopsを作ろう。さらに物足りない人はEvoloopを作ろう。

Spring BootでJDBCを使う(アプリ開発例)

データベースのCRUD

前回は、掲示板のデータをデータベースに格納するように(永続化するように)改良した。そこでのポイントは以下の通り。

  • Javaでデータベースを扱う(接続する)方法の1つにJDBCがあり、Spring BootにおいてはSpring JDBCという仕組みが使える(他にも色々あるがまずはこれ)。
  • H2は組み込みで使えるデータベースで、Spring Bootから簡単に使える。ウェブインターフェースも使える。
  • データベースを操作するSQL
    • CREATE TABLE: テーブルを作成する
    • SELECT: テーブルからデータを取得する
    • INSERT: テーブルにデータを投入する。
  • 具体的には、JdbcTemplateのメソッドを使って、SQLを実行する。

データベースを使った永続化の扱いの基本はCRUDと言われている。
今回はオンラインメモ帳の開発を通してCRUDを一通り実装してみよう。また、Spring Bootにおけるウェブアプリ開発で使われる基本を紹介する。

ソースコード

ポイント

テーブルの作成

前回、テーブルの作成はH2のウェブインターフェースから行ったが、これもプログラムから実行できる。下記はテーブルを作成するプログラムであるが、「IF NOT EXISTS」をつけることによって、テーブルが存在している場合は実行されない(テーブルがない時だけ実行される)。これをコントローラのコンストラクタで実行している。(Lect11Controller.javaの34〜41行目)

レコードの編集(更新)

レコードを更新するにはUPDATEを使う。更新するカラムを「カラム名 = 値」で指定する。WHEREで更新するレコードを限定する。(Lect11Controller.javaの103行目)

フォームのデフォルト値

フォームのデフォルト値はほとんどの場合、value属性で設定することができる。これをTymeleafで設定するには「th:value=”${変数}”』をタグにつければ良い。ただし、textareaタグはタグによって挟まれたところ(textareaの子となるテキストノード)がデフォルト値となるので「th:text」を使う。

非表示でもフォームで送信

画面上に表示させないが、フォームで値を送信したい場合、type属性の値として「hidden」を指定する。(edit.htmlの14行目)

レコードの削除

レコードを削除するにはDELETEを使う。WHEREで更新するレコードを限定する。(Lect11Controller.javaの112行目)

レコードの並び順

SELECTでレコードを取得するときには並び順を指定することができる。「ORDER BY カラム名 順番」を付加する。順番はASC(昇順)かDESC(降順)を指定する。(Lect11Controller.javaの50行目)

改行を含む文字列の表示

HTMLにおいて改行はスペースと同様の扱いになる(基本的には。例外はpreタグ等)。このため改行がある場合は、brタグを挿入する等の処理が必要である。色々な方法が考えられるが、今回のコードでは下記のような処理を行なっている。

  • Note.javaにフィールドbodyを改行区切りのListで返すメソッドを追加(Note.javaの20〜30行目)
  • テンプレートでは1行づつ取得し、行末にbrタグを付加して表示(view.htmlの19〜22行目)

リンクの動的な生成

index.htmlでは操作に関するリンクを動的に生成している。

URLの一部を変数として扱う

マッピングの指定(@GetMapping、@PostMapping、@RequestMapping)で「{}」を使うと、その部分を変数として利用することができる。

Lect11Controller.javaの119行目を見てみよう。ここでは「/view/{id}」となっている。これは、/view/1や/view/2といったURLに対応する。
「{id}」の部分を取得するには、メソッドの引数に、カッコ内と同じ文字列(ここではid)を指定して@PathVariableアノテーションを付加する(Lect11Controller.javaの120行目)。

Javaで永続化

Javaで永続化

本日の内容: https://docs.spring.io/spring-boot/docs/2.0.3.RELEASE/reference/html/boot-features-sql.html

永続化とは

これまで作ったウェブアプリは、起動し直すとそれまでに入力したデータ(例えば掲示板のコメント等)は消えてしまっていた。今回は、入力されたデータを保存することを考えよう。このように、プログラムの実行を終了してもデータが存続する特性を永続性(Persistence)といい、永続性を持たせることを永続化という。

Javaプログラムにおける永続化の方法

色々な方法がある。

  • テキストファイルとして保存
    • 独自の書式(フォーマット)を開発・利用
    • 既存のフォーマットを利用
      • CSV
      • HTML、XML(をベースとしたマークアップ言語)
      • JSON(JavaScript Object Notation)
      • YAML
      • OpenDocument
      • etc…
  • バイナリファイルとして保存
    • 独自の形式を開発・利用
    • 既存のフォーマットを利用
      • Rich Text Format
      • PNG、JPEG、TIFF、MPEG
      • PDF
      • etc…
  • データベースシステムを利用
    • 独自のシステムを開発・利用
    • リレーショナルデータベースベース管理システム(relational database management system, RDBMS)を利用
    • RDBMS以外のデータベース(NoSQL、オブジェクトデータベース等)を利用
  • etc…

掲示板のデータをRDBMSを使って永続化する

本講義はJavaに関する講義であるが、RDBMSは知っておいた方がいい。実際、ウェブアプリ開発ではRDBMSがめちゃくちゃ使われている。

RDBMSはSQLという言語を使う。様々なRDBMSが存在するが、どれもSQLを使うので、これを知っておけばどのRDBMSでも基本的な操作はできるようになる。

Spring Bootでデータベースを使う準備

まずはRDBMSを選定しよう。今回は、組み込みで使える(アプリケーションの中に入れてしまうことができる)H2を使う。

次にJavaのプログラムからどのような方法を使ってデータベースにアクセスするかを決めよう。その方法は主に次の2つがある。

JDBCは、SQLをJavaプログラムの中で使ってデータベースを操作する方法で、JPAはO/Rマッパーというもので、Javaのインスタンスをデータベースに格納できる形に変換してデータベースにアクセスする方法(データベースにアクセスするSQLを自動生成する方法)である。

こう説明すると「JPAを使えばJavaだけでOK」と思えるかもしれないが、現状、JPAはSQLをよく知らないと使いこなすことはできない。

というわけで、本講義では、JDBCを使っていく。

build.gradleのdependenciesに下記の2行を追記して「Reload Project」を実行する。

これで、必要なファイル等が追加される。

ウェブインターフェースでデータベースに接続する

H2には、ブラウザからデータベースを操作できるインターフェースが内蔵されている。これはSpring Bootアプリケーションに組み込んだ状態でも利用することができる。

ウェブインターフェースを利用可能にするため、下記の1行をapplication.propertiesに加えよう。

bootRunで実行し、http://localhost:18080/h2-consoleにアクセスする。

h2-console

次に各設定項目を入力しよう。

  • JDBC URL: データベースの接続を表すURL。これにはどのディレクトリにデータを置くか、という情報が含まれる。今回は、ホームディレクトリに「webappdb」というディレクトリを作り、その中に「database」というファイル名で作るということを指定する。この場合、JDBC URLは「jdbc:h2:~/webappdb/database」となる(実際には「database.mv.db」等のファイルが作られる)。
  • User Name: データベースに接続する時のユーザ名を表す。今回はデフォルトのまま「sa」とする。
  • Password: データベースに接続する時のパスワードを表す。今回は「sa」とする。

入力して、Connectボタンをクリックすると、SQLの入力画面となる。

テーブルを作成する

掲示板のコメントを格納するためのテーブルを作成しよう。

次のSQL文を入力して、Runボタンをクリックするとテーブルが作成される。

「bbs_comment」はテーブル名。Javaのクラスに例えるとクラス名に相当する。

id、comment、name、dateはカラム名。Javaのクラスに例えるとフィールド名に相当する。

INT、TEXT、TIMESTAMPは型で、それぞれJavaのint、String、Dateに対応している(参考: Data Types)。

AUTO_INCREMENTは、自動的に番号をつけることを意味している。だから、保存するときにidには値を入れないで良い。保存されたときに自動的に番号がつく。PRIMARY KEYは、そのレコード(Javaでいうところのインスタンス)における「テーブルの中に保存されているデータのある1行を識別するために必要な情報」を表し、主キーという。Javaにはそういうものはないが(無理やりこじつけるとすればhashCodeかな?)、データベースではレコードを区別するためにあったほうが良い(ほとんどの場合設定するが、なくても大丈夫)。

左側に表のアイコンがついた「BBS_COMMENT」というのができれば作成成功。

テーブルにレコードを登録する

登録するには、INSERT命令を使う。

うまくいったら、「Update count: 1」と表示される。適当に値を変えて、さらにデータを入力してみよう。

テーブルからレコードを検索・取得して表示する

データの検索・取得には、SELECTを使う。先ずは全件取得してみよう。

「*」は全てのカラムの情報(ここでは、id、name、comment、date)を取得することを示す。

一部のデータを表示(検索)するには、WHERE節を追加する。

これは、nameカラムの値が「たろう」であるレコードだけが表示される。

プログラムから扱う

プログラムから扱うために、接続についての情報をapplication.propertiesに加えよう。ウェブインターフェースでデータベースに接続する時の情報と同じにする。

コントローラは次のようになる: Lect10Controller.java)。
ベースとなっているLect05Controllerと比較しながらみていこう。

18〜26行目

プログラムからJDBCを使いデータベースにアクセスするには、JdbcTemplateクラスを用いる。このクラスのインスタンスを用意し、データベースにアクセスするための各種メソッドを利用すれば良い。

この「JdbcTemplateクラスのインスタンス」をどのようにして用意すればいいだろうか?これまでと同様にnew演算子を使えばいいのだろうか?

Spring Bootの環境においては、一部のクラスは、自分でnew演算子を使ってインスタンス化するのではなくシステムにインスタンス化してもらって埋め込むという「依存性注入(dependency injection、DI)」によって行う。

JdbcTemplateクラスのインスタンスはDIで用意する。これを行なっているのが、コンストラクタである。コンストラクタに@Autowiredをつけると、引数はDIコンテナによってインスタンス化されたものが渡される。それをフィールドとして保持する。

49〜54行目

postされたデータをデータベースに登録する。

データを登録するINSERT文を実行するには、updateメソッドを利用する。

第1引数にSQL文を指定する。SQL文の中に「?」をかくと、そこには変数を埋め込むことができる。この「?」をプレースホルダ(placeholder)という。

第2引数以降はプレースホルダに対応した変数を指定する。

最後に、同一サーバの「/lect10/bbs」にリダイレクトする。

31〜44行目

データベースからデータを全件取り出して表示する。

データを取り出すSELECT文を実行するには、queryForListメソッドを利用する。このメソッドの戻り値は、レコードのListである。レコードは、カラム名がキーでデータが値となるMapの形となっている。よって、queryForListの戻り値の型は「List<Map<String, Object>>」となる。

取り出したデータからBbsCommentのインスタンスを生成し、表示用のリストに入れていく。

C言語の関数を定義できますか?

前回のまとめ等

  • if
  • for
  • ソースコードの整形(主にインデント)について
    • まともなエディタを使おう。
    • indent、astyle等の整形ツール
  • 課題の解答例

関数を定義しよう

実行例と同じになるようにプログラムを修正(関数を追加するだけで、元のコードは変更しない)して実行しよう。

BMI算出

元のプログラム: bmi.c

身長[cm]は?: 170
体重[kg]は?: 60
BMIは20.761246です。

「170」と「60」はキーボードからの入力。BMIの計算方法はBMIと適正体重(keisanサービス)が参考になる。

任意の範囲の数値の合計を求める

元のプログラム: sum.c

10から40までの数の合計は775です。

パラメータが指定できるFizzBuzz

元のプログラム: fizzbuzz.c

5の倍数のときFizz、9の倍数のときBuzzを表示するFizzBuzzを400以上500未満で実行する
Fizz 401 402 403 404 FizzBuzz 406 407 408 409 Fizz 411 412 413 Buzz Fizz 416 417 418 419 Fizz 421 422 Buzz 424 Fizz 426 427 428 429 Fizz 431 Buzz 433 434 Fizz 436 437 438 439 Fizz Buzz 442 443 444 Fizz 446 447 448 449 FizzBuzz 451 452 453 454 Fizz 456 457 458 Buzz Fizz 461 462 463 464 Fizz 466 467 Buzz 469 Fizz 471 472 473 474 Fizz 476 Buzz 478 479 Fizz 481 482 483 484 Fizz Buzz 487 488 489 Fizz 491 492 493 494 FizzBuzz 496 497 498 499

C言語でプログラムを作成、実行できますか?

プログラミングが身についているか確認しよう

実行例と同じになるようにプログラムを作成、実行しよう。

[課題1] BMI算出

身長[cm]は?: 170
体重[kg]は?: 60
BMIは20.761246です。

「170」と「60」はキーボードからの入力。BMIの計算方法はBMIと適正体重(keisanサービス)が参考になる。

[課題2] 100以上200未満の数のうち、3の倍数でないものを空白区切で表示せよ

100 101 103 104 106 107 109 110 112 113 115 116 118 119 121 122 124 125 127 128 130 131 133 134 136 137 139 140 142 143 145 146 148 149 151 152 154 155 157 158 160 161 163 164 166 167 169 170 172 173 175 176 178 179 181 182 184 185 187 188 190 191 193 194 196 197 199

[課題3] 200以上300未満でFizzBuzz、空白区切

3の倍数の時に「Fizz」、5の倍数の時に「Buzz」と表示する。ただし、3と5の両方の倍数の時には「FizzBuzz」と表示する。3もしくは5の倍数でない時にはその数字を表示する。

Buzz Fizz 202 203 Fizz Buzz 206 Fizz 208 209 FizzBuzz 211 212 Fizz 214 Buzz Fizz 217 218 Fizz Buzz 221 Fizz 223 224 FizzBuzz 226 227 Fizz 229 Buzz Fizz 232 233 Fizz Buzz 236 Fizz 238 239 FizzBuzz 241 242 Fizz 244 Buzz Fizz 247 248 Fizz Buzz 251 Fizz 253 254 FizzBuzz 256 257 Fizz 259 Buzz Fizz 262 263 Fizz Buzz 266 Fizz 268 269 FizzBuzz 271 272 Fizz 274 Buzz Fizz 277 278 Fizz Buzz 281 Fizz 283 284 FizzBuzz 286 287 Fizz 289 Buzz Fizz 292 293 Fizz Buzz 296 Fizz 298 299

詳細はFizz Buzz (Wikipedia)を参照。

その他

プログラムを作ってみよう。