Kombinasi Spring Boot dengan DataTables

Photo by Maximilian Weisbecker on Unsplash

Lama tak update tutorial programming, kali ini saya mau berbagi mengenai Spring Boot. Yup, salah satu framework besutan Spring. Praktisnya, dengan menggunakan Spring Boot memudahkan untuk development karena semuanya sudah built-in ketika setup project.

Nah, pada tutorial ini saya akan buat project sederhana yaitu menampikan database pada Jquery DataTables. Adapaun tech stack dari project ini antara lain :

  • Tentu saja Spring Boot
  • Maven (build tools)
  • Netbeans (IDE, saya pengguna setia Netbeans :D)
  • Java 8
  • JPA
  • Spring RESTful
  • Spring MVC
  • MySQL
  • Thymeleaf (template engine)
  • DataTables

Persiapan project

Oke, langsung saja kita buat projectnya, terdapat 2 cara untuk membuat project Spring Boot. Cara pertama, kita bisa setup project melalui https://start.spring.io/. Cara kedua, kita bisa setup project langsung menggunakan Netbeans dengan terlebih dahulu install plugin NB Spring Boot. Dalam tutorial ini, saya gunakan cara pertama yaitu melalui https://start.spring.io/.

Pada Group saya buat com.dekikurnia dan Artifact kita buat belajar-spring-boot. Untuk dependencies silahkan masukkan, Web, JPA, MySQL dan Thymeleaf.

Kemudian generate project, project ini dalam bentuk .zip dan silahkan ekstrak dan buka melalui IDE.

Sebelumnnya silahkan pindahkan BelajarSpringBootApplication.java pada folder package com.dekikurnia.

Karena kita menggunakan template engine Thymeleaf maka kita perlu menambahkan dependency nekohtml. Buka pom.xml tambahkan dependency nekohtml. Berikut kode lengkapnya :

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
 
    <groupId>com.dekikurnia</groupId>
    <artifactId>belajar-spring-boot</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
 
    <name>belajar-java-web</name>
    <description>Belajar Java Web dengan Spring Boot</description>
 
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
 
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>
 
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
 
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
                <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
                <dependency>
                    <groupId>net.sourceforge.nekohtml</groupId>
                    <artifactId>nekohtml</artifactId>
                    <version>1.9.21</version>
                </dependency>
    </dependencies>
 
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

Buka application.properties tambahkan script dibawah.  Setelah itu silahkan buat database di MySQL, pastikan sesuai dengan konfigurasi database pada application.properties.

spring.thymeleaf.mode=LEGACYHTML5
spring.thymeleaf.cache=false
 
spring.datasource.url=jdbc:mysql://localhost:3306/javaweb
spring.datasource.username=root
spring.datasource.password=passworddb
 
spring.jpa.hibernate.ddl-auto=update

Server side

Kemudian, kita buat package baru untuk entity (entitas) class. Buat dengan nama com.dekikurnia.entities, lalu buat class Product.java

package com.dekikurnia.entities;
 
import java.math.BigDecimal;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Version;
 
/**
 *
 * @author dekikurnia
 */
@Entity
public class Product {
   
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Integer id;
       
    @Column(name="name", length=100)
    private String name;
   
    @Column(name="price", length=19)
    private BigDecimal price;
   
    @Column(name="product_id")
    private String productId;
       
    @Version
    private Integer version;
 
    public Product() {
    super();
    }
   
    public Product(String name, BigDecimal price, String productId, Integer version) {
    super();
        this.name = name;
        this.price = price;
        this.productId = productId;
        this.version = version;
    }
 
    public Integer getId() {
        return id;
    }
 
    public void setId(Integer id) {
        this.id = id;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public BigDecimal getPrice() {
        return price;
    }
 
    public void setPrice(BigDecimal price) {
        this.price = price;
    }
 
    public String getProductId() {
        return productId;
    }
 
    public void setProductId(String productId) {
        this.productId = productId;
    }
 
    public Integer getVersion() {
        return version;
    }
 
    public void setVersion(Integer version) {
        this.version = version;
    }    
}

Kita gunakan anotasi @Version gunanya sebagai melihat perubahan ketika mengubah data, misalnya kita merubah suatu data sebanyak 2 kali, maka isi version otomatis terisi 2. Untuk pengertian anotasi lain di Spring Framework, silahkan googling sendiri karena saya tidak menjelaskan secara detil pada tulisan ini.

Setelah membuat class entitas, kita buat package repositories dengan nama com.dekikurnia.repositories. Buat interface baru dengan nama ProductRepository.java

package com.dekikurnia.repositories;
 
import com.dekikurnia.entities.Product;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
 
/**
 *
 * @author dekikurnia
 */
@Repository("productRepository")
public interface ProductRepository extends CrudRepository<Product, Integer>{
 
}

Buat package com.dekikurnia.services, kemudian buat interface ProductService.java.

package com.dekikurnia.services;
 
import com.dekikurnia.entities.Product;
import java.util.List;
 
/**
 *
 * @author dekikurnia
 */
public interface ProductService {
    Iterable<Product> getAllProducts();
    public Product getProductById(Integer id);
}

Setelah itu, buat class implementasi, buat dengan nama ProductServiceImpl,pada class ini kita buat dua buah method yaitu menampilkan semua product dan menampilkan berdasarkan primary key (id).

package com.dekikurnia.services;
 
import com.dekikurnia.entities.Product;
import com.dekikurnia.repositories.ProductRepository;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
/**
 *
 * @author dekikurnia
 */
@Service("productService")
public class ProductServiceImpl implements ProductService{
   
    private ProductRepository productRepository;
 
    @Autowired
    public void setProductRepository(ProductRepository productRepository) {
        this.productRepository = productRepository;
    }
 
    @Override
    public Iterable <Product> getAllProducts() {
        return productRepository.findAll();
    }
 
    @Override
    public Product getProductById(Integer id) {
        return productRepository.findOne(id);
    }
}

Terakhir, kita buat package controller buat dengan namacom.dekikurnia.controllers,  buat dua buah class yaitu ProductController.java dan ProductRestController.java. ProductController.java adalah class logic dimana kita mendefinisikan url untuk melihat data product beserta dengan methodnya, sedangkan ProductRestController adalah untuk membuat api dalam bentuk format JSON.

package com.dekikurnia.controllers;
 
import com.dekikurnia.entities.Product;
import com.dekikurnia.services.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
 
/**
 *
 * @author dekikurnia
 */
@Controller
public class ProductController {
   
    private ProductService productService;
 
    @Autowired
    public void setProductService(ProductService productService) {
        this.productService = productService;
    }
   
    @RequestMapping(path="/products", method=RequestMethod.GET)
    public String goProduct() {
        return "product";
    }
}
package com.dekikurnia.controllers;
 
import com.dekikurnia.entities.Product;
import com.dekikurnia.services.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
 
/**
 *
 * @author dekikurnia
 */
@RestController
public class ProductRestController {
   
    @Autowired
    private ProductService productService;
   
    @RequestMapping(path="/api/products", method=RequestMethod.GET)
    public Iterable <Product> getAllProducts() {
        return productService.getAllProducts();
    }
   
    @RequestMapping(path="/api/products/{id}", method=RequestMethod.GET)
    public Product getProductById(@PathVariable("id") Integer id) {
        return productService.getProductById(id);
    }
}

Client side

Setelah semua kode untuk server side selesai, tibalah kita untuk koding pada client side. Sebelumnya, kita buat terlebih dahulu file sql yang gunanya untuk membuat sample data. Mari kita buat file sql, letakkan sejajar dengan application.properties

INSERT INTO product (name, price, product_id, version) values ('Mie Goreng Indomie','2500','01','1');
INSERT INTO product (name, price, product_id, version) values ('Mie Indomie Soto','2000','01','1');
INSERT INTO product (name, price, product_id, version) values ('Aqua Gelas','1000','01','1');

Pada package/folder static buat folder/package baru js, kita buat dengan nama product.js. Sederhananya pada file js ini kita mengambil resource /api/products yang telah kita buat pada class ProductRestController, jadi kita mengeksekusi RESTful dalam hal ini berformat JSON.

$(document).ready (function() {
var table = $('#productsTable').DataTable({          
            "sAjaxSource": "/api/products",
            "sAjaxDataProp": "",
            "order": [[ 0, "asc" ]],
            "columns": [
                { "mData": "id"},
                { "mData": "name" },
                { "mData": "price" },
                { "mData": "productId" },
                { "mData": "version" }                
            ]
     })
});

Terakhir buat file product.html dalam package template :

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:th="http://www.thymeleaf.org">
   <head>
        <meta charset="utf-8" />
        <title>Latihan Spring Boot</title>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.15/js/jquery.dataTables.min.js"></script>
        <script src="/js/product.js"></script>
        <link rel="stylesheet" href=
       "https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
        <link rel="stylesheet"
             href="https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.15/css/jquery.dataTables.min.css">
    </head>
    <body>
        <div class="container">
            <h1>Products Table</h1>
            <table id="productsTable" class="display">
                <thead>
                    <tr>
                        <th>Id</th>
                        <th>Name</th>
                        <th>Price</th>
                        <th>Product ID</th>
                        <th>Version</th>
                    </tr>
                </thead>
            </table>
        </div>
    </body>
</html>

Saatnya testing, jalankan project, buka terminal/cmd :

mvn spring-boot:run

Buka localhost:8080/products

Kemudian buka localhost:8080/api/products atau berdasarkan id localhost:8080/api/products/112

Source code lengkap https://github.com/dekikurnia/simple-spring-boot

Post Author: dekikurnia