学生に伝えたいツイート

Spring Bootでチャートを生成・表示する

チャートを生成・表示する

ソースコード

変更(追加)

新規作成

実行例

chart

ポイント

  • チャート描画はJavaScriptで行うのが一般的だが、ここではJFreeChartを用いてサーバーサイドで生成している。
  • 画像ファイルを生成するのではなく、data URIで画像データを表示している。

Spring Bootで日付を扱う(フォームから日付を入力する)

日付を扱う

ソースコード

新規作成

ポイント

  • Javaにおいて日付の扱いは1)従来からあるDateクラスを使う方法と、2)Time APIを使う方法がある。教科書でどちらも詳しく解説されている。
  • inputタグのtypeとして、dateやdatetime-localが使える。他にもmonth等がある。
  • ThymeleafではDateに対するユーティリティーメソッドがある。

関連文書

変数の値とアドレス

前回のまとめ等

  • 配列
    • 同一型の複数のデータで、各データを添字によって区別する
    • 添字は0から始まる整数
  • 課題の解答例

課題の回答状況

  • ◯ コンパイルできるソースコードを提出している。
  • × 関数の定義の形が理解できていない。例: fizzbuzzの戻り値の型をintにしている、あるいは指定していない。
  • × 演算子を正しく理解していない。例: for文で i=i++
  • × 関数の使い方を理解していない。例: printf(“FizzBuzz “,i);

C言語における変数の値とアドレス、代入という操作について

変数の値とアドレスについて

  • 変数は値を入れておく箱のようなもの。箱の名前のことを「変数名」という。
  • 変数の値はコンピューターのメモリのどこかにに保存される。
  • 「どこか」を知りたい場合、アドレス演算子を使うと取り出すことができる。
  • 「アドレスを保存するための変数」があり、それを「ポインタ変数」という(教科書P.106、重要ポイント及び表7.1)。

この辺りをしっかり理解しておくと、Javaを勉強するときに役立つ。

代入という演算について

  • 「a = b」はbの値をコピーしてaの値にするという操作
  • 「func(a)」とした場合、aの値をコピーして関数にわたされる

値とアドレスとポインタに関するサンプルプログラム

address.c

実行して結果を確かめよう。

ポイント:

  • b: aを変更してもbの値は変わらない。
  • *c: aと同じアドレスなので、aを変更すれば*cも変わる(変わるというかaの別名が*cと言っても良い)。
  • 関数の引数は、値のコピー。

配列を引数とする関数

array.c

実行して結果を確かめよう。

ポイント:

  • 値がコピーされた新しい配列が作られるわけではない。
  • 先頭アドレスがコピーされる。
  • 値がコピーされた新しい配列が欲しい場合は、関数ないで配列を宣言し値をコピーする。

変数の入れ替え

次の実行例と同じになるように、変数の値を入れ替えるプログラムを完成させよう。

元のプログラム: swap.c

Spring Bootでメール送信を行う

メール送信

ソースコード

Gmailを使う場合の例。

変更(追加)

新規作成

関連文書

Spring Bootでユーザ認証を行う

ユーザ認証

ソースコード

変更(追加)

  • build.grade: spring-boot-starter-securityをdependenciesに追加

新規作成

関連文書

昨年度の資料はバージョンが古いので注意する必要があるが、参考になるはず。

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

前回のまとめ等

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