-
Notifications
You must be signed in to change notification settings - Fork 26
Angular 6 Spring Boot 2 Spring Data JPA MySQL CRUD Tutorial
In this tutorial, we will learn how to develop a single page application(SPA) using Angular 6 at a front-end and Spring boot restful API at the backend.
Basically, we will create two projects:
-
springboot2-jpa-crud-example: This project is used to develop CRUD RESTFul APIs for a Simple Employee Management System using Spring Boot 2, JPA and MySQL as a database.
-
angular6-springboot-client: This project is used to develop single page application using Angular 6 as front-end technology. This angular 6 application consumes CRUD Restful APIs developed and exposed by a springboot2-jpa-crud-example project.
diagram here - list of employees
Let me list out tools and technologies used to develop these two applications.
- Spring Boot - 2.0.4.RELEASE
- JDK - 1.8 or later
- Spring Framework - 5.0.8 RELEASE
- Hibernate - 5.2.17.Final
- Spring Data JPA - 2+
- Angular 6
- Bootstrap 4
- npm- 6.4.1
- JQuery
- Maven - 3.2+
- IDE - Eclipse or Spring Tool Suite (STS)
- Visual Studio 2017
- Angular CLI
Let's first develop a CRUD RESTFul APIs for a Simple Employee Management System using Spring Boot 2 JPA and MySQL. Following are five REST APIs (Controller handler methods) are created for Employee resource. We will be exposing these rest APIs to Angular 6 Client.
diagram here
reuse http://www.javaguides.net/2018/09/spring-boot-2-jpa-mysql-crud-example.html article here
You can also clone source code of spring-boot2-jpa-crud-example project from my GitHub repository at https://github.com/RameshMF/spring-boot2-jpa-crud-example
Let's develop a step by step Angular 6 SPA(single page application) to consume above CRUD rest APIs.
I am assuming that you have basic knowledge of using Angular 6 and Angular CLI.
The Angular CLI is a command-line interface tool that you use to initialize, develop, scaffold, and maintain Angular applications. You can use the tool directly in a command shell, or indirectly through an interactive UI such as Angular Console.
If you are new to Angular CLI then check out official documentation at https://cli.angular.io.
You can install angular by typing the following command in your terminal -
$ npm install -g @angular/cli
Once installed, let's use below command to generate Angular 6 client application. We name this project as "angular6-springboot-client".
ng new angular6-springboot-client
Let's list out what are components, service and modules we are going to create in this application. We will use Angular CLI to generate components, services because Angular CLI follows best practices and saves much of time.
- Components
- create-employee
- employee-list
- employee-details
- Services
- employee.service.ts - Service for Http Client methods
- Modules
- FormsModule
- HttpClientModule
- AppRoutingModule.
- Employee Class (Typescript class)
- employee.ts: class Employee (id, firstName, lastName, emailId)
In this next step, we will generate these components,classes and services using Angular CLI.
Let's auto generate service and components. Change you project directory to angular6-springboot-client\src\app and run following commands:
- ng g s employee
– ng g c create-employee
– ng g c employee-details
– ng g c employee-list
Here is complete command and output for your reference:
C:\angular6\angular6-springboot-client\src\app>ng g s employee
CREATE src/app/employee.service.spec.ts (343 bytes)
CREATE src/app/employee.service.ts (137 bytes)
C:\angular6\angular6-springboot-client\src\app>ng g c create-employee
CREATE src/app/create-employee/create-employee.component.html (34 bytes)
CREATE src/app/create-employee/create-employee.component.spec.ts (685 bytes)
CREATE src/app/create-employee/create-employee.component.ts (304 bytes)
CREATE src/app/create-employee/create-employee.component.css (0 bytes)
UPDATE src/app/app.module.ts (509 bytes)
C:\angular6\angular6-springboot-client\src\app>ng g c employee-details
CREATE src/app/employee-details/employee-details.component.html (35 bytes)
CREATE src/app/employee-details/employee-details.component.spec.ts (692 bytes)
CREATE src/app/employee-details/employee-details.component.ts (308 bytes)
CREATE src/app/employee-details/employee-details.component.css (0 bytes)
UPDATE src/app/app.module.ts (629 bytes)
C:\angular6\angular6-springboot-client\src\app>ng g c employee-list
CREATE src/app/employee-list/employee-list.component.html (32 bytes)
CREATE src/app/employee-list/employee-list.component.spec.ts (671 bytes)
CREATE src/app/employee-list/employee-list.component.ts (296 bytes)
CREATE src/app/employee-list/employee-list.component.css (0 bytes)
UPDATE src/app/app.module.ts (737 bytes)
We will using bootstrap 4 for styling our application so let's integrate bootstrap 4 with angular 6.
Use NPM to download Bootstrap & JQuery. Bootstrap and jQuery will be installed into the node_modules folder.
npm install bootstrap jquery --save
Configure installed Bootstrap & JQuery in angular.json file:
...
"styles": [
"src/styles.css",
"node_modules/bootstrap/dist/css/bootstrap.min.css"
],
"scripts": [
"node_modules/jquery/dist/jquery.min.js",
"node_modules/bootstrap/dist/js/bootstrap.min.js"
]
...
Let's discuss each of the above generate components and service files and we will customize it as per our requirement.
Before defining the EmployeeListComponent, let’s define a Employee class for working with employees. create a new file employee.ts inside src/app folder and add the following code to it -
export class Employee {
id: number;
firstName: string;
lastName: string;
emailId: string;
active: boolean;
}
The EmployeeService will be used to get the data from backend by calling spring boot apis. Update the employee.service.ts file inside src/app directory with following code to it -
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class EmployeeService {
private baseUrl = '/api/v1/employees';
constructor(private http: HttpClient) { }
getEmployee(id: number): Observable<Object> {
return this.http.get(`${this.baseUrl}/${id}`);
}
createEmployee(employee: Object): Observable<Object> {
return this.http.post(`${this.baseUrl}`, employee);
}
updateEmployee(id: number, value: any): Observable<Object> {
return this.http.put(`${this.baseUrl}/${id}`, value);
}
deleteEmployee(id: number): Observable<any> {
return this.http.delete(`${this.baseUrl}/${id}`, { responseType: 'text' });
}
getEmployeesList(): Observable<any> {
return this.http.get(`${this.baseUrl}`);
}
}Let's update EmployeeListComponent component which will be used to display a list of employee, create a new employee, and delete employee.
Update/remove content of todo-list.component.ts inside src/app directory and add the following code to it -
import { Observable } from "rxjs";
import { EmployeeService } from "./../employee.service";
import { Employee } from "./../employee";
import { Component, OnInit } from "@angular/core";
@Component({
selector: "app-employee-list",
templateUrl: "./employee-list.component.html",
styleUrls: ["./employee-list.component.css"]
})
export class EmployeeListComponent implements OnInit {
employees: Observable<Employee[]>;
constructor(private employeeService: EmployeeService) {}
ngOnInit() {
this.reloadData();
}
reloadData() {
this.employees = this.employeeService.getEmployeesList();
}
deleteEmployee(id: number) {
this.employeeService.deleteEmployee(id)
.subscribe(
data => {
console.log(data);
this.reloadData();
},
error => console.log(error));
}
}Update employee-list.component.html file with following code to it -
<div class="panel panel-default">
<div class="panel-heading">
<h1>Employees</h1>
</div>
<div class="panel-body">
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let employee of employees | async">
<td>{{employee.firstName}}</td>
<td>{{employee.lastName}}</td>
<td>{{employee.emailId}}</td>
<td><button (click)="deleteEmployee(employee.id)">Delete</button></td>
</tr>
</tbody>
</table>
</div>
</div>CreateEmployeeComponent is used create and handle a new employee form data. Add the following code to it -
import { EmployeeService } from './../employee.service';
import { Employee } from './../employee';
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-create-employee',
templateUrl: './create-employee.component.html',
styleUrls: ['./create-employee.component.css']
})
export class CreateEmployeeComponent implements OnInit {
employee: Employee = new Employee();
submitted = false;
constructor(private employeeService: EmployeeService) { }
ngOnInit() {
}
newEmployee(): void {
this.submitted = false;
this.employee = new Employee();
}
save() {
this.employeeService.createEmployee(this.employee)
.subscribe(data => console.log(data), error => console.log(error));
this.employee = new Employee();
}
onSubmit() {
this.submitted = true;
this.save();
}
}<h3>Create Employee</h3>
<div [hidden]="submitted" style="width: 400px;">
<form (ngSubmit)="onSubmit()">
<div class="form-group">
<label for="name">First Name</label>
<input type="text" class="form-control" id="firstName" required [(ngModel)]="employee.firstName" name="firstName">
</div>
<div class="form-group">
<label for="name">Last Name</label>
<input type="text" class="form-control" id="lastName" required [(ngModel)]="employee.lastName" name="lastName">
</div>
<div class="form-group">
<label for="name">First Name</label>
<input type="text" class="form-control" id="emailId" required [(ngModel)]="employee.emailId" name="emailId">
</div>
<button type="submit" class="btn btn-success">Submit</button>
</form>
</div>
<div [hidden]="!submitted">
<h4>You submitted successfully!</h4>
</div>