きり丸アドベントカレンダー2020の8記事目です。
今回の記事でDBの更新を行います。データの取得(Select)と追加(Insert)をこの記事で紹介します。
更新と削除に関しても同様の処理で問題ありませんので、頑張ってみてください。なお、9日目にDBのテストコードを書きますので、9日目までは更新・削除は実装いたしません。
ゴール
- データの取得を行う
- データの更新を行う
手順
画面項目を修正する
7日目の記事を作成していた時は、TODO項目に対してIdとUserIdを固定させていましたが、ハンドリングが面倒くさいので追加するときだけは入力できるようにします。
ファイル名:index.html
<form action="/" method="post"> <td><input type="text" name="id"/></td> <!-- input項目を追加 --> <td><input type="text" name="userId"/></td><!-- input項目を追加 --> <td><input type="text" name="action"/></td> <td><input type="submit" name="add" value="追加"/></td> </form>
テーブル項目を追加する
画面上にはaction
項目を追加いたしましたが、テーブル定義にはまだaction
項目を追加していません。ですので、action
項目を追加します。
また、現在のまま修正すると再度CREATE TABLE
を実行してしまい、起動しなくなってしまいます。ですので、1回TODOSテーブルを削除する必要があります。
ファイル名:R__test.sql
DROP TABLE IF EXISTS TODOS CASCADE; -- TODOテーブルを削除する CREATE TABLE TODOS( id int, user_id varchar, action varchar -- action項目追加 );
取得と追加を行うMapperを準備する(DBへのアクセス)
今回はMyBatisを使用しています。
MyBatisでは、interfaceに@Mapper
を付与します。
追加するときはメソッドに@Insert
、検索するときは@Select
、更新は@Update
、削除は@Delete
を付与するとそれぞれのメソッドで実行できます。
ファイル名:TodoRepository.java
@Mapper public interface TodoRepository { @Insert("INSERT INTO todos (id, user_id, action) VALUES (#{id}, #{userId}, #{action})") public void insert(TodoDto todo); @Select("SELECT * FROM todos WHERE user_id = #{userId}") public List<TodoDto> findList(String userId); }
MyBatisの設定でキャメルケースをマッピングできるようにする
キャメルケースとスネークケースという、命名規則があります。
- キャメルケース
- userIdのように、単語と単語の間の英単語を大文字にする
- スネークケース
- user_idのように、単語と単語の間の英単語をアンダースコアでつなぐ。
Javaの項目名はキャメルケースのuserId
、DBの項目名はスネークケースのuser_id
となっており、MyBatisが自動でマッピングしてくれません。ですので、うまくマッピングできるようにします。
ファイル名:application.yml
mybatis: configuration: map-underscore-to-camel-case: true
なお、もしこの設定を行わずにマッピングしようと思ったらエイリアスを使用する必要があります。こちらでも問題ありませんが、手間がかかるので上記の設定ファイルの修正の方がよいでしょう。
SELECT user_id as userId FROM TODOS;
コントローラに処理を追加する
本来であれば、アーキテクチャを意識して下記流れでDBの処理を呼んだ方がいいです。
- Controller
- Service
- Repository
ただし、現在はトランザクション管理等も行っていないので、Controllerから直接Mapperを呼んでしまいましょう。クラスの生成はコンストラクタに設定すると、Springが自動でDIしてくれるようになります。
Lombokの@RequiredArgsCOnstructor
を付与すると、private final
な変数に対してコンストラクタを生成してくれるので、便利です。
ここまで実施すれば、TODOの追加と検索ができるようになりました!
ファイル名:IndexController.java
@RequiredArgsConstructor // コンストラクタ自動生成 public class IndexController { private final TodoRepository todoRepository; // DBへのアクセスクラス @PostMapping(value="/", params="add") public String add(TodoDto model){ todoRepository.insert(model); // insertクラスの呼び出し return "redirect:/"; } }
なお、DIする際は@Autowired
を付与することでも同様の処理になります。
しかし、こちらのやり方で生成してしまうとテストが難しくなってしまいます。もちろん可能ですし、大した手間ではないのですが…。
少しでも楽をできるほうがよいので、コンストラクタでDIしましょう。
ソースコード
アドベントカレンダー8日目。
github.com
終わりに
8日目の処理で基本的なことは一気通貫でできるようになりました。ただし、基本的にこの一気通貫できるようになっていれば、最低限開発はできます。
ただし、現状のままでは動きはするものの、テストコードが無いので品質を担保できません。次回はDBのテストを行います。
この記事がお役に立ちましたら、各種SNSでのシェアや、今後も情報発信しますのでフォローよろしくお願いします。
類似記事
きり丸アドベントカレンダー2020 adventar.org
きり丸のHerokuページ
https://kirimaru-todoapp.herokuapp.com/
9日目のアドベントカレンダーの記事 https://nainaistar.hatenablog.com/entry/2020/12/09/083000nainaistar.hatenablog.com