Spring BootでMongoDBを操作する方法

に公開

個人的に詰まったところの備忘録

MongoDBとは

MongoDBはNoSQL(RDBのように表で管理しない)の中でもドキュメント指向と呼ばれるジャンルに該当する。キーに基づくデータをJSONのようなドキュメント形式で保持しておくことができる。
シェル(mongosh)で操作できるほか、CRUDツールのMongodb CompassでGUIで操作したり MongoDB Atlasではクラウド環境でインストール不要でデータベースを扱える。

Spring Bootで扱う

Spring BootでMongoDBを扱う方法は実は簡単で、MongoRepositoryインターフェースを継承してしまえばメソッドを呼び出すだけで基本的なCRUDが可能だ。

環境設定

build.gradleに依存関係を追加

Spring Data MongoDBを追加する

build
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'

application.propatiesに以下を記述

雛形はClustersのDB名にあるconnectから発行できる(MongoDB Atlasの場合)

application
spring.data.mongodb.uri=mongodb+srv://<db_username>:<db_password>@learningmongo.wznd2xq.mongodb.net/?retryWrites=true&w=majority&appName=<appName>

アプリケーションで使う

簡単なブログアプリを構築し、CRUD操作を試す。

Repositoryの実装

下のようなリポジトリクラスでMongoRepositoryを継承すればCRUDメソッドを記述しなくてもDBを操作できる。
カスタムクエリを追加したい場合はfindBy~でメソッドを記述すれば良い。

Repository
package com.example.MyBlog.Repository;

import com.example.MyBlog.Entity.Article;
import org.springframework.data.mongodb.repository.MongoRepository;

import java.util.List;

public interface MyBlogRepository extends MongoRepository<Article, String> {
    // ここにカスタムクエリメソッドを追加できます
    // 例: List<Article> findByTitle(String title);
    List<Article> findByPublishedTrue();
    //公開状態がtrueのものを取得
    List<Article> findByPublishedFalse();
    //公開状態がfalseのものを取得
}

Serviceの実装

記事の登録と削除のメソッドをServiceに記述する。SpringにはDIコンテナ機能があるのでinterfaceにメソッドを書き、implで依存を注入するのが良いらしい。
implでDIしたmyBlogRepositoryを通じてMongoRepositoryのメソッドを使用する。

Service
package com.example.MyBlog.Service;

import com.example.MyBlog.Entity.Article;

import java.util.List;

public interface MyBlogService {
    Article submitArticle(Article article);
    //記事の登録

    void deleteArticle(String id);
    //記事の削除
}
Serviceimpl
package com.example.MyBlog.Service;

import com.example.MyBlog.Entity.Article;
import com.example.MyBlog.Repository.MyBlogRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@Transactional
@RequiredArgsConstructor
public class MyBlogServiceImpl implements MyBlogService {

    @Autowired
    private final MyBlogRepository myBlogRepository;

    @Override
    public Article submitArticle(Article article) {
        return myBlogRepository.save(article);
    }

    @Override
    public void deleteArticle(String id) {
        myBlogRepository.deleteById(id);
    }


}


//    @Override
//    public Article editArticle(Article article) {
//        return null;
//    }

Controllerの実装

今回は"/Submit"のリクエストを受け取った際にsubmitArticleを呼び出すハンドラーメソッドと隠しメソッド"delete"を@DeleteMappingで受け取り、deleteArticleを呼び出すハンドラーメソッドを実装する。

Controller
package com.example.MyBlog.Controller;

import com.example.MyBlog.Entity.Article;
import com.example.MyBlog.Service.MyBlogService;
import com.vladsch.flexmark.ext.gfm.strikethrough.StrikethroughExtension;
import com.vladsch.flexmark.ext.tables.TablesExtension;
import com.vladsch.flexmark.util.ast.Node;
import com.vladsch.flexmark.html.HtmlRenderer;
import com.vladsch.flexmark.parser.Parser;
import com.vladsch.flexmark.util.data.MutableDataSet;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;

@Controller
@RequiredArgsConstructor
@RequestMapping("/Hello")
public class MyBlogController {



    private final MyBlogService myBlogService;


    @PostMapping({"/Submit", "/Update/{id}"})
    public String saveArticle(@PathVariable(value = "id", required = false) String id, @ModelAttribute Article article, Model model) {
        Article submitArticle = myBlogService.submitArticle(article);
        model.addAttribute("savedArticle", submitArticle);
        model.addAttribute("Submit", "登録完了");
        System.out.println("submit" + article);
        return "Submit";
    }


    @DeleteMapping("{id}")
    public String deleteArticle(@PathVariable("id") String id) {
        myBlogService.deleteArticle(id);
        return "redirect:/Hello";
    }

}

まとめ

Spring Data MongoDBが強力なので認証と疎通がとれればメソッドの記述は容易

参考文献

https://www.mongodb.com/ja-jp/docs/
https://zenn.dev/nameless_sn/articles/mongodb_tutorial
https://qiita.com/rubytomato@github/items/3c1ce7f91c576ec14423

Discussion