開発チーム(s.w)こんにちは。タグボート開発チームのワシヅカです。最近冬に備えて少しずつ肥えてきました。今日は、2回目から使っているサンプルプロジェクトのDBアクセス部分を中心に確認していきたいと思います。1.ログ出力レベルの変更...と作業の前に。ログレベルを設定しておきましょう。下のように変更しておくと、データベースアクセスが発生した際にSQLログを出力してくれます。application.propertiesに以下の1行を追加しておきましょう。ログ出力レベルの変更logging.level.org.hibernate.SQL=TRACE1logging.level.org.hibernate.SQL=TRACE2.「UserRepository.java」を読み解くそれでは、DBアクセス部分を確認していきたいと思います。「MainController」クラスの「getAllUsers」メソッドを覗いてみましょう。このメソッドは、たった1行です。userRepository.findAll();とだけコードが書いてあります。「UserRepository」インターフェースの「findAll」メソッドを呼び出してUSERテーブルからデータ抽出を行っています。「MainController」クラスの中で、「@Autowired」アノテーションとともに「UserRepository」インターフェースを宣言することで、「UserRepository」インターフェースは自動的に利用可能な状態になっています。英語で書かれているコメント行にもそのようなことが書かれていますね。続いて「UserRepository」インターフェースの中身を見てみましょう。なんと、このインターフェースは中身がほとんど書かれていません。見ると「CrudRepository」を継承していることがわかります。実はこの継承がポイントです。継承の階層構造を見てみましょう。CrudRepositoryにポインタを合わせ、右クリック→[型階層を開く]とすると「型階層」タブにされます。CrudRepositoryにはたくさんのメソッドがあることが分かります。saveメソッドにctrlキー押しながらポインタをあわせ、[実装を開く]をクリックしてみましょう。実際の実装を確認する事ができます。「SimpleJpaRepository」クラスで実装されているようです。細かい実装を追い続けると「AbstractEntityManagerImpl」あたりの深いところまで行ってしまいそうなので、今回はこの先は追いませんが、このような階層構造を引き継ぎながら動いていることが分かります。API)というAPIを利用して実現しています。サンプルプロジェクトのpom.xmlにも「JPAを使っているよ」と書かれています。--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency>3.条件を付けて検索可能にしてみる(WHERE句)さて、この「UserRepository」クラスで名前(name)カラムを条件に検索可能なメソッドを定義してみましょう。以下の1行を追加してください。name);また「MainController」クラスには以下のような呼出メソッドを追加します。userRepository.findByName(name);}追加し終わったら、アプリケーションを実行してブラウザで以下のURLにアクセスしてみましょう。http://localhost:8080/demo/user-by-name?name=hogehogenameカラムに”hogehoge”を持つデータが取得できました。ログも確認してみましょう。ログにもしっかりWHERE句がついて出力されていますね。BY句)もう1つおまけに、並び順も付けてみましょう。今度は、名前(nameカラム)を条件にし登録が新しい順(IDが大きい順)で取得できるメソッドを定義してみます。先ほどと同様にUserRepositoryクラスに以下のようにメソッドを定義してあげます。name);コントロールクラスは、先ほどのメソッドを使ってしまいましょう。呼出メソッドに「OrderByIdDesc」と追加してあげます。データベースのデータの状態は以下のような感じです。先ほどと同じURLを叩くことでデータが取得可能です。http://localhost:8080/demo/user-by-name?name=hogehoge見事にname=”hogehoge”を条件に、idを降順に並び替えたデータを取得することができました。このように、メソッド名の命名規則によって検索クエリを変更することが可能となっています。5.データを更新(UPDATE)するだいたい要領がつかめてきました。データの更新はどのメソッドを使えば良いのでしょうか。これは、saveメソッドを使います。実は先ほど深追いしかけた際に「em.merge(entity);」というキーワードがありました。(このページの5枚目のスクリーンショットです。)saveメソッドは、テーブルキーに対してデータが無ければINSERT、データが有れば更新という動作をしてくれます。試しに以下のようなデータを更新するメソッドをコントローラクラスに追加してみます。userEntity;}サンプルのUserクラス(エンティティークラス)はidが@Idアノテーションによりキーとなっています。「UserRepository」インターフェースの定義を少し修正します。Integer>書き終わったら実行してみます。実行前のDBの状態は以下のようになっています。ブラウザから以下のURLにアクセスしてみましょう。http://localhost:8080/demo/update-user?id=9&name=kyapikyapi&email=email99ブレイクポイントを事前に張っておきました。パラメータが予定通りリクエストされています。F8キーを押して再開してみましょう。データベースが更新されて、画面へ値が返却されました。5.データ更新中にエラーが発生した場合のロールバック更新中にエラーが発生した場合のロールバックについて確認してみましょう。トランザクションの管理は@Transactionalアノテーションで実現できます。Exceptionが発生した場合、ロールバックしてくれるようになります。今回はすべてのエラーと例外のスーパークラスであるThrowable.classが発生したのをトリガーにロールバックするように書いています。Throwable.class)では、実際にSQL実行エラーを発生させてみましょう。varchar(255)で定義されているnameカラムにそれ以上の文字列のデータを入力してみましょう。下は実行してブレークを張った状態です。nameプロパティーに長い文字列が代入されていることが分かります。そのままF8キーで再開します。エラーが発生しました。nameカラムに長過ぎるデータが発生しているとログ出力されています。画面を見てみると「Exceptionが発生して実行できません」と表示されています。肝心のデータベースを確認してみましょう。データは更新されずに、実行前のままとなっています。こんな風に書いて、意図的にRuntimeExceptionをスローしても良かったかもしれません。RuntimeException();}余談ですが、継承元をJpaRepositoryに変更するとページャーのような一部データ取得のようなこともできそうです。これについては別の機会に検証してみたいと思います。BY句の着いたSQLを実行することができるロールバックは@Transactionalアノテーションを付与しトランザクション管理を行うことで実現できる今回もだいぶ長くなってしまいました。いかかでしたでしょうか?ここまでサンプルプロジェクトを少し拡張しながら見てきました。Startedのサンプル解説ページ(英語)で紹介されていますが、少し機能追加しながら見てきました。次回は、ThymeLeafを使ったHTML出力を紹介したいと思います。PMwebシステム開発、spring、javaの初心者の私でもわかりやすいため参考にさせていただいております。1点、ご教示ください。Throwable.class)という記述ですが、rollbackOnだとエラーになってしまいます。rollbackForにするとエラーが消えましたがrollbackForが正しいのでしょうか?またこのような基本的な知識を習得するには何(本、サイト)を参考にするとよいかご教示頂けると幸甚です。PMここに書いてある通りに実装し、実行したところ、タイプUserのfindOneプロパティが見つかりません!といったエラーが出力されてしまいました。何をどう調べればよいか、またはどう対処すればよいか、ご教示頂けると幸甚です。‘userRepository’で表現されている満足度の低い依存関係。‘userRepository’という名前のBeanの作成中にエラーが発生しました:initメソッドの呼び出しに失敗しました。AMweb開発初心者さん、こんにちは♪コメントありがとうございます。Throwable.class)とコーディングするとエラーになってしまう...。SpringToolSuite(eclipse)をご使用でしたら、コントロールキーを押しながら@Transactionalと書いた文字の上にマウスのポインタをあてて、クリックしてみてください。{};という記載があると思います。javax.transaction.Transactional;という記述がないのではないかな?(もしくは、べつのパッケージを利用しているのかな?)と思います。個人的に新しい技術を勉強するときは、まず書籍を探して勉強するようにしています。Webですと断片的に情報が入ってきてしまうので、最初は本でさっと体系的に勉強するのがよいかなと思っています。そのあとでWebでより詳しい情報を調べるようにしています。SpringBootの場合はWebで検索するとSpringも検索に引っかかってしまうので、なかなか良い情報にたどり着けないんですけれども...。おすすめの書籍ですが、私はこちらを購入して読んでいました。コメントをキャンセルメールアドレスが公開されることはありません。*サイト次回のコメントで使用するためブラウザーに自分の名前、メールアドレス、サイトを保存する。コメントデータの処理方法の詳細はこちらをご覧ください。