1. Backend (Spring Boot)
1.1. Struktur Proyek
1.2. pom.xml
<?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>3.1.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.joko</groupId>
<artifactId>Springboot-crud-angular16-mysql</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Springboot-crud-angular16-mysql</name>
<description>Springboot-crud-angular16-mysql</description>
<properties>
<java.version>17</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-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</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>
1.3. Model (DanamonEmployee.java)
package com.joko.model;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
@Entity
@Table(name="employees")
public class DanamonEmployee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotBlank
@Size(max = 120)
@Column(name = "name")
private String name;
@NotBlank
@Size(max = 200)
@Column(name = "address")
private String address;
@NotBlank
@Size(max = 200)
@Column(name = "salary")
private String salary;
@NotBlank
@Size(max = 120)
@Column(name = "job")
private String job;
public DanamonEmployee () {}
public DanamonEmployee(@NotBlank @Size(max = 120) String name, @NotBlank @Size(max = 200) String address,
@NotBlank @Size(max = 200) String salary,@NotBlank @Size(max = 120) String job) {
super();
this.name = name;
this.address = address;
this.salary = salary;
this.job = job;
}
@Override
public String toString() {
return "DanamonEmployee [id=" + id + ", name=" + name + ", address=" + address + ", salary=" + salary
+ ", job="+job+", getId()=" + getId() + ", getName()=" + getName() + ", getAddress()=" + getAddress()
+ ", getSalary()=" + getSalary() +", getJob()="+getJob()+ ", toString()=" + super.toString() + "]";
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getSalary() {
return salary;
}
public void setSalary(String salary) {
this.salary = salary;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
}
1.4. Repository (DanamonEmployeeRepository.java)
1.5. Controller (DanamonEmployeeController.java)
package com.joko.controller;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
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.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import com.joko.model.DanamonEmployee;
import com.joko.repository.DanamonEmployeeRepository;
@RestController
@RequestMapping("/bdi/api")
public class DanamonEmployeeController {
@Autowired
DanamonEmployeeRepository danamonEmployeeRepository;
private static final Logger logger =LoggerFactory.getLogger(DanamonEmployeeController.class);
@GetMapping("/employee")
public ResponseEntity<List<DanamonEmployee>> getAllDanamonEmployee(@RequestParam(required = false) String name) {
try {
List<DanamonEmployee> danamonEmployees = new ArrayList<DanamonEmployee>();
if (name == null)
danamonEmployeeRepository.findAll().forEach(danamonEmployees::add);
else
danamonEmployeeRepository.findByNameContaining(name).forEach(danamonEmployees::add);
if (danamonEmployees.isEmpty()) {
logger.info(" Get All employee No Content");
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
logger.info(" Get All employee succcess");
return new ResponseEntity<>(danamonEmployees, HttpStatus.OK);
} catch (Exception e) {
// TODO: handle exception
logger.error("INTERNAL_SERVER_ERROR Failure Get All employee ",e);
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@GetMapping("/employee/{id}")
public ResponseEntity<DanamonEmployee> getDanamonEmployeeById(@PathVariable("id") long id) {
Optional<DanamonEmployee> danamonEmployees = danamonEmployeeRepository.findById(id);
if (danamonEmployees.isPresent()) {
logger.info(" Get employee by Id success");
return new ResponseEntity<>(danamonEmployees.get(), HttpStatus.OK);
} else {
logger.error(" Not Found Fail to Get employee by id");
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
@PostMapping("/employee")
public ResponseEntity<DanamonEmployee> createDanamonEmployee(@RequestBody DanamonEmployee danamonEmployee) {
try {
DanamonEmployee danamonemployee = danamonEmployeeRepository.save(new DanamonEmployee(danamonEmployee.getName(), danamonEmployee.getAddress(),danamonEmployee.getSalary(),danamonEmployee.getJob()));
logger.info(" Successfully added new employee: ID={}, Name={}, Address={}, Salary={}, Job={}",
danamonemployee.getId(),
danamonemployee.getName(),
danamonemployee.getAddress(),
danamonemployee.getSalary(),
danamonemployee.getJob()
);
return new ResponseEntity<>(danamonemployee, HttpStatus.CREATED);
} catch (Exception e) {
logger.error(" INTERNAL_SERVER_ERROR Fail adding new employee",e);
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@PutMapping("/employee/{id}")
public ResponseEntity<DanamonEmployee> updateDanamonEmployee(@PathVariable("id") long id, @RequestBody DanamonEmployee danamonEmployee) {
Optional<DanamonEmployee> employeedata = danamonEmployeeRepository.findById(id);
if (employeedata.isPresent()) {
DanamonEmployee emp = employeedata.get();
emp.setName(danamonEmployee.getName());
emp.setAddress(danamonEmployee.getAddress());
emp.setSalary(danamonEmployee.getSalary());
emp.setJob(danamonEmployee.getJob());
logger.info(" You have been success updating employee by id");
return new ResponseEntity<>(danamonEmployeeRepository.save(emp), HttpStatus.OK);
} else {
logger.error(" NOT_FOUND Fail updating employee by id");
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
@DeleteMapping("/employee/{id}")
public ResponseEntity<HttpStatus> deleteDanamonEmployee(@PathVariable("id") long id) {
try {
danamonEmployeeRepository.deleteById(id);
logger.info(" You have been success deleting employee by id");
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
} catch (Exception e) {
logger.error(" INTERNAL_SERVER_ERROR, error delete employee by id",e);
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@DeleteMapping("/employee")
public ResponseEntity<HttpStatus> deleteAllDanamonEmployee() {
try {
danamonEmployeeRepository.deleteAll();
logger.info(" You have been success deleting all employee");
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
} catch (Exception e) {
logger.error(" INTERNAL_SERVER_ERROR, error delete All employee ",e);
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
@RestControllerAdvice
class GlobalExceptionHandler{
private static final Logger logger =LoggerFactory.getLogger(GlobalExceptionHandler.class);
public ResponseEntity<String> handleRunTimeException(RuntimeException e){
logger.error("Exception Occur:{}",e.getMessage());
return ResponseEntity.badRequest().body(e.getMessage());
}
}
1.6. SpringbootCrudAngular16MysqlApplication.java
package com.joko;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringbootCrudAngular16MysqlApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootCrudAngular16MysqlApplication.class, args);
}
}
1.6. Konfigurasi Database (application.properties)
server.port=8087
spring.datasource.url= jdbc:mysql://localhost:3306/testdb?useSSL=false
spring.datasource.username= root
spring.datasource.password= root
spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQL8Dialect
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto= update
spring.jpa.properties.hibernate.globally_quoted_identifiers=true
2. Frontend (Angular 16)
2.1. Install Angular CLI dan Buat Proyek
2.9. Routing di Angular
Tambahkan route untuk komponen Employee List dan Employee Form di app-routing.module.ts
app.component.html
3. Jalankan Aplikasi
3.1. Jalankan Backend (Spring Boot)
Pastikan MySQL berjalan, lalu jalankan backend dengan:
Atau menggunakan IntelliJ IDEA atau Eclipse, jalankan DanamonBackendApplication
.
3.2. Jalankan Frontend (Angular)
http://localhost:4200/
.4. Hasil Akhir
- Halaman utama akan menampilkan daftar karyawan.
- Halaman "Add Employee" akan memungkinkan pengguna untuk menambahkan karyawan baru.
- Tombol "Delete" akan menghapus karyawan dari database.
5. Kesimpulan
✅ Spring Boot + JPA + MySQL menangani backend API untuk CRUD karyawan.
✅ Angular 16 digunakan untuk frontend, memungkinkan user melihat dan mengelola data karyawan.
✅ Bootstrap dan Angular Material membantu dalam styling UI agar lebih rapi.
No comments:
Post a Comment