JavaでWebアプリ制作を学習してみよう。- データベースの利用 –
今回は Spring Boot で Webアプリケーションを制作する際に必要不可欠なデータベースアクセスについてまとめてみました。
注意:
ここに書いている内容は私が独学でネット情報を色々読んで自分なりに学習し、頭の整理も兼ねてまとめたものです。誤った認識をしている場合があります。予めご理解の上読んで下さい。
Spring Boot データベースの使用
前回のSpring Boot のMVCの説明で使用したイメージ図にデータベースアクセスを追加したイメージ図を作成してみました。
データベースはM「ビジネスロジック」内で使うのが行うのが一般的であろうと思う。ユーザ認証などフィルターで使う場合もありますが...
Spring Bootのアプリ開発をネットで調べてみると 簡単なアプリであればMをCの中に記述している場合が良くあります。
Cにずらずらコードをタスキのように書かれても見にくいし、分けた方が良いかと思う。
ここではビジネスロジック(業務処理)をMとして分割しそのMの中でデータベースを使っているかを見ていく。
Serviceには、業務のデータの登録や変更、削除の他、日時月時処理の売上確認等の集計等々に対応するメソッドを書いていくことになる。各業務に対応したメソッドの中でデータベースを使用することになる。Spring Boot では Repository と Entity 、データベースに対応したデータベースドライバで利用することになる。
Entityには、データベースに作成したテーブルのカラムの定義(数字 or 文字列 or 日時等、長さなど)やキー指定や外部テーブル参照(テーブルジョイン)を書いていくことになる。
Repositoryには、キーワード検索や登録、変更等のデータベースにSQL文単位の実行メソッドを書いていくことになる。
Service・Repository・Entityをドメイン層と呼んでいたネット情報にも出くわしました。(※真偽は調べていないの不明)
前々回の
でSQLのデータベースライブラリとして
- Spring Data JDBC
- Spring Data Jpa
- JDBC API
の3つを入れていました。
実際どのライブラリが使うかは 実際にRepositoryインターフェースクラス(@Repositoryを付けたクラス)を記述する際にどのクラスを継承するかで決まります。
ただし、JDBC APIは例外と考えた方がよさそう。
Spring Data Jpaを使用する場合は JpaRepositoryを継承
Spring Data JDBCを使用する場合は CrudRepositoryを継承
するようにする。
うれしいことにライブラリのクラスを継承するといくつかの標準的なSQLメソッドを利用できるようになる。
独自のSQL処理をしたいい場合は独自メソッドを追加して実装していくことになる。
は独自メソッドを追加して実装していくときインターフェースクラスと実装クラスを分けて書くのが主流なのだろうか?どっちが良いかは使いながら判断しようと思う。
JDBC API については、歴史が古く低次元なデータベースアクセスを提供するライブラリのようでentityを使用せずにダイレクトなデータベースのSQL文を記述し実行させる。
Spring Bootを勉強する以前にjavaを使っていた時はJDBC APIを使った記憶があります。
低次元ライブラリなので使いこなせるならば自由度が大きく細かいテクニックをつかえるのではないかと思う。
今の私はWebアプリを先ずは効率よく早く全体が動くように作りたいので Spring Data Jpa や Spring Data JDBC を使おうと考えています。
運よく作ったWebアプリが利用者が増えた(売れた・当たった)ならば利用者増により発生しそうな処理性能の低下を予測してデータベースアクセス処理の改善を図る必要があると判断すれば行うという位置付けでいます。その際の対策として低次元なデータベースアクセスに降りていくという選択肢も一つかも。
なので日々のWebアプリが稼働するシステムのモニタリング(監視)等の運用保守管理も大切な仕事ですね。
Spring Bootを勉強する前までのjavaの経験ではデータベースアクセスといえばJDBC API を使用していました。
データベースアクセス周りの処理にいては、データ(レコード)量が少ないうちは問題なかったけどデータ(レコード)量が増えたら極端に結果表示が遅くなってしまうことを経験したことがあるかと思います。アプリ作成が完成した後もこの手の問題はデータベースのデータ量が増えていくことによって発生するものなので、あらかじめ頭に入れておいて対応するためのリソース(人・対応策・時間)を準備しておく必要があるかもしれませんね。負荷分散やクエリー系のSQL文の見直しが必要になるかもしれません。
大規模システムのアプリを開発した経験持っている場合は、それらのノウハウを最初からデータベースアクセス処理コードに反映しておくとよいのかもしれません。
チームにその経験がない場合はこのような問題が起こるかもしれないということを考慮しておく必要はあると思います。発生したときにジタバタしないように。。。
また、前々回の
ではSQLのデータベースとして「MySQL」を選択しました。
使用するデータベースは上の図の「application.properties」ファイルのパラメータ「Spring.datasource.******=XXXX」の記述を変更することで簡単に変更できます。
最も
・Mavenの場合「pom.xlm」ファイル
・Gradleの場合は「build.gradle」ファイル
に使用するデータベースのライブラリを記述しておくことも必要ですよ。
開発初期段階ではローカルで使用できる「H2」を使用して「ビジネスロジック」のコードの作成を行う。
開発途中から実稼働環境に近い本格的なデータベースサーバ「MySQL」や「PostgreSQL」「Oracle」...に換えるということが容易に行えるなぁと思っている。
ただし、Entityのテーブル定義の記述をデータベースの種類に依存しないようにするテクニックはいるかもしれないなぁということを今は頭の中に残している。
実際のデータベースの設定は「src/main/resource/application.properties」で行います。
例:H2データベースの場合
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:./h2db
spring.datasource.username=hoge
spring.datasource.password=hoge
spring.datasource.sql-script-encoding=utf-8
spring.h2.console.enabled=true
spring.datasource.initialization-mode=never
例:MySQLデータベースの場合
spring.datasource.url=jdbc:mysql://192.168.1.100:3306/testdb
spring.datasource.username=hoge
spring.datasource.password=hoge
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.sql-script-encoding=utf-8
ここで書いた以外のパラメータがあります。自分で調べてください。
余談:
Entityクラス(@Entityアノテーションを付けたクラス)は意味のあるデータの集まりを定義するものなのでWebクライアントからのRequestのFormデータをEntityで受け取ることも出来るようです。個々のFromデータを個別に取得しなくて済むので便利かも。