0% found this document useful (0 votes)
66 views

07 Spring Boot 3 Spring MVC Crud

The document discusses creating a web UI for an employee directory using Thymeleaf and Spring Boot. It will involve reusing code from a previous project to build out the application architecture including an EmployeeController, EmployeeService, EmployeeRepository and Employee entity. The development process will involve getting a list of employees, adding a new employee, updating an existing employee, and deleting an employee. Specific steps outlined include adding a button to link to a form for adding a new employee, creating an HTML form bound to a model attribute to collect employee details, and processing the form submission.

Uploaded by

hughston.musashi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
66 views

07 Spring Boot 3 Spring MVC Crud

The document discusses creating a web UI for an employee directory using Thymeleaf and Spring Boot. It will involve reusing code from a previous project to build out the application architecture including an EmployeeController, EmployeeService, EmployeeRepository and Employee entity. The development process will involve getting a list of employees, adding a new employee, updating an existing employee, and deleting an employee. Specific steps outlined include adding a button to link to a form for adding a new employee, creating an HTML form bound to a model attribute to collect employee details, and processing the form submission.

Uploaded by

hughston.musashi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 46

Thymeleaf CRUD - Real Time Project

© luv2code LLC
Application Requirements
From the Boss

Create a Web UI for the Employee Directory

Users should be able to


• Get a list of employees Thymeleaf + Spring Boo
t
• Add a new employee
• Update an employee
• Delete an employee

www.luv2code.com © luv2code LLC


Real-Time Project Thymeleaf + Spring Boo
t

www.luv2code.com © luv2code LLC


Big Picture

1 2 3 4
Employe Employe Employe

Controller Service Repository

Web
Browser
Thymeleaf Templates

www.luv2code.com © luv2code LLC


Application Architecture Reuse code from

previous project

Employee Employe Employe

Controller Service Repository

New code that we will create

www.luv2code.com © luv2code LLC


Project Set Up
• We will extend our existing Employee project and add DB integration

• Add EmployeeService, EmployeeRepository and Employee entit

• Available in one of our previous project

• We created all of this code already from scratch … so we'll just copy/paste it

• Allows us to focus on creating EmployeeController and Thymeleaf


templates

www.luv2code.com © luv2code LLC


Development Process - Big Picture Step-
By-S
tep

1. Get list of employee

2. Add a new employe

3. Update an existing employe

4. Delete an existing employee

www.luv2code.com © luv2code LLC


Thymeleaf - Add Employee

Date

© luv2code LLC
Add Employee - DEMO

www.luv2code.com © luv2code LLC


Add Employee Step-
By-S
tep
1. New Add Employee button for list-employees.html

www.luv2code.com © luv2code LLC


Add Employee Step-
By-S
tep
1. New Add Employee button for list-employees.html

2. Create HTML form for new employee

www.luv2code.com © luv2code LLC


Add Employee Step-
By-S
tep
1. New Add Employee button for list-employees.html

2. Create HTML form for new employee

3. Process form data to save employee

www.luv2code.com © luv2code LLC


Step 1: New "Add Employee" button
• Add Employee button will href link to

• request mapping /employees/showFormForAdd

<a th:href="@{/employees/showFormForAdd}">
Add Employee Add Employee
</a>
@ symbo

Reference context path of your application

(app root)

www.luv2code.com © luv2code LLC


Step 1: New "Add Employee" button
• Add Employee button will href link to

• request mapping /employees/showFormForAdd

<a th:href="@{/employees/showFormForAdd}"
<a th:href="@{/employees/showFormForAdd}">
class="btn btn-primary btn-sm mb-3">
Add Employee
Add Employee
</a>
</a>
Button
Apply Bootstrap styles Button Primary
Button Small
Docs on Bootstrap styles: www.getbootstrap.com Margin Bottom, 3 pixels

www.luv2code.com © luv2code LLC


Step 1: New "Add Employee" button
• Add Employee button will href link to

• request mapping /employees/showFormForAdd

<a th:href="@{/employees/showFormForAdd}"
class="btn btn-primary btn-sm mb-3">
Add Employee
</a>
TODO

Add controller request mapping for

/employees/showFormForAdd

www.luv2code.com © luv2code LLC


Showing Form
In your Spring Controller

• Before you show the form, you must add a model attribute

• This is an object that will hold form data for the data binding

www.luv2code.com © luv2code LLC


Controller code to show form
@Controller
@RequestMapping("/employees")
public class EmployeeController {

@GetMapping("/showFormForAdd") Our Thymleaf template will


public String showFormForAdd(Model theModel) { access this data for
binding form data
// create model attribute to bind form data
Employee theEmployee = new Employee();

theModel.addAttribute("employee", theEmployee);

return "employees/employee-form";
}

} src/main/resources/templates/employees/employee-form.html

www.luv2code.com © luv2code LLC


Thymeleaf and Spring MVC Data Binding
• Thymeleaf has special expressions for binding Spring MVC form data

• Automatically setting / retrieving data from a Java object

www.luv2code.com © luv2code LLC


Thymeleaf Expressions
• Thymeleaf expressions can help you build the HTML form :-)

Expression Description

th:action Location to send form data

th:object Reference to model attribute

th:field Bind input field to a property on model attribute

more …. See - www.luv2code.com/thymeleaf-create-form

www.luv2code.com © luv2code LLC


Step 2: Create HTML form for new employee
Empty place holder Real work
Thymeleaf will handle real work Send form data to
/employees/save

<form action="#" th:action="@{/employees/save}"


th:object="${employee}" method="POST">

</form>
Our model attribute

www.luv2code.com © luv2code LLC


Step 2: Create HTML form for new employee

www.luv2code.com © luv2code LLC


Step 2: Create HTML form for new employee
*{…}
Selects property on referenced
th:object
<form action="#" th:action="@{/employees/save}"
th:object="${employee}" method="POST">

<input type="text" th:field="*{firstName}" placeholder="First name">

<input type="text" th:field="*{lastName}" placeholder="Last name">

<input type="text" th:field="*{email}" placeholder="Email">

<button type="submit">Save</button>

</form>

www.luv2code.com © luv2code LLC


Step 2: Create HTML form for new employee
1
<form action="#" th:action="@{/employees/save}" When form is loaded,
th:object="${employee}" method="POST"> will call:

<input type="text" th:field="*{firstName}" placeholder="First name"> employee.getFirstName()

employee.getLastName
<input type="text" th:field="*{lastName}" placeholder="Last name">

<input type="text" th:field="*{email}" placeholder="Email">

2
<button type="submit">Save</button>
When form is submitted,
</form> will call:

employee.setFirstName(…)

employee.setLastName(…)

www.luv2code.com © luv2code LLC


Step 2: Create HTML form for new employee
<form action="#" th:action="@{/employees/save}"
th:object="${employee}" method="POST">

<input type="text" th:field="*{firstName}" placeholder="First name"


name">
class="form-control mb-4 w-25">

<input type="text" th:field="*{lastName}" placeholder="Last name">

Form control
<input type="text" th:field="*{email}" placeholder="Email">
Apply Bootstrap styles Margin Bottom: 4 pixels
Width: 25%
<button type="submit">Save</button>

</form>
</form>

www.luv2code.com © luv2code LLC


Step 2: Create HTML form for new employee
<form action="#" th:action="@{/employees/save}"
th:object="${employee}" method="POST">

<input type="text" th:field="*{firstName}" placeholder="First name" Button


class="form-control mb-4 w-25"> Button Info
Column Span 2
<input type="text" th:field="*{lastName}" placeholder="Last name"
class="form-control mb-4 w-25">

<input type="text" th:field="*{email}" placeholder="Email"


class="form-control mb-4 w-25">

<button type="submit" class="btn btn-info col-2">Save</button>

</form>

Apply Bootstrap styles

www.luv2code.com © luv2code LLC


Step 2: Create HTML form for new employee
TODO

<form action="#" th:action="@{/employees/save}" Add controller request mapping for

th:object="${employee}" method="POST"> /employees/save

<input type="text" th:field="*{firstName}" placeholder="First name"


class="form-control mb-4 w-25">

<input type="text" th:field="*{lastName}" placeholder="Last name"


class="form-control mb-4 w-25">

<input type="text" th:field="*{email}" placeholder="Email"


class="form-control mb-4 w-25">

<button type="submit" class="btn btn-info col-2">Save</button>

</form>

www.luv2code.com © luv2code LLC


Step 3: Process form data to save employee
@Controller
Since only one constructor
@Autowired is optional
@RequestMapping("/employees")
public class EmployeeController {

private EmployeeService employeeService;

public EmployeeController(EmployeeService theEmployeeService) {


employeeService = theEmployeeService;
}

@PostMapping("/save") Constructor injection


public String saveEmployee(@ModelAttribute("employee") Employee theEmployee) {

// save the employee


employeeService.save(theEmployee);

// use a redirect to prevent duplicate submissions


return "redirect:/employees/list";
}

}

www.luv2code.com © luv2code LLC


Step 3: Process form data to save employee
@Controller
@RequestMapping("/employees")
public class EmployeeController {

private EmployeeService employeeService;

public EmployeeController(EmployeeService theEmployeeService) {


employeeService = theEmployeeService;
}

@PostMapping("/save")
public String saveEmployee(@ModelAttribute("employee") Employee theEmployee) {

// save the employee


employeeService.save(theEmployee);

// use a redirect to prevent duplicate submissions


return "redirect:/employees/list";
}

}

www.luv2code.com © luv2code LLC


Step 3: Process form data to save employee
@Controller
@RequestMapping("/employees")
public class EmployeeController {

private EmployeeService employeeService;

public EmployeeController(EmployeeService theEmployeeService) {


employeeService = theEmployeeService;
}

@PostMapping("/save")
public String saveEmployee(@ModelAttribute("employee") Employee theEmployee) {

// save the employee


employeeService.save(theEmployee);

// use a redirect to prevent duplicate submissions "Post/Redirect/Get" pattern


return "redirect:/employees/list";
}

}

For more info see
Redirect to request mapping www.luv2code.com/post-redirect-get
/employees/list

www.luv2code.com © luv2code LLC


Thymeleaf - Update Employee

Date

© luv2code LLC
Update Employee - Demo

www.luv2code.com © luv2code LLC


Update Employee Step-
By-S
tep
1. "Update" button

2. Pre-populate the form

3. Process form data

www.luv2code.com © luv2code LLC


Step 1: "Update" Button
Each row has an Update link

- current employee id embedded in link

When clicked

- will load the employee from database


- prepopulate the form

www.luv2code.com © luv2code LLC


Step 1: "Update" button
• Update button includes employee id

<tr th:each="tempEmployee : ${employees}">



<td>

<a th:href="@{/employees/showFormForUpdate(employeeId=${tempEmployee.id})}"
class="btn btn-info btn-sm">
Update
</a>
Appends to URL
</td>
?employeeId=xxx
</tr>

www.luv2code.com © luv2code LLC


Step 2: Pre-populate Form
@Controller
@RequestMapping("/employees")
public class EmployeeController {

@GetMapping("/showFormForUpdate")
public String showFormForUpdate(@RequestParam("employeeId") int theId,
Model theModel) {

// get the employee from the service


Employee theEmployee = employeeService.findById(theId);

// set employee as a model attribute to pre-populate the form


theModel.addAttribute("employee", theEmployee);

// send over to our form


return "employees/employee-form";
}

www.luv2code.com © luv2code LLC


Step 2: Pre-populate Form 1
When form is loaded,
will call:

employee.getFirstName()
<form action="#" th:action="@{/employees/save}"
th:object="${employee}" method="POST">

employee.getLastName
<!-- Add hidden form field to handle update -->
<input type="hidden" th:field="*{id}" />

<input type="text" th:field="*{firstName}"


class="form-control mb-4 w-25" placeholder="First name"> This is how form is
pre-populated
<input type="text" th:field="*{lastName}" Thanks to calls to getters
class="form-control mb-4 w-25" placeholder="Last name">

<input type="text" th:field="*{email}"


class="form-control mb-4 w-25" placeholder="Email">

<button type="submit" class="btn btn-info col-2">Save</button>

</form>

www.luv2code.com © luv2code LLC


Step 2: Pre-populate Form

<form action="#" th:action="@{/employees/save}"


th:object="${employee}" method="POST">

<!-- Add hidden form field to handle update -->


Hidden form field
<input type="hidden" th:field="*{id}" /> required for updates
<input type="text" th:field="*{firstName}"
class="form-control mb-4 w-25" placeholder="First name">

<input type="text" th:field="*{lastName}"


class="form-control mb-4 w-25" placeholder="Last name">

<input type="text" th:field="*{email}"


class="form-control mb-4 w-25" placeholder="Email">

<button type="submit" class="btn btn-info col-2">Save</button>

</form>

www.luv2code.com © luv2code LLC


Step 2: Pre-populate Form

<form action="#" th:action="@{/employees/save}"


th:object="${employee}" method="POST">

<!-- Add hidden form field to handle update -->


<input type="hidden" th:field="*{id}" />

<input type="text" th:field="*{firstName}"


class="form-control mb-4 w-25" placeholder="First name">

<input type="text" th:field="*{lastName}"


class="form-control mb-4 w-25" placeholder="Last name">

<input type="text" th:field="*{email}"


class="form-control mb-4 w-25" placeholder="Email">

<button type="submit" class="btn btn-info col-2">Save</button>

</form>

www.luv2code.com © luv2code LLC


Step 2: Pre-populate Form

<form action="#" th:action="@{/employees/save}"


th:object="${employee}" method="POST">

<!-- Add hidden form field to handle update -->


<input type="hidden" th:field="*{id}" />

<input type="text" th:field="*{firstName}"


class="form-control mb-4 w-25" placeholder="First name">

<input type="text" th:field="*{lastName}"


class="form-control mb-4 w-25" placeholder="Last name">

<input type="text" th:field="*{email}" This binds to the model attribute


class="form-control mb-4 w-25" placeholder="Email">

Tells your app


<button type="submit" class="btn btn-info col-2">Save</button>

</form> which employee to update

www.luv2code.com © luv2code LLC


Step 3: Process form data to save employee
• No need for new code … we can reuse our existing cod

• Works the same for add or update :-)

@Controller
@RequestMapping("/employees")
public class EmployeeController {

@PostMapping("/save")
public String saveEmployee(@ModelAttribute("employee") Employee theEmployee) {

// save the employee


employeeService.save(theEmployee);

// use a redirect to prevent duplicate submissions


return "redirect:/employees/list";
}

}

www.luv2code.com © luv2code LLC


Thymeleaf - Delete Employee

Date

© luv2code LLC
Delete Employee - DEMO

www.luv2code.com © luv2code LLC


Delete Employee Step-
By-S
tep
1. Add “Delete” button/link on page

2. Add controller code for “Delete”

www.luv2code.com © luv2code LLC


Step 1: "Delete" button
Each row has a Delete button/link

- current employee id embedded in link

When clicked

- prompt user
- will delete the employee from database

www.luv2code.com © luv2code LLC


Step 1: "Delete" button
• Delete button includes employee id

Appends to URL
<tr th:each="tempEmployee : ${employees}">

?employeeId=xxx
<td>

<a th:href="@{/employees/delete(employeeId=${tempEmployee.id})}"
class="btn btn-danger btn-sm"
onclick="if (!(confirm('Are you sure you want to delete this employee?'))) return false">
Delete
</a>

</td>

</tr>
JavaScript to prompt user before deleting

www.luv2code.com © luv2code LLC


Step 2: Add controller code for delete
@Controller
@RequestMapping("/employees")
public class EmployeeController {

@GetMapping("/delete")
public String delete(@RequestParam("employeeId") int theId) {

// delete the employee


employeeService.deleteById(theId);

// redirect to /employees/list
return "redirect:/employees/list";
}

}

www.luv2code.com © luv2code LLC

You might also like