きり丸の技術日記

技術検証したり、資格等をここに残していきます。

MyBatisを使用してデータの取得・更新をする(JavaとSpringBoot)

きり丸アドベントカレンダー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の処理を呼んだ方がいいです。

  1. Controller
  2. Service
  3. 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

f:id:nainaistar:20201109133010p:plain