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を追加する
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
application.propatiesに以下を記述
雛形はClustersのDB名にあるconnectから発行できる(MongoDB Atlasの場合)
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~でメソッドを記述すれば良い。
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のメソッドを使用する。
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);
//記事の削除
}
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を呼び出すハンドラーメソッドを実装する。
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が強力なので認証と疎通がとれればメソッドの記述は容易
参考文献
Discussion