ใช้งาน MongoDB NoSQL database ใน Spring Boot project

สำหรับการเก็บข้อมูลบางอย่าง หรือการทำ prototyping project แบบไวๆ ผมมองว่าการใช้งาน MongoDB ซึ่งเป็น NoSQL database ที่มองว่าข้อมูลที่เราต้องการเก็บเป็น document หรือหน้าเอกสารหนึ่งหน้า แทนที่เราจะต้องแยกข้อมูลเป็นตารางดังเช่นที่เราทำกันใน relational database ( MySQL, SQL Server) เราก็สามารถโยนข้อมูลทั้งก้อนเข้าไปเก็บได้เลย ไม่ต้องสนใจเรื่องการ normalization ช่วยในการเก็บและดึงข้อมูลมาใช้ได้อย่างสะดวก ไม่ต้องมีการ join เกิดขึ้น

ข้อดีบางส่วนของ MongoDB

  • MongoDB Server สามารถติดตั้งได้ทั้งบน Windows และ Linux
  • มี client library รองรับหลายภาษา เช่น C#, Java, C++, NodeJS, Python, Ruby, PHP
  • เป็น open source project เอามาใช้งานได้ฟรี

สำหรับในบทความนี้ เราจะมาเรียนรู้การใช้งาน Spring Boot กับ MongoDB กัน โดยมีขั้นตอนต่างๆ ดังนี้

  • ติดตั้ง MongoDB Community Edition บนเครื่อง Windows
  • ทดลองใช้งาน MongoDB Shell
  • สร้าง Spring Boot REST API ง่ายๆ
  • ใช้งาน Spring Data MongoTemplate สร้าง CRUD operation
  • ทดสอบการใช้งาน

ติดตั้ง MongoDB Community Edition บนเครื่อง Windows

  • download MongoDB จากหน้า website ของ MongoDB ได้โดยตรง หรือจาก URL https://www.mongodb.org/downloads
  • เลือก version ให้ตรงกับ Spec ของเครื่องผู้อ่าน เช่นถ้าใช้ Windows 64 bit ก็เลือก file 64 bit version แต่ถ้าใช้เครื่อง 32 bit อยู่ก็เลือก 32 bit version ในตัวอย่างนี้ผมได้เลือก file Windows 64-bit 2008 R2+
  • ทำการติดตั้งโดยกดปุ่ม next ไปเรื่อยๆ
  • เมื่อติดตั้งเรียบร้อยแล้ว เข้าไปใน bin folder ที่ติดตั้ง MongoDB แล้วเปิด command line ที่ folder ดังกล่าว ตัวอย่างเช่น C:\Program Files\MongoDB\Server\3.2\bin
  • สร้าง folder สำหรับเก็บ database file ที่ C:\data\db
  • แล้วใช้คำสั่ง mongod เพื่อเปิดใช้งาน MongoDB Server

mongod command เพื่อเปิดการทำงานของ MongoDB server image title

ทดลองใช้งาน MongoDB Shell

  • ไปที่ folder เข้าไปใน bin folder ของ MongoDB เช่น
  • เปิด command line อีกตัวเพื่อใช้งาน MongoDb shell ด้วยคำสั่ง mongo
  • ใช้คำสั่ง use testเป็นคำสั่งเพื่อเปลี่ยนไปเชื่อมต่อกับ database ที่ว่า test
  • หากผลลัพธ์แสดงออกมาดังเช่นในรูปต่อไปนี้ แสดงว่าเราได้ทำการติดตั้ง MongoDB บนเครื่องของเราเรียบร้อยแล้วครับ

image title

สร้าง Spring Boot REST API ง่ายๆ

ผมจะแสดงเพียง code ตัวอย่างและคำอธิบายเพียงสั้นๆ หากผู้อ่านท่านใดที่ยังไม่เคยลองใช้งาน Spring Boot สามารถอ่านพื้นฐานได้จาก link ต่อไปนี้ครับ เริ่มต้นกับ Spring Boot

เริ่มต้นสร้าง Spring Boot REST ด้วยขั้นตอนต่อไปนี้

เปิดใช้งาน Intellij IDEA

สร้าง Gradle project ใหม่ โดยกำหนดค่าต่างๆ ดังนี้

  • group id: com.codesanook.example
  • artifact id : spring-boot-mongodb

แก้ไข build.gradle เพื่อใช้ Spring dada Mongo Library

build.gradle

group 'com.codesanook.example'
version '1.0-SNAPSHOT'

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.7.RELEASE")
    }
}
apply plugin: 'spring-boot'
apply plugin: 'java'

sourceCompatibility = 1.7

repositories {
    mavenCentral()
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web:1.2.7.RELEASE")
    compile("org.springframework.boot:spring-boot-starter-data-mongodb:1.2.7.RELEASE")
}

สร้าง Customer.java สำหรับเป็น model ของข้อมูลลูกค้า

src\main\java\com\codesanook\examplemodel\Customer.java

package com.codesanook.example.model;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;

@Document(collection = "customers")
public class Customer {

    @Id
    private String id;

    private String firstName;
    private String lastName;

    @Indexed(unique = true)
    private String email;

    public String getId() {
        return id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

สร้าง CustomerController.java เป็น Controller ใช้สำหรับเพิ่ม แสดง แก้ไข ลบข้อมูลของลูกค้า พร้อมกำหนด URL ตาม REST API standard

src\main\java\com\codesanook\example\controller\CustomerController.java

package com.codesanook.example.controller;

import com.codesanook.example.model.Customer;
import org.springframework.web.bind.annotation.*;
import java.util.List;


@RestController
@RequestMapping("/customers")
public class CustomerController {

    //URL : /customers
    //add new customer
    @RequestMapping(value = "", method = RequestMethod.POST)
    public String addCustomer(@RequestBody Customer customer) {
        throw new IllegalStateException("not implemented");
    }

    //URL : /customers/{id}
    //get customer by id
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public Customer getCustomer(@PathVariable String id) {
        throw new IllegalStateException("not implemented");
    }

    //URL : /customers
    //get all customers
    @RequestMapping(value = "", method = RequestMethod.GET)
    public List<Customer> getAllCustomers() {
        throw new IllegalStateException("not implemented");
    }


    //URL : /customers/{id}
    //update customer with id
    @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
    public void updateCustomer(@PathVariable String id, @RequestBody Customer request) {
        throw new IllegalStateException("not implemented");
    }

    //URL : /customers/{id}
    //remove customer by id
    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
    public void remove(@PathVariable String id) {
        throw new IllegalStateException("not implemented");
    }

    //URL : /customers
    //remove all customers
    @RequestMapping(value = "", method = RequestMethod.DELETE)
    public void removeAll() {
        throw new IllegalStateException("not implemented");
    }

    //URL : /customers/count
    //get count amount of customers
    @RequestMapping("/count")
    public long countCustomer() {
        throw new IllegalStateException("not implemented");
    }

}

สร้าง Application.java เพื่อเป็น entry point ของ Application

src\main\java\com\codesanook\example\Application.java

package com.codesanook.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

ใช้งาน Spring Data MongoTemplate สร้าง CRUD operation

Spring Boot ได้เตรียม MongoTemplate bean ให้เราใช้งานได้เลย เพียง inject เข้าไปยัง class ที่เราจะเรียกใช้ MongoTemplate แก้ไข CustomerController.java เพื่อเพิ่มคำสั่งใช้งาน MongoTemplate ในการแก้ไขข้อมูล Customer

constructor injection

    private MongoTemplate mongoTemplate;

    @Autowired
    public CustomerController(MongoTemplate mongoTemplate) {
        this.mongoTemplate = mongoTemplate;
    }

คำสั่งสำหรับเพิ่มข้อมูลลูกค้า

    //URL : /customers
    //add new customer
    @RequestMapping(value = "", method = RequestMethod.POST)
    public String addCustomer(@RequestBody Customer customer) {
        mongoTemplate.insert(customer);
        return customer.getId();
    }

คำสั่งสำหรับดึงข้อมูลลูกค้าด้วย id

    //URL : /customers/{id}
    //get customer by id
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public Customer getCustomer(@PathVariable String id) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));
        Customer customer = mongoTemplate.findOne(query, Customer.class);
        return customer;    
    }

คำสั่งสำหรับดึงข้อมูลของลูกค้าทั้งหมดที่มีอยู่ออกมา

    //URL : /customers
    //get all customers
    @RequestMapping(value = "", method = RequestMethod.GET)
    public List<Customer> getAllCustomers() {
        List<Customer> customer = mongoTemplate.findAll(Customer.class);
        return customer;
    }

คำสั่งสำหรับแก้ไขข้อมูลของลูกค้า

    //URL : /customers/{id}
    //update customer with id
    @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
    public void updateCustomer(@PathVariable String id, @RequestBody Customer request) {
        Query query = new Query(Criteria.where("id").is(id));
        Customer customer = mongoTemplate.findOne(query, Customer.class);
        customer.setFirstName(request.getFirstName());
        customer.setLastName(request.getLastName());
        mongoTemplate.save(customer);
    }

คำสั่งสำหรับลบข้อมูลของลูกค้า

    //URL : /customers/{id}
    //remove customer by id
    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
    public void remove(@PathVariable String id) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));
        mongoTemplate.remove(query, Customer.class);
    }

ตัวอย่างคำสั่งทั้งหมดของ CustomerController.java

package com.codesanook.example.controller;

import com.codesanook.example.model.Customer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.web.bind.annotation.*;
import java.util.List;

@RestController
@RequestMapping("/customers")
public class CustomerController {

    private MongoTemplate mongoTemplate;

    @Autowired
    public CustomerController(MongoTemplate mongoTemplate) {
        this.mongoTemplate = mongoTemplate;
    }

    //URL : /customers
    //add new customer
    @RequestMapping(value = "", method = RequestMethod.POST)
    public String addCustomer(@RequestBody Customer customer) {
        mongoTemplate.insert(customer);
        return customer.getId();
    }

    //URL : /customers/{id}
    //get customer by id
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public Customer getCustomer(@PathVariable String id) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));
        Customer customer = mongoTemplate.findOne(query, Customer.class);
        return customer;
    }

    //URL : /customers
    //get all customers
    @RequestMapping(value = "", method = RequestMethod.GET)
    public List<Customer> getAllCustomers() {
        List<Customer> customer = mongoTemplate.findAll(Customer.class);
        return customer;
    }


    //URL : /customers/{id}
    //update customer with id
    @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
    public void updateCustomer(@PathVariable String id, @RequestBody Customer request) {
        Query query = new Query(Criteria.where("id").is(id));
        Customer customer = mongoTemplate.findOne(query, Customer.class);
        customer.setFirstName(request.getFirstName());
        customer.setLastName(request.getLastName());
        mongoTemplate.save(customer);
    }

    //URL : /customers/{id}
    //remove customer by id
    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
    public void remove(@PathVariable String id) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));
        mongoTemplate.remove(query, Customer.class);
    }

    //URL : /customers
    //remove all customers
    @RequestMapping(value = "", method = RequestMethod.DELETE)
    public void removeAll() {
        Query query = new Query();
        mongoTemplate.remove(query, Customer.class);
    }

    //URL : /customers/count
    //get count amount of customers
    @RequestMapping("/count")
    public long countCustomer() {
        Query query = new Query();
        long count = mongoTemplate.count(query, Customer.class);
        return count;
    }

}

ทดสอบการทำงาน

ผมใช้ browser chrome และ Advanced REST client plugin สามารถติดตั้งได้ผ่าน Chrome Web Store image title

run Spring Boot Application และใช้ Advanced REST client plugin ของ Chrome ทดสอบ REST API ที่บันทึกข้อมูลลง MongoDB กรอกข้อมูลลงไปใน Advanced REST client plugin และกดปุ่ม send จะได้ id ของลูกค้า (customer) กลับมา

ทดสอบการทำงานสร้างข้อมูลลูกค้าใหม่ insert

image title

ทดสอบดึงข้อมูลลูกค้า (get customer) ด้วย id

image title

ทดสอบดึงข้อมูลทั้งหมด

image title

ทดสอบแก้ไขข้อมูล

image title

ทดสอบลบข้อมูล

image title

ส่งท้าย

หวังเป็นอย่างยิ่งว่าผู้อ่านได้เข้าใจและเห็นภาพการทำงานของ Spring Boot และ MongoDB

ใครมีคำถาม ข้อสงสัยใด comment กันเข้ามาได้เลยนะครับ

download source code