Guest Books CRUD spring-boot + mysql+thymeleaf

Hai hyvercoder! semua kali ini kita akan membuat aplikasi CRUD (Create Read Update Delete ) Guest-Book dimana aplikasi ini berisikan data tamu atau member, aplikasi kali ini akan mengunakan :

  • Spring-boot
  • Maven
  • Mysql
  • Java 1.8
  • Thymeleaf

Buat project spring-boot Structure project seperti ini :

Buat database dengan nama guest_books

create database guest_books;

Buat table dengan nama guest

CREATE TABLE guest_books.guest
(
  id integer PRIMARY KEY NOT NULL,
  name character varying(30),
  phone_number character varying(15)
);

 

Buat class entity dalam package entity dengan Nama Guest.java, Isi file class terse but seperti berikut

import javax.persistence.*;
import java.io.Serializable;

@Table(name = "guest")
@Entity
public class Guest implements Serializable {
    @Id
    @Column(name = "id_guest")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer idGuest;
    @Column(name = "name",length = 30)
    private String name;
    @Column(name = "phone_number",length = 15)
    private String phoneNumber;

    public Integer getIdGuest() {
        return idGuest;
    }

    public void setIdGuest(Integer idGuest) {
        this.idGuest = idGuest;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

}

Buat class GuestRepository.java Pada package repository

package com.alfazid.guestbooks.repository;

import com.alfazid.guestbooks.model.Guest;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface GuestRepository extends JpaRepository<Guest,Integer> {
    List<Guest> findByName(String name);
}

Buat class GuestController.java dalam package controller

package com.alfazid.guestbooks.controller;

import com.alfazid.guestbooks.model.Guest;
import com.alfazid.guestbooks.repository.GuestRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.ModelAndView;

import java.util.List;
import java.util.Optional;


@Controller
public class GuestController {
    @Autowired
    private GuestRepository guestRepository;

    @GetMapping("/")
    public ModelAndView getList(Model model){
        List<Guest> list = guestRepository.findAll();
        model.addAttribute("list", list);
        return new ModelAndView ("index");
    }

    @GetMapping("/param")
    public ModelAndView getListByName(Model model, @Param("name") String name){
        List<Guest> list;
        if(name.isEmpty()){
            list= guestRepository.findAll();
        }else{
            list= guestRepository.findByName(name);
        }
        model.addAttribute("list", list);
        return new ModelAndView ("index");
    }

    @GetMapping("/create")
    public ModelAndView create(Guest guest){
        return new ModelAndView ("create");
    }

    @PostMapping("/create")
    public ModelAndView insert(Guest guest){
        guestRepository.save(guest);
        return new ModelAndView ("redirect:/");
    }

    @GetMapping("/update/{id}")
    public ModelAndView edit(Model model,@PathVariable("id") Integer id){
        Optional<Guest> guestBooks = guestRepository.findById(id);
        if(guestBooks.isPresent()){
            model.addAttribute("guest",guestBooks.get());
            return new ModelAndView ("update");
        }
        return new ModelAndView ("redirect:/");

    }

    @PostMapping("/update/{id}")
    public ModelAndView update(@PathVariable("id") Integer id, Guest guest){
        guestRepository.save(guest);
        return new ModelAndView ("redirect:/");
    }

    @GetMapping("/delete/{id}")
    public ModelAndView delete(@PathVariable("id") Integer id){
        guestRepository.deleteById(id);
        return new ModelAndView ("redirect:/");
    }
}

Buat file html pada folder resources/templates

file index.html adalah halaman utama web saat aplikasi dijalankan

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Guest Books</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <link rel="stylesheet" type="text/css" th:href="@{/css/bootstrap.min.css}" />
</head>
<body>
<div class="container" style="margin-top:30px;">
    <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3">
        <h2>Guest Books</h2>
        <div class="btn-toolbar mb-5 mb-md-0">
            <div class="btn-group mr-2">
                <input type="text" placeholder="Input name" name="name" id="name" onsubmit="name"
                       class="form-control input-sm form-control-sm"/>
                <button class="btn btn-sm btn-secondary" onclick="onSearch()">Cari</button>
            </div>
            <a class="btn btn-sm btn-secondary" href="/create">
                Tambah Data
            </a>
        </div>
    </div>
    <div class="table-responsive">
        <table class="table table-striped table-sm table-hover">
            <thead>
            <tr>
                <th>Guest ID</th>
                <th>Name</th>
                <th>Phone</th>
                <th style="text-align: center">#</th>
            </tr>
            </thead>
            <tbody>
            <tr th:each="data,iter : ${list}">
                <td th:text="${data.idGuest}"></td>
                <td th:text="${data.name}"></td>
                <td th:text="${data.phoneNumber}"></td>
                <td style="width: 100px;">
                    <a class="btn btn-sm btn-secondary" th:href="@{/update/{id}(id=${data.idGuest})}" style="padding: 3px;">Edit</a>
                    <a class="btn btn-sm btn-secondary" th:href="@{/delete/{id}(id=${data.idGuest})}" style="padding: 3px;">delete</a>
                </td>
            </tr>
            </tbody>
        </table>
    </div>
    <script>
    function onSearch() {
        var name = document.getElementById("name").value;
        if (name !="") {
            window.location = "/param?name="+name;
        } else {
            window.location = "/"
        }
    }
    </script>
</div>
</body>
</html>

Buat file create.html , ini adalah halaman untuk membuat data tamu / member baru

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Guest Books</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <link rel="stylesheet" type="text/css" th:href="@{/css/bootstrap.min.css}" />
</head>
<body>
<div class="container">
    <div class="row">
        <main role="main" class="col-md-9 ml-sm-auto col-lg-10 px-4">
            <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3">
                <h2>Guest Books</h2>
            </div>
            <div class="col-sm-8 col-md-8 col-lg-8 col-xs-12">
                <form action="#" th:action="@{/create}" th:object="${guest}" method="POST">
                    <div class="form-group row has-success">
                        <label class="control-label col-sm-3" for="name">Name</label>
                        <div class="col-sm-6">
                            <input class="form-control form-control-sm" type="text" th:field="*{name}" id="name"
                                   name="name" placeholder="Input name" required>
                        </div>
                    </div>
                    <div class="form-group row has-success">
                        <label class="control-label col-sm-3" for="phoneNumber">Phone</label>
                        <div class="col-sm-6">
                        <input class="form-control form-control-sm" type="text" th:field="*{phoneNumber}" id="phoneNumber"
                               name="name" placeholder="Input Phone Number" required>
                        </div>
                    </div>
                    <div class="">
                        <div class="col-sm-6" style="float: right;">
                            <a class="btn btn-sm btn-secondary" href="/">
                                Cancel
                            </a>
                            <input type="submit" class="btn btn-secondary btn-sm" value="Save"/>
                        </div>
                    </div>
                </form>
            </div>
        </main>
    </div>
</div>
</body>
</html>

Buat file update.html , ini adalah halaman untuk merubah data tamu / member

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Guest Books</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <link rel="stylesheet" type="text/css" th:href="@{/css/bootstrap.min.css}" />
</head>
<body>
<div class="container">
    <div class="row">
        <main role="main" class="col-md-9 ml-sm-auto col-lg-10 px-4">
            <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3">
                <h2>Guest Books</h2>
            </div>
            <div class="col-sm-8 col-md-8 col-lg-8 col-xs-12">
                <form action="#" th:action="@{/update/{id}(id=${guest.idGuest})}" th:object="${guest}" method="POST">
                    <div class="form-group row has-success">
                        <div class="col-sm-6">
                            <input class="form-control form-control-sm" th:field="*{idGuest}" type="text" id="idGuest"
                                   name="idGuest"  hidden style="background-color: transparent;border: gray solid 1px;">
                        </div>
                    </div>

                    <div class="form-group row has-success">
                        <label class="control-label col-sm-3" for="name">Name</label>
                        <div class="col-sm-6">
                            <input class="form-control form-control-sm" type="text" th:field="*{name}" id="name"
                                   name="name" placeholder="Input name" required>
                        </div>
                    </div>
                    <div class="form-group row has-success">
                        <label class="control-label col-sm-3" for="phoneNumber">Phone</label>
                        <div class="col-sm-6">
                        <input class="form-control form-control-sm" type="text" th:field="*{phoneNumber}" id="phoneNumber"
                               name="name" placeholder="Input Phone Number" required>
                        </div>
                    </div>
                    <div class="">
                        <div class="col-sm-6" style="float: right;">
                            <a class="btn btn-sm btn-secondary" href="/">
                                Cancel
                            </a>
                            <input type="submit" class="btn btn-secondary btn-sm" value="Update"/>
                        </div>
                    </div>
                </form>
            </div>
        </main>
    </div>
</div>
</body>
</html>

Pastikan semua dependencies yg aplikasi butuhkan pada file pom.xml sama seperti berikut :

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.4.0</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.alfazid</groupId>
	<artifactId>guestbooks</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>tes1</name>
	<description>Guest Books</description>

	<properties>
		<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>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</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>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

Setup database yang terdapat pada file resources/application.yml sesuikan database , username dan password sesuai dengan local mesin kalian

spring:
  datasource:
    driverClassName:
    url: jdbc:mysql://localhost:3306/guest_books?createDatabaseIfNotExist=true&useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Jakarta&useSSL=false
    username: root
    password: 
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: update
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL5Dialect
        format_sql: true

Untuk menjalankan aplikasi gunakan perintah

- mvn clean install
- mvn spring-boot:run

jika aplikasi tidak terjadi kesalahan saat running maka tampilan aplikasi yang kita buat superti berikut:

Halaman utama

Halaman tambah data

Halaman ubah data

The project source code can be downloaded on the GitHub  guest-books

hyvercode

Leave a Reply

Your email address will not be published. Required fields are marked *