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

Spring Boot

The document outlines the Layered Architecture pattern in Spring Boot, detailing the roles and interactions of various layers: Presentation (UI), Controller (handles requests), Service (business logic), Repository (data access), and Entity (database models). It explains how these layers work together to process user requests and manage data, emphasizing the importance of separation of concerns for maintainability and scalability. Additionally, it lists common dependencies used in Spring Boot applications and provides a beginner-friendly explanation of core components.

Uploaded by

suresh709210
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views

Spring Boot

The document outlines the Layered Architecture pattern in Spring Boot, detailing the roles and interactions of various layers: Presentation (UI), Controller (handles requests), Service (business logic), Repository (data access), and Entity (database models). It explains how these layers work together to process user requests and manage data, emphasizing the importance of separation of concerns for maintainability and scalability. Additionally, it lists common dependencies used in Spring Boot applications and provides a beginner-friendly explanation of core components.

Uploaded by

suresh709210
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 68

The architecture you've described follows the Layered Architecture pattern in Spring Boot.

This is
a common design pattern that helps separate concerns and organize the code into logical
layers. Let me break down each layer of the architecture and explain its role:

1. Presentation Layer (Frontend): HTML Templates

 Role: This layer is responsible for presenting the user interface (UI) of the application. In your
case, the HTML templates are used to render views for the user.

 How it works:

o When the Spring Boot application starts, it serves these templates via the / or any
other URL endpoint.

o Thymeleaf or JSP can be used in Spring Boot to render the HTML pages.

o The user interacts with these pages through buttons, forms, etc., and those
interactions generate requests that are sent to the backend controllers.

 Example:

 <form action="/addEmployee" method="POST">

 <input type="text" name="firstName" placeholder="First Name">

 <button type="submit">Add Employee</button>

 </form>

2. Controller Layer: Handles HTTP Requests

 Role: The controller layer handles incoming HTTP requests and sends the appropriate
responses. This layer acts as the interface between the frontend (HTML templates) and the
backend (Service layer).
 How it works:

o The controller contains the endpoints (URLs) that map to specific methods in the
service layer. It listens for user actions like GET, POST, PUT, and DELETE requests.

o It processes the input (from the user, usually in the form of JSON or form data) and
returns a response, either by redirecting to another page, rendering a view, or
returning data (e.g., JSON).

o The controller typically does not contain business logic. Instead, it delegates the logic
to the service layer.

 Example:

 @RestController

 @RequestMapping("/api")

 public class EmployeeController {

 @PostMapping("/employees")

 public ResponseEntity<Employee> addEmployee(@RequestBody Employee employee){

 Employee newEmployee = employeeService.addEmployee(employee);

 return new ResponseEntity<>(newEmployee, HttpStatus.CREATED);

 }

 }

3. Service Layer: Business Logic

 Role: The service layer holds the business logic of the application. It performs operations like
validating input data, applying transformations, or interacting with the database.

 How it works:

o This layer is typically where the core functionality resides, such as adding an
employee, updating records, calculating salaries, etc.

o The service layer calls methods from the repository layer to interact with the
database (data layer).

o It is a good practice to use interfaces in the service layer to allow better separation
of concerns, easier testing, and flexibility.

 Example:

 @Service

 public class EmployeeService {

 private final EmployeeRepository employeeRepository;

 public EmployeeService(EmployeeRepository employeeRepository) {


 this.employeeRepository = employeeRepository;

 }

 public Employee addEmployee(Employee employee) {

 return employeeRepository.save(employee);

 }

 }

4. Repository Layer: Data Access Layer (DAO/DTO)

 Role: The repository layer interacts directly with the database. It is responsible for
performing CRUD (Create, Read, Update, Delete) operations.

 How it works:

o This layer abstracts the database interaction logic, using JPA repositories or Spring
Data JPA interfaces to define query methods that will interact with the database.

o The repository layer typically deals with entities (models that represent database
tables) and may return DTOs (Data Transfer Objects) for better performance or
structure.

o DAO (Data Access Object) is a pattern used to define operations to fetch data from
the database and return it to the service layer.

o DTO (Data Transfer Object) is an object that carries data between processes. It is
typically used to prevent exposing the entity directly to the client and to aggregate
data for better performance.

 Example:

 @Repository

 public interface EmployeeRepository extends JpaRepository<Employee, Long> {

 // Additional custom queries can be defined here

 }

5. Entity Layer: Database Models

 Role: The entity layer represents the data structure stored in the database. In a typical Spring
Boot JPA application, entities are mapped to database tables.

 How it works:

o This layer contains the classes annotated with @Entity that correspond to the
database tables.

o Each field in the entity represents a column in the corresponding table.

o Entities are used by the repository to store and retrieve data from the database.
 Example:

 @Entity

 public class Employee {

 @Id

 @GeneratedValue(strategy = GenerationType.IDENTITY)

 private Long id;

 private String firstName;

 private String lastName;

 private String email;

 // Getters and setters

 }

Summary of Spring Boot Layered Architecture:

1. Frontend (HTML Templates): Renders UI and sends requests to the backend via HTTP (e.g.,
using form submissions or Ajax).

2. Controller: Handles HTTP requests, delegates business logic to the service layer, and sends
appropriate responses to the frontend.

3. Service: Contains the business logic and calls the repository to interact with the database. It
may also perform validation and transformations.

4. Repository (DAO/DTO): Interacts with the database and performs CRUD operations on
entities.

5. Entity: Represents the database model, mapped to database tables.

Flow of Operations:

1. A user makes a request (e.g., submit a form) from the Frontend.

2. The request hits the Controller (e.g., @PostMapping("/employees")).

3. The Controller delegates the logic to the Service layer.

4. The Service layer interacts with the Repository to access or modify data in the Database.

5. The Repository performs CRUD operations on Entities (such as Employee) in the database.

6. The Controller sends a response back to the Frontend, which updates the UI.

By dividing the application into these layers, you ensure separation of concerns, making the
application easier to maintain and extend.
Common dependencies from [Spring Initializr](https://start.spring.io/) and their uses:

1. Spring Web

Use:

- Develop RESTful web services and web applications.

- Includes Spring MVC (Model-View-Controller).

- Handles HTTP requests, JSON responses, and web APIs.

- Provides an embedded Tomcat, Jetty, or Undertow server.

Typical Use Case:

- Building web applications and REST APIs.

- Handling GET, POST, PUT, DELETE requests.

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

---

2. Spring Data JPA

Use:

- Simplifies data access by using JPA (Java Persistence API).

- Reduces boilerplate code for database operations.

- Integrates seamlessly with Hibernate.

- Provides repository interfaces for CRUD operations.

Typical Use Case:

- Interacting with relational databases.

- Performing queries using repository methods.


xml

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-data-jpa</artifactId>

</dependency>

---

3. Spring Boot DevTools

Use:

- Provides development-time features to speed up coding.

- Automatic application restart upon code changes.

- Enables live reload in browsers.

- Improves developer productivity during the development phase.

Typical Use Case:

- Real-time reloading and testing during development.

- Faster iteration cycles without restarting the app manually.

xml

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-devtools</artifactId>

</dependency>

---

4. Lombok
Use:

- Reduces boilerplate code by auto-generating getters, setters, constructors, and `toString()`.

- Simplifies Java class creation.

- Improves code readability and maintainability.

Typical Use Case:

- Data transfer objects (DTOs), entity classes, and models.

Annotations:

- `@Getter`, `@Setter`, `@NoArgsConstructor`, `@AllArgsConstructor`, `@Builder`

xml

<dependency>

<groupId>org.projectlombok</groupId>

<artifactId>lombok</artifactId>

<optional>true</optional>

</dependency>

---

5. MySQL Driver

Use:

- Provides connectivity to MySQL databases.

- Required for database interaction with Spring Data JPA or JDBC.

Typical Use Case:

- Connecting Spring Boot applications to MySQL databases.

- Running SQL queries and performing database operations.

xml
<dependency>

<groupId>mysql</groupId>

<artifactId>mysql-connector-java</artifactId>

<scope>runtime</scope>

</dependency>

---

6. Thymeleaf

Use:

- A server-side template engine for rendering HTML.

- Supports dynamic content rendering in web applications.

- Replaces JSP (Java Server Pages).

- Integrates seamlessly with Spring MVC.

Typical Use Case:

- Rendering dynamic HTML pages.

- Creating forms, tables, and views in MVC applications.

xml

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-thymeleaf</artifactId>

</dependency>

---

7. Spring Security

Use:

- Adds security features like authentication, authorization, and CSRF protection.


- Supports OAuth2, JWT, and form-based logins.

xml

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-security</artifactId>

</dependency>

---

8. Spring Boot Starter Actuator

Use:

- Provides production-ready features like health checks, metrics, and monitoring.

xml

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-actuator</artifactId>

</dependency>

---

9. Spring Boot Starter Test

Use:

- Provides tools for unit and integration testing using JUnit, Mockito, and AssertJ.

xml

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<scope>test</scope>
</dependency>

---

10. Spring Boot Starter Validation

Use:

- Enables validation for request payloads and form data using annotations like `@Valid` and
`@NotNull`.

xml

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-validation</artifactId>

</dependency>

---

Here's a beginner-friendly explanation of Entity, Controller, Service, and Repository in Spring


Boot, along with how they are interconnected in a simple web application.

1. Understanding the Roles

These four components represent the core of the Spring MVC architecture. Together, they follow
the 3-layered architecture (Presentation, Service, and Data Access layers), which makes the
code organized and scalable.

1.1. Entity (Model Layer)

 Purpose: Represents a table in the database.

 Role: Models the data and maps it to a relational database using JPA (Java Persistence API).

 Annotation: @Entity

Example:

import jakarta.persistence.Entity;

import jakarta.persistence.Id;
@Entity

public class User {

@Id

private int id;

private String name;

private String email;

// Getters and Setters

 Explanation: This User class maps to a user table in the database.

 Real-World Example: A "User" entity represents a user in an app, with fields like ID, name,
and email.

1.2. Repository (Data Access Layer)

 Purpose: Interacts with the database.

 Role: Handles CRUD (Create, Read, Update, Delete) operations on entities.

 Annotation: @Repository (Extends JpaRepository or CrudRepository)

Example:

import org.springframework.data.jpa.repository.JpaRepository;

@Repository

public interface UserRepository extends JpaRepository<User, Integer> {

User findByEmail(String email);

 Explanation: UserRepository provides database operations like saving, finding by ID, or


querying by email.

 Real-World Example: Fetching a user from the database by their email.

1.3. Service (Business Logic Layer)

 Purpose: Contains the business logic of the application.

 Role: Calls the repository to fetch or save data and applies business rules.

 Annotation: @Service
Example:

import org.springframework.stereotype.Service;

import java.util.List;

@Service

public class UserService {

private final UserRepository userRepository;

public UserService(UserRepository userRepository) {

this.userRepository = userRepository;

public List<User> getAllUsers() {

return userRepository.findAll();

public User createUser(User user) {

return userRepository.save(user);

 Explanation: UserService calls UserRepository to retrieve/save users, applying any business


logic before persisting the data.

 Real-World Example: A rule like "don't allow duplicate emails" can be implemented in the
service.

1.4. Controller (Presentation Layer)

 Purpose: Handles incoming HTTP requests and returns responses.

 Role: Receives API calls, delegates tasks to the service layer, and returns the result.

 Annotation: @RestController or @Controller

Example:

import org.springframework.web.bind.annotation.*;
import java.util.List;

@RestController

@RequestMapping("/users")

public class UserController {

private final UserService userService;

public UserController(UserService userService) {

this.userService = userService;

@GetMapping

public List<User> getUsers() {

return userService.getAllUsers();

@PostMapping

public User addUser(@RequestBody User user) {

return userService.createUser(user);

 Explanation: UserController handles HTTP requests for getting and creating users by calling
UserService.

 Real-World Example: When a user submits a form, the controller processes the data and
returns the response.

2. How They Work Together (Flow)

1. Client Request:
A client (browser/postman) sends an HTTP request (e.g., GET /users).

2. Controller Layer:
The UserController handles the request and calls the UserService for logic.
3. Service Layer:
The UserService processes the request, applies business rules, and calls the UserRepository.

4. Repository Layer:
The UserRepository interacts with the database to fetch/save data.

5. Entity Layer:
The User entity represents the database row, and the result is returned to the service and
controller.

6. Response:
The response is sent back to the client.

3. Diagram Representation

Client (Browser/Postman)

| --> (1) HTTP Request (GET/POST)

Controller (UserController) ---> Service (UserService) ---> Repository (UserRepository) --->


Database (User Table)

| <-- (5) HTTP Response

4. Simple Example (Flow)


Request: GET /users

 Controller: Receives the request.

 Service: Calls the repository to fetch users.

 Repository: Retrieves users from the database.

 Entity: Represents the user data.

 Response: Returns a list of users in JSON format.

5. Why This Separation Matters?

 Separation of Concerns: Each layer handles a specific task, making code clean and organized.

 Scalability: Each layer can evolve independently.

 Maintainability: Easier to test and debug specific layers without affecting the entire app.

 Reusability: Services and repositories can be reused across different controllers.

6. How to Practice (Step-by-Step)

1. Set up a Spring Boot project using start.spring.io.

2. Add dependencies – Spring Web, Spring Data JPA, H2/MySQL Driver.

3. Create an Entity – Create a simple User entity.

4. Build a Repository – Implement a JPA repository.

5. Write a Service Layer – Create methods for fetching and saving data.

6. Add a Controller – Implement endpoints for getting and adding users.

7. Test with Postman or browser by making simple GET/POST requests.

1. @Component Annotation
2. @Autowired Annotation
3. @Qualifier Annotation
4. @Primary Annotation
5. @SpringBootApplication
6. @Bean and @Configuration Annotations
7. @Controller, @Service and @Repository
8. @Lazy Annotation
9. @Scope Annotation
10. @Value Annotation
11. @PropertySource and PropertySources Annotations
12. @ConfigurationProperties Annotation
13. @Controller and @ResponseBody Annotations
14. @RestController Annotation
15. @RequestMapping Annotation
16. @GetMapping Annotation
17. @PostMapping and @RequestBody Annotations
18. @PutMapping Annotation
19. @DeleteMapping Annotation
20. @PathVariable Annotation
21. @RequestParam Annotation
22. @EnableAutoConfiguration
23. @ComponentScan

Spring Framework uses annotations to simplify the configuration and management of beans, define
services, and handle HTTP requests. Here's a detailed explanation of each of the annotations you've
listed, along with how they interconnect:

1. @Component Annotation

 Purpose: Marks a class as a Spring bean. It's a generic stereotype annotation used for auto-
detecting and creating beans during component scanning.

 Example:

 @Component

 public class MyBean {

 // class definition

 }

 Connection: Any class annotated with @Component will be registered as a Spring bean and
can be injected using @Autowired.

2. @Autowired Annotation

 Purpose: Used to inject dependencies automatically into Spring beans. It can be applied to
constructors, fields, or methods.

 Example:

 @Autowired

 private MyBean myBean;

 Connection: Automatically injects a matching bean (e.g., @Component) into the dependent
class.

3. @Qualifier Annotation

 Purpose: Used with @Autowired to specify which bean to inject when multiple beans of the
same type exist.
 Example:

 @Autowired

 @Qualifier("myBean1")

 private MyBean myBean;

 Connection: Resolves ambiguity by explicitly specifying the bean name when there are
multiple candidates.

4. @Primary Annotation

 Purpose: Marks a bean as the default candidate for autowiring when there are multiple
beans of the same type.

 Example:

 @Primary

 @Bean

 public MyBean myPrimaryBean() {

 return new MyBean();

 }

 Connection: @Autowired will inject the bean marked with @Primary when no @Qualifier is
provided.

5. @SpringBootApplication

 Purpose: A convenience annotation for setting up a Spring Boot application. It's a


combination of @Configuration, @EnableAutoConfiguration, and @ComponentScan.

 Example:

 @SpringBootApplication

 public class MyApp {

 public static void main(String[] args) {

 SpringApplication.run(MyApp.class, args);

 }

 }

 Connection: Bootstraps the Spring context and enables component scanning, auto-
configuration, and application setup.

6. @Bean and @Configuration Annotations

 @Bean: Declares a method that will return a Spring bean.

 @Configuration: Marks a class as a configuration class that can contain bean definitions.

 Example:
 @Configuration

 public class MyConfig {

 @Bean

 public MyBean myBean() {

 return new MyBean();

 }

 }

 Connection: @Configuration is used to define beans via @Bean, and they can be injected
using @Autowired.

7. @Controller, @Service, and @Repository Annotations

 @Controller: Used for defining Spring MVC controllers.

 @Service: Used to define service classes, typically for business logic.

 @Repository: Used for DAO (Data Access Object) classes.

 Example:

 @Controller

 public class MyController {

 // controller methods

 }

 @Service

 public class MyService {

 // service methods

 }

 @Repository

 public class MyRepository {

 // repository methods

 }

 Connection: These annotations are specialized versions of @Component and help Spring
manage the roles of the classes.

8. @Lazy Annotation

 Purpose: Marks a bean to be lazily initialized, meaning it will only be created when it's first
needed.

 Example:
 @Lazy

 @Component

 public class MyLazyBean {

 // class definition

 }

 Connection: Ensures the bean is created only when required, improving startup time.

9. @Scope Annotation

 Purpose: Defines the scope of a Spring bean (e.g., singleton, prototype).

 Example:

 @Scope("prototype")

 @Component

 public class MyPrototypeBean {

 // class definition

 }

 Connection: Controls the lifecycle and visibility of beans within the Spring container.

10. @Value Annotation

 Purpose: Injects values from properties files or expressions into fields, methods, or
constructor parameters.

 Example:

 @Value("${my.property}")

 private String property;

 Connection: Useful for externalizing configuration and setting values dynamically.

11. @PropertySource and @PropertySources Annotations

 Purpose: Specifies the location of property files for Spring to load.

 Example:

 @PropertySource("classpath:application.properties")

 @Configuration

 public class MyConfig {

 // class definition

 }

 Connection: Allows Spring to load external properties files for dependency injection.
12. @ConfigurationProperties Annotation

 Purpose: Binds the properties from external files (e.g., application.properties) into a Java
class.

 Example:

 @ConfigurationProperties(prefix = "my")

 public class MyProperties {

 private String property;

 // getters and setters

 }

 Connection: Provides a structured way to bind configuration properties to a POJO.

13. @Controller and @ResponseBody Annotations

 @Controller: Marks a class as a controller in Spring MVC.

 @ResponseBody: Tells Spring to return the object as the response body (useful for RESTful
APIs).

 Example:

 @Controller

 public class MyController {

 @RequestMapping("/greeting")

 @ResponseBody

 public String greeting() {

 return "Hello, World!";

 }

 }

 Connection: Used for building web applications and REST APIs.

14. @RestController Annotation

 Purpose: A combination of @Controller and @ResponseBody, used for RESTful web services.

 Example:

 @RestController

 public class MyRestController {

 @GetMapping("/api")

 public String getApi() {

 return "Hello, API!";


 }

 }

 Connection: Simplifies the creation of RESTful web services.

15. @RequestMapping Annotation

 Purpose: Maps HTTP requests to handler methods of MVC and REST controllers.

 Example:

 @RequestMapping("/hello")

 public String hello() {

 return "Hello, World!";

 }

 Connection: Central to request routing in Spring MVC and REST APIs.

16. @GetMapping Annotation

 Purpose: A shorthand for @RequestMapping(method = RequestMethod.GET), used for


handling GET requests.

 Example:

 @GetMapping("/greet")

 public String greet() {

 return "Hello!";

 }

 Connection: Simplifies defining GET request handlers.

17. @PostMapping and @RequestBody Annotations

 @PostMapping: A shorthand for @RequestMapping(method = RequestMethod.POST), used


for handling POST requests.

 @RequestBody: Binds the request body to a method parameter.

 Example:

 @PostMapping("/submit")

 public String submit(@RequestBody MyData data) {

 return "Data received!";

 }

 Connection: Used for receiving and processing data in POST requests.

18. @PutMapping Annotation


 Purpose: A shorthand for @RequestMapping(method = RequestMethod.PUT), used for
handling PUT requests.

 Example:

 @PutMapping("/update")

 public String update() {

 return "Updated!";

 }

 Connection: Simplifies PUT request handling.

19. @DeleteMapping Annotation

 Purpose: A shorthand for @RequestMapping(method = RequestMethod.DELETE), used for


handling DELETE requests.

 Example:

 @DeleteMapping("/delete")

 public String delete() {

 return "Deleted!";

 }

 Connection: Simplifies DELETE request handling.

20. @PathVariable Annotation

 Purpose: Extracts values from the URI path.

 Example:

 @GetMapping("/user/{id}")

 public String getUser(@PathVariable String id) {

 return "User ID: " + id;

 }

 Connection: Used to access dynamic values from the URL path.

21. @RequestParam Annotation

 Purpose: Binds request parameters to method arguments.

 Example:

 @GetMapping("/search")

 public String search(@RequestParam String query) {

 return "Searching for: " + query;

 }
 Connection: Extracts query parameters from the URL.

22. @EnableAutoConfiguration

 Purpose: Tells Spring Boot to automatically configure the application based on the
dependencies in the classpath.

 Example: This is typically used by Spring Boot when running a standalone application.

 Connection: Helps Spring Boot automatically configure beans based on classpath


dependencies.

23. @ComponentScan

 Purpose: Tells Spring to scan the package for annotated classes (like @Component,
@Service, @Repository).

 Example:

 @ComponentScan("com.myapp")

 @Configuration

 public class MyConfig {

 // class definition

 }

 Connection: Automatically detects and registers beans in the Spring context.

How to Learn These Annotations:

 Start with the Basics: Begin by learning the most commonly used annotations like
@Component, @Autowired, @RequestMapping, and @Controller. These are foundational
and used across most Spring applications.

 Practice in Projects: Implement each annotation in small projects to see how they work
together.

 Understand Their Use Cases: Learn when to use each annotation based on its intended
purpose (e.g., @Controller for MVC, @Service for business logic).

 Reference Spring Documentation: Always refer to the Spring documentation for more in-
depth explanations and examples.

Spring API Project Using MYSQL & Postman:


To set up and connect your Spring Boot application to MySQL, follow these steps for configuring
MySQL and ensuring your application works correctly:

1. MySQL Setup

Step 1: Install MySQL


Ensure MySQL is installed and running on your machine.

Step 2: Create a Database


Log into MySQL and create a database:

CREATE DATABASE employeerepo;

Step 3: Create a User (Optional)

CREATE USER 'springuser'@'localhost' IDENTIFIED BY 'springpassword';

GRANT ALL PRIVILEGES ON employeerepo.* TO 'springuser'@'localhost';

FLUSH PRIVILEGES;

Alternatively, you can use the root user.

2. Application Configuration

In the application.properties file (you already have most of this), ensure the following properties are
correct:

server.port=8081

spring.datasource.url=jdbc:mysql://localhost:3306/employeerepo?
allowPublicKeyRetrieval=true&useSSL=false

spring.datasource.username=root

spring.datasource.password=root
spring.jpa.hibernate.ddl-auto=update

spring.jpa.show-sql=true

# Use the built-in Spring naming strategy

spring.jpa.hibernate.naming.implicit-
strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl

spring.jpa.hibernate.naming.physical-
strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

3. Breakdown of Properties

 spring.datasource.url – Connection URL to your MySQL database (employeerepo).

 spring.datasource.username – MySQL username (e.g., root).

 spring.datasource.password – MySQL password.

 spring.jpa.hibernate.ddl-auto – Automatically updates the schema. Options: update, create,


create-drop, none.

 spring.jpa.show-sql – Logs SQL queries in the console.

 spring.jpa.hibernate.naming – Controls table/column naming strategies.

4. Database Table

The Employee entity will automatically map to a table named employee_tbl in the database due to:

@Entity

@Table(name="employee_tbl")

If the table does not exist, Hibernate will create it based on the @Entity class.

5. Verify MySQL Connection

Run your application and check if the table is created:

SHOW TABLES;

The employee_tbl table should be listed.

6. Testing

Run the EmployeeIntegrationTests class. This will:

1. Start the Spring context.


2. Verify the EmployeeService is loaded.

3. Perform an integration test by querying for an employee.

7. Troubleshooting

 Database not found – Ensure the database employeerepo exists.

 Access denied – Check your root password or create a new MySQL user with the required
privileges.

 Table not created – Ensure spring.jpa.hibernate.ddl-auto=update is set. If needed, change it


to create for the first run.

EmployeeManagementApiApplication
EmployeeManagementApiApplication
package com.tsdotinc.employeemanagement.api;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication

public class EmployeeManagementApiApplication {

public static void main(String[] args) {

SpringApplication.run(EmployeeManagementApiApplication.class, args);

EmployeeController
package com.tsdotinc.employeemanagement.api.controller;

import com.tsdotinc.employeemanagement.api.model.Employee;

import com.tsdotinc.employeemanagement.api.service.EmployeeService;

import org.springframework.http.HttpStatus;

import org.springframework.http.ResponseEntity;

import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController

@RequestMapping("/api")

public class EmployeeController {


private final EmployeeService employeeService;

public EmployeeController(EmployeeService employeeService){

this.employeeService = employeeService;

@PostMapping("/employees")

public ResponseEntity<Employee> addEmployee(@RequestBody Employee employee){

Employee newEmployee = employeeService.addEmployee(employee);

return new ResponseEntity<>(newEmployee, HttpStatus.CREATED);

@GetMapping("/employees")

public ResponseEntity<List<Employee>> getAllEmployees(){

List<Employee> employees = employeeService.findAllEmployees();

return new ResponseEntity<>(employees, HttpStatus.OK);

@GetMapping("/employees/{id}")

public ResponseEntity<Employee> findEmployeeById(@PathVariable("id") Long id){

Employee employee = employeeService.findEmployeeById(id);

return new ResponseEntity<>(employee, HttpStatus.OK);

@PutMapping("/employees/{id}")

public ResponseEntity<Employee> updateEmployee(@PathVariable("id") Long id,

@RequestBody Employee employee){

employee.setId(id);

Employee updateEmployee = employeeService.updateEmployee(employee);

return new ResponseEntity<>(updateEmployee, HttpStatus.OK);

@DeleteMapping("/employees/{id}")
public ResponseEntity<?> deleteEmployee(@PathVariable("id") Long id){

employeeService.deleteEmployee(id);

return new ResponseEntity<>(HttpStatus.OK);

EmployeeNotFoundException
package com.tsdotinc.employeemanagement.api.exception;

import org.springframework.http.HttpStatus;

import org.springframework.web.bind.annotation.ResponseStatus;

import java.io.Serial;

@ResponseStatus(value = HttpStatus.NOT_FOUND)

public class EmployeeNotFoundException extends RuntimeException{

@Serial

private static final long serialVersionUID = 5088656726691794786L;

public EmployeeNotFoundException(String message){

super(message);

Employee
package com.tsdotinc.employeemanagement.api.model;

import jakarta.persistence.*;

import com.fasterxml.jackson.annotation.JsonProperty;

import lombok.AllArgsConstructor;

import lombok.Data;

import lombok.NoArgsConstructor;
import lombok.ToString;

import java.io.Serial;

import java.io.Serializable;

@Entity

@Table(name="employee_tbl")

@Data

@AllArgsConstructor

@NoArgsConstructor

@ToString

public class Employee implements Serializable {

@Serial

private static final long serialVersionUID = 1954355911137869829L;

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

@Column(name="Id")

private Long id;

@Column(name="First_Name")

@JsonProperty("firstName")

private String firstName;

@Column(name="Last_Name")

@JsonProperty("lastName")

private String lastName;

@Column(name="Email_Id")

@JsonProperty("emailId")

private String emailId;


@Column(name="Job_Title")

@JsonProperty("jobTitle")

private String jobTitle;

@Column(name="Department_Name")

@JsonProperty("departmentName")

private String departmentName;

@Column(name="Phone")

@JsonProperty("phone")

private String phone;}

EmployeeRepository
package com.tsdotinc.employeemanagement.api.repository;

import com.tsdotinc.employeemanagement.api.model.Employee;

import org.springframework.data.jpa.repository.JpaRepository;

import org.springframework.stereotype.Repository;

import java.util.Optional;

@Repository

public interface EmployeeRepository extends JpaRepository<Employee, Long> {

Optional<Employee> findEmployeeById(Long id);

EmployeeService
package com.tsdotinc.employeemanagement.api.service;

import com.tsdotinc.employeemanagement.api.exception.EmployeeNotFoundException;

import com.tsdotinc.employeemanagement.api.model.Employee;

import com.tsdotinc.employeemanagement.api.repository.EmployeeRepository;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;
import java.util.List;

@Service

public class EmployeeService {

@Autowired

private EmployeeRepository employeeRepository;

public Employee addEmployee(Employee employee) {

return employeeRepository.save(employee);

public List<Employee> findAllEmployees() {

return employeeRepository.findAll();

public Employee findEmployeeById(Long id) {

return employeeRepository.findEmployeeById(id)

.orElseThrow(() -> new EmployeeNotFoundException

("Employee by id "+id+"was not found"));

public Employee updateEmployee(Employee employee) {

return employeeRepository.save(employee);

public void deleteEmployee(Long id) {

Employee existingEmployee = this.employeeRepository

.findById(id)

.orElseThrow(() -> new EmployeeNotFoundException

("Employee by id "+id+"was not found"));

this.employeeRepository.delete(existingEmployee);
}

ApplicationProperties
server.port=8081

spring.datasource.url=jdbc:mysql://localhost:3306/employeerepo?
allowPublicKeyRetrieval=true&useSSL=false

spring.datasource.username=root

spring.datasource.password=root

spring.jpa.hibernate.ddl-auto=update

spring.jpa.show-sql=true

# Use the built-in Spring naming strategy

spring.jpa.hibernate.naming.implicit-
strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl

spring.jpa.hibernate.naming.physical-
strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

EmployeeIntegrationTests
package com.tsdotinc.employeemanagement.api;

import static org.assertj.core.api.Assertions.assertThat;

import com.tsdotinc.employeemanagement.api.service.EmployeeService;

import org.junit.jupiter.api.Test;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.test.context.SpringBootTest;

import org.springframework.test.context.ActiveProfiles;

@SpringBootTest

@ActiveProfiles("test") // Use a test profile if available

class EmployeeIntegrationTests {
@Autowired

private EmployeeService employeeService;

@Test

void contextLoads() {

// Verify that the application context loads successfully

assertThat(employeeService).isNotNull();

@Test

void testEmployeeService() {

// Example integration test: Fetch an employee and validate

var employee = employeeService.findEmployeeById(1L);

assertThat(employee).isNotNull();

assertThat(employee.getFirstName()).isEqualTo("Morgan");

}
1. Create - Add New Employee

Endpoint:
POST /api/employees

Request Body (JSON):

json

Copy code

"firstName": "John",

"lastName": "Doe",

"emailId": "[email protected]",

"jobTitle": "Software Engineer",

"departmentName": "Engineering",

"phone": "123-456-7890"

Description:

 The addEmployee method in EmployeeController handles this.

 It accepts an Employee object in the request body and saves it to the database through the
EmployeeService layer.

2. Read (All Employees) - Get All Employees

Endpoint:
GET /api/employees

Response Example (JSON):

json

Copy code

"id": 1,

"firstName": "John",

"lastName": "Doe",
"emailId": "[email protected]",

"jobTitle": "Software Engineer",

"departmentName": "Engineering",

"phone": "123-456-7890"

Description:

 The getAllEmployees method in the controller fetches all records using findAllEmployees().

3. Read (Single Employee by ID)

Endpoint:
GET /api/employees/{id}

Example:
GET /api/employees/1

Response Example (JSON):

json

Copy code

"id": 1,

"firstName": "John",

"lastName": "Doe",

"emailId": "[email protected]",

"jobTitle": "Software Engineer",

"departmentName": "Engineering",

"phone": "123-456-7890"

Description:

 The findEmployeeById method in the controller retrieves an employee by their ID.

 If the employee doesn't exist, a custom EmployeeNotFoundException is thrown.

4. Update - Modify Existing Employee


Endpoint:
PUT /api/employees/{id}

Request Body (JSON):

json

Copy code

"firstName": "Jane",

"lastName": "Doe",

"emailId": "[email protected]",

"jobTitle": "Project Manager",

"departmentName": "Management",

"phone": "987-654-3210"

Example:
PUT /api/employees/1

Description:

 The updateEmployee method accepts an employee object and updates it in the database by
ID.

5. Delete - Remove an Employee

Endpoint:
DELETE /api/employees/{id}

Example:
DELETE /api/employees/1

Description:

 The deleteEmployee method finds the employee by ID and deletes them from the database.

 If the employee is not found, an exception is thrown.


To set up MySQL for your Spring Boot project, you need to complete the following steps:

1. Install MySQL (If not already installed)

 Download and install MySQL from the official site:


https://dev.mysql.com/downloads/installer/

 Follow the instructions based on your operating system.

2. Create a Database for the Application

You need to create a database where the application can store its data. In your case, the
configuration uses book as the database name.

Run the following SQL command to create the book database:

CREATE DATABASE book;

3. Create Tables

Since you are using Hibernate (JPA) to manage your entities, you can allow Spring Boot to
automatically create the necessary tables in the database, thanks to the spring.jpa.hibernate.ddl-
auto=update property. This will create or update the database schema based on the entities you
have defined.

However, if you want to manually create the tables, here's an SQL script that corresponds to your
Book and MyBookList entities.

-- Creating 'book' table (based on Book entity)

CREATE TABLE Book (

id INT AUTO_INCREMENT PRIMARY KEY,

name VARCHAR(255),

author VARCHAR(255),

price VARCHAR(255)

);

-- Creating 'MyBooks' table (based on MyBookList entity)

CREATE TABLE MyBooks (

id INT PRIMARY KEY,

name VARCHAR(255),

author VARCHAR(255),

price VARCHAR(255)

);

4. Configure MySQL User and Permissions


Make sure that the MySQL user (root in your case) has the necessary permissions to access the
database.

If you haven't already created a user with privileges for the book database, you can do that with the
following commands:

-- Create a new user (optional)

CREATE USER 'root'@'localhost' IDENTIFIED BY 'root';

-- Grant privileges to the user

GRANT ALL PRIVILEGES ON book.* TO 'root'@'localhost';

-- Flush privileges to apply changes

FLUSH PRIVILEGES;

5. Verify Database Connection

You can verify the connection to the database by running the following command in MySQL:

SHOW TABLES;

This should display the tables you've created (Book and MyBooks) if everything is set up correctly.

6. Ensure MySQL is Running

Ensure that your MySQL server is running. You can start it using the following command (based on
your operating system):

 Windows: Use MySQL Workbench or the Command Prompt with mysql.server start.

 Linux/Mac: Run sudo service mysql start or sudo systemctl start mysql.

7. Test the Connection

Once the database is set up, you can run your Spring Boot application and check the logs to ensure
the application successfully connects to the MySQL database and interacts with the tables.

Summary

 Create the book database in MySQL.

 Define the tables (Book and MyBooks) based on your entity models, or rely on Hibernate to
do this automatically.

 Ensure that MySQL user permissions are properly set up.

 Start MySQL and verify the connection from Spring Boot.

Once these steps are completed, your Spring Boot application should be able to interact with the
MySQL database.
BookStore/

├── src/

│ ├── main/

│ │ ├── java/com/BookStore/

│ │ │ ├── controller/

│ │ │ │ ├── BookController.java

│ │ │ │ ├── MyBookListController.java

│ │ │ ├── entity/

│ │ │ │ ├── Book.java

│ │ │ │ ├── MyBookList.java

│ │ │ ├── repository/

│ │ │ │ ├── BookRepository.java

│ │ │ │ ├── MyBookRepository.java

│ │ │ ├── service/

│ │ │ │ ├── BookService.java

│ │ │ │ ├── MyBookListService.java

│ │ │

│ │ │

│ │ └── resources/

│ │ ├── static/

│ │ │ ├── css/

│ │ │ │ └── style.css

│ │ │ ├── js/

│ │ │ │ └── script.js

│ │ ├── templates/

│ │ │ ├── bookEdit.html

│ │ │ ├── bookList.html

│ │ │ ├── BookRegister.html

│ │ │ ├── home.html

│ │ │ └── myBooks.html
│ │

│ │ ├── application.properties

│ └── src/test/java

└── pom.xml

BookStore/

├── src/

│ ├── main/

│ │ ├── java/com/BookStore/

package com.bookStore;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication

public class BookStoreApplication {


public static void main(String[] args) {

SpringApplication.run(BookStoreApplication.class, args);

│ │ │ ├── controller/

│ │ │ │ ├── BookController.java

package com.bookStore.controller;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

import org.springframework.web.bind.annotation.*;

import org.springframework.web.servlet.ModelAndView;

import com.bookStore.entity.Book;

import com.bookStore.entity.MyBookList;
import com.bookStore.service.BookService;

import com.bookStore.service.MyBookListService;

import java.util.*;

@Controller

public class BookController {

@Autowired

private BookService service;

@Autowired

private MyBookListService myBookService;

@GetMapping("/")

public String home() {

return "home";

@GetMapping("/book_register")

public String bookRegister() {

return "bookRegister";

@GetMapping("/available_books")

public ModelAndView getAllBook() {

List<Book>list=service.getAllBook();

// ModelAndView m=new ModelAndView();

// m.setViewName("bookList");

// m.addObject("book",list);

return new ModelAndView("bookList","book",list);

@PostMapping("/save")
public String addBook(@ModelAttribute Book b) {

service.save(b);

return "redirect:/available_books";

@GetMapping("/my_books")

public String getMyBooks(Model model)

List<MyBookList>list=myBookService.getAllMyBooks();

model.addAttribute("book",list);

return "myBooks";

@RequestMapping("/mylist/{id}")

public String getMyList(@PathVariable("id") int id) {

Book b=service.getBookById(id);

MyBookList mb=new MyBookList(b.getId(),b.getName(),b.getAuthor(),b.getPrice());

myBookService.saveMyBooks(mb);

return "redirect:/my_books";

@RequestMapping("/editBook/{id}")

public String editBook(@PathVariable("id") int id,Model model) {

Book b=service.getBookById(id);

model.addAttribute("book",b);

return "bookEdit";

@RequestMapping("/deleteBook/{id}")

public String deleteBook(@PathVariable("id")int id) {

service.deleteById(id);

return "redirect:/available_books";

}
}

│ │ │ │ ├── MyBookListController.java

package com.bookStore.controller;

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 com.bookStore.service.MyBookListService;

@Controller

public class MyBookListController {

@Autowired

private MyBookListService service;

@RequestMapping("/deleteMyList/{id}")

public String deleteMyList(@PathVariable("id") int id) {

service.deleteById(id);

return "redirect:/my_books";

│ │ │ ├── entity/

│ │ │ │ ├── Book.java

package com.bookStore.entity;

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;

import javax.persistence.Id;

@Entity

public class Book {

@Id

@GeneratedValue(strategy=GenerationType.IDENTITY)

private int id;

private String name;

private String author;

private String price;

public Book(int id, String name, String author, String price) {

super();

this.id = id;

this.name = name;

this.author = author;

this.price = price;

public Book() {

super();

// TODO Auto-generated constructor stub

public int getId() {

return id;

public void setId(int id) {

this.id = id;

public String getName() {

return name;
}

public void setName(String name) {

this.name = name;

public String getAuthor() {

return author;

public void setAuthor(String author) {

this.author = author;

public String getPrice() {

return price;

public void setPrice(String price) {

this.price = price;

│ │ │ │ ├── MyBookList.java

package com.bookStore.entity;

import javax.persistence.Column;

import javax.persistence.Entity;

import javax.persistence.Id;

import javax.persistence.Table;

@Entity

@Table(name="MyBooks")

public class MyBookList {

@Id
private int id;

private String name;

private String author;

private String price;

public MyBookList() {

super();

// TODO Auto-generated constructor stub

public MyBookList(int id, String name, String author, String price) {

super();

this.id = id;

this.name = name;

this.author = author;

this.price = price;

public int getId() {

return id;

public void setId(int id) {

this.id = id;

public String getName() {

return name;

public void setName(String name) {

this.name = name;

public String getAuthor() {

return author;

public void setAuthor(String author) {


this.author = author;

public String getPrice() {

return price;

public void setPrice(String price) {

this.price = price;

│ │ │ ├── repository/

│ │ │ │ ├── BookRepository.java

package com.bookStore.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import org.springframework.stereotype.Repository;

import com.bookStore.entity.Book;

@Repository

public interface BookRepository extends JpaRepository<Book,Integer> {

│ │ │ │ ├── MyBookRepository.java

package com.bookStore.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import org.springframework.stereotype.Repository;

import com.bookStore.entity.MyBookList;
@Repository

public interface MyBookRepository extends JpaRepository<MyBookList,Integer>{

│ │ │ ├── service/

│ │ │ │ ├── BookService.java

package com.bookStore.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import com.bookStore.entity.Book;

import com.bookStore.repository.BookRepository;

@Service

public class BookService {

@Autowired

private BookRepository bRepo;

public void save(Book b) {

bRepo.save(b);

public List<Book> getAllBook(){

return bRepo.findAll();

public Book getBookById(int id) {


return bRepo.findById(id).get();

public void deleteById(int id) {

bRepo.deleteById(id);

│ │ │ │ ├── MyBookListService.java

package com.bookStore.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import com.bookStore.entity.MyBookList;

import com.bookStore.repository.MyBookRepository;

@Service

public class MyBookListService {

@Autowired

private MyBookRepository mybook;

public void saveMyBooks(MyBookList book) {

mybook.save(book);

public List<MyBookList> getAllMyBooks(){

return mybook.findAll();

}
public void deleteById(int id) {

mybook.deleteById(id);

│ │ │

│ │ │

│ │ └── resources/

│ │ ├── static/

│ │ │ ├── css/

│ │ │ │ └── style.css

│ │ │ ├── js/

│ │ │ │ └── script.js

│ │ ├── templates/

│ │ │ ├── bookEdit.html
│ │ │ │ <!doctype html>

<html lang="en" xmlns:th="https://www.thymeleaf.com">

<head>

<meta charset="utf-8">

<meta name="viewport" content="width=device-width, initial-scale=1">

<link

href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"

rel="stylesheet"

integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"

crossorigin="anonymous">

<title>Book Store</title>

</head>

<body>
<nav class="navbar navbar-expand-lg navbar-light bg-dark">

<div class="container-fluid">

<a class="navbar-brand text-white" href="#">Book Store</a>

<button class="navbar-toggler" type="button"

data-bs-toggle="collapse" data-bs-
target="#navbarSupportedContent"

aria-controls="navbarSupportedContent" aria-expanded="false"

aria-label="Toggle navigation">

<span class="navbar-toggler-icon"></span>

</button>

<div class="collapse navbar-collapse" id="navbarSupportedContent">

<ul class="navbar-nav me-auto mb-2 mb-lg-0">

<li class="nav-item"><a class="nav-link active text-white"

aria-current="page" href="/">Home</a></li>

<li class="nav-item"><a class="nav-link text-white"

href="available_books">Available Books</a></li>

<li class="nav-item"><a class="nav-link text-white"


href="my_books">My

Books</a></li> </ul>

<div><a class="nav-link text-white" href="book_register">New Book


Register</a>

</div>

</div>

</div>

</nav>

<div class="container my-5 p-5" style="border:1px solid black;">

<h4 class="text-center">Edit Book Here</h4>

<form class="col-md-4 offset-md-4" th:action="@{/save}" method="post"


th:object="${book}">

<input type="hidden" name="id" th:value="${book.id}"/>

<div class="mb-3">

<label for="name" class="form-label">Name


</label> <input type="text" class="form-control"
name="name" th:value="${book.name}">

</div>

<div class="mb-3">

<label for="author" class="form-label">Author

</label> <input type="text" class="form-control"


name="author" th:value="${book.author}">

</div>

<div class="mb-3">

<label for="price" class="form-label">Price

</label> <input type="text" class="form-control"


name="price" th:value="${book.price}">

</div>

<center><button type="submit" class="btn


btn-primary">Submit</button></center>

</form>

</div>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"

integrity="sha384-
MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"

crossorigin="anonymous"></script>

<script src="https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/umd/popper.min.js"

integrity="sha384-
IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p"

crossorigin="anonymous"></script>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"

integrity="sha384-cVKIPhGWiC2Al4u+LWgxfKTRIcfu0JTxR+EQDz/bgldoEyl4H0zUF0QKbrJ0EcQF"

crossorigin="anonymous"></script>

</body>

</html>
│ │ │ ├── bookList.html

│ │ │ │ <!doctype html>

<html lang="en" xmlns:th="https://www.thymeleaf.com">

<head>

<meta charset="utf-8">

<meta name="viewport" content="width=device-width, initial-scale=1">

<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
crossorigin="anonymous">

<title>Book Store</title>

<script src="https://kit.fontawesome.com/0faddc1af8.js" crossorigin="anonymous"></script>

</head>

<body>

<nav class="navbar navbar-expand-lg navbar-light bg-dark">

<div class="container-fluid">

<a class="navbar-brand text-white" href="#">Book Store</a>

<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-


target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false"
aria-label="Toggle navigation">

<span class="navbar-toggler-icon"></span>

</button>

<div class="collapse navbar-collapse" id="navbarSupportedContent">

<ul class="navbar-nav me-auto mb-2 mb-lg-0">

<li class="nav-item">

<a class="nav-link active text-white" aria-current="page" href="/">Home</a>

</li>

<li class="nav-item">

<a class="nav-link text-white" href="available_books">Available Books</a>


</li>

<li class="nav-item">

<a class="nav-link text-white" href="my_books">My Books</a>

</li>

</ul>

<div>

<a class="nav-link text-white" href="book_register">New Book Register</a>

</div>

</div>

</div>

</nav>

<div class="container my-5 col-md-8">

<table class="table table-striped table-hover">

<thead>

<tr>

<th scope="col">Id</th>

<th scope="col">Name</th>

<th scope="col">Author</th>

<th scope="col">Price</th>

<th scope="col">Action</th>

</tr>

</thead>

<tbody>

<tr th:each="b :${book}">

<td th:text="${b.id}"></td>

<td th:text="${b.name}"></td>

<td th:text="${b.author}"></td>

<td th:text="${b.price}"></td>

<td><a class="btn btn-secondary btn-sm" th:href="@{/mylist/{id}(id=${b.id})}">Add To


Mybook</a>
<a style="color:blue" th:href="@{/editBook/{id}(id=${b.id})}"><i class="fa-solid fa-pen-to-square
ms-4"></i></a>

<a style="color:red" th:href="@{/deleteBook/{id}(id=${b.id})}"><i class="fa-solid fa-trash ms-


4"></i></a>

</td>

</tr>

</tbody>

</table>

</div>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous"></script>

<script src="https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/umd/popper.min.js"
integrity="sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p"
crossorigin="anonymous"></script>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"
integrity="sha384-cVKIPhGWiC2Al4u+LWgxfKTRIcfu0JTxR+EQDz/bgldoEyl4H0zUF0QKbrJ0EcQF"
crossorigin="anonymous"></script>

</body>

</html>

│ │ │ ├── BookRegister.html

│ │ │ │ <!doctype html>

<html lang="en" xmlns:th="https://www.thymeleaf.com">

<head>

<meta charset="utf-8">

<meta name="viewport" content="width=device-width, initial-scale=1">

<link
href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"

rel="stylesheet"

integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"

crossorigin="anonymous">

<title>Book Store</title>

</head>

<body>

<nav class="navbar navbar-expand-lg navbar-light bg-dark">

<div class="container-fluid">

<a class="navbar-brand text-white" href="#">Book Store</a>

<button class="navbar-toggler" type="button"

data-bs-toggle="collapse" data-bs-
target="#navbarSupportedContent"

aria-controls="navbarSupportedContent" aria-expanded="false"

aria-label="Toggle navigation">

<span class="navbar-toggler-icon"></span>

</button>

<div class="collapse navbar-collapse" id="navbarSupportedContent">

<ul class="navbar-nav me-auto mb-2 mb-lg-0">

<li class="nav-item"><a class="nav-link active text-white"

aria-current="page" href="/">Home</a></li>

<li class="nav-item"><a class="nav-link text-white"

href="available_books">Available Books</a></li>

<li class="nav-item"><a class="nav-link text-white"


href="my_books">My

Books</a></li>

</ul>

<div>
<a class="nav-link text-white" href="book_register">New
Book

Register</a>

</div>

</div>

</div>

</nav>

<div class="container my-5 p-5" style="border:1px solid black;">

<h4 class="text-center">New Book Register</h4>

<form class="col-md-4 offset-md-4" th:action="@{/save}" method="post">

<div class="mb-3">

<label for="name" class="form-label">Name

</label> <input type="text" class="form-control"


name="name">

</div>

<div class="mb-3">

<label for="author" class="form-label">Author

</label> <input type="text" class="form-control"


name="author">

</div>

<div class="mb-3">

<label for="price" class="form-label">Price

</label> <input type="text" class="form-control"


name="price">

</div>

<center><button type="submit" class="btn


btn-primary">Submit</button></center>

</form>

</div>
<script

src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"

integrity="sha384-
MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"

crossorigin="anonymous"></script>

<script

src="https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/umd/popper.min.js"

integrity="sha384-
IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p"

crossorigin="anonymous"></script>

<script

src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"

integrity="sha384-cVKIPhGWiC2Al4u+LWgxfKTRIcfu0JTxR+EQDz/bgldoEyl4H0zUF0QKbrJ0EcQF"

crossorigin="anonymous"></script>

</body>

</html>

│ │ │ ├── home.html
│ │ │ │ <!doctype html>

<html lang="en" xmlns:th="https://www.thymeleaf.com">

<head>

<meta charset="utf-8">

<meta name="viewport" content="width=device-width, initial-scale=1">

<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
crossorigin="anonymous">

<title>Book Store</title>

</head>
<body>

<nav class="navbar navbar-expand-lg navbar-light bg-dark">

<div class="container-fluid">

<a class="navbar-brand text-white" href="#">Book Store</a>

<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-


target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false"
aria-label="Toggle navigation">

<span class="navbar-toggler-icon"></span>

</button>

<div class="collapse navbar-collapse" id="navbarSupportedContent">

<ul class="navbar-nav me-auto mb-2 mb-lg-0">

<li class="nav-item">

<a class="nav-link active text-white" aria-current="page" href="/">Home</a>

</li>

<li class="nav-item">

<a class="nav-link text-white" href="available_books">Available Books</a>

</li>

<li class="nav-item">

<a class="nav-link text-white" href="my_books">My Books</a>

</li>

</ul>

<div>

<a class="nav-link text-white" href="book_register">New Book Register</a>

</div>

</div>

</div>

</nav>

<div class="container text-center my-5">

<h1>WELCOME TO NEW BOOK STORE</h1>


<h6>Lorem ipsum dolor sit amet .

The graphic and typographic operators know this well, in reality all the professions

dealing with the universe of communication have a stable relationship with these words,

but what is it? Lorem ipsum is a dummy text without any sense. It is a sequence of Latin

words that, as they are positioned, do not form sentences with a complete sense, but give

life to a test text useful to fill spaces that will subsequently be occupied from ad hoc

texts composed by communication professionals. It is certainly the most famous placeholder

text even if there are different versions distinguishable from the order in which the

Latin words are repeated.

</h6>

<img src="/images/bg.png" width="360px"/>

</div>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous"></script>

<script src="https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/umd/popper.min.js"
integrity="sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p"
crossorigin="anonymous"></script>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"
integrity="sha384-cVKIPhGWiC2Al4u+LWgxfKTRIcfu0JTxR+EQDz/bgldoEyl4H0zUF0QKbrJ0EcQF"
crossorigin="anonymous"></script>

</body>

</html>

│ │ │ └── myBooks.html

│ │ <!doctype html>

<html lang="en" xmlns:th="https://www.thymeleaf.com">

<head>

<meta charset="utf-8">

<meta name="viewport" content="width=device-width, initial-scale=1">

<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
crossorigin="anonymous">

<title>Book Store</title>
<script src="https://kit.fontawesome.com/0faddc1af8.js" crossorigin="anonymous"></script>

</head>

<body>

<nav class="navbar navbar-expand-lg navbar-light bg-dark">

<div class="container-fluid">

<a class="navbar-brand text-white" href="#">Book Store</a>

<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-


target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false"
aria-label="Toggle navigation">

<span class="navbar-toggler-icon"></span>

</button>

<div class="collapse navbar-collapse" id="navbarSupportedContent">

<ul class="navbar-nav me-auto mb-2 mb-lg-0">

<li class="nav-item">

<a class="nav-link active text-white" aria-current="page" href="/">Home</a>

</li>

<li class="nav-item">

<a class="nav-link text-white" href="available_books">Available Books</a>

</li>

<li class="nav-item">

<a class="nav-link text-white" href="my_books">My Books</a>

</li>

</ul>

<div>

<a class="nav-link text-white" href="book_register">New Book Register</a>

</div>

</div>

</div>

</nav>

<div class="container my-5 col-md-6">


<table class="table table-striped table-hover">

<thead>

<tr>

<th scope="col">Id</th>

<th scope="col">Name</th>

<th scope="col">Author</th>

<th scope="col">Price</th>

<th scope="col">Action</th>

</tr>

</thead>

<tbody>

<tr th:each="b :${book}">

<td th:text="${b.id}"></td>

<td th:text="${b.name}"></td>

<td th:text="${b.author}"></td>

<td th:text="${b.price}"></td>

<td><a style="color:red" th:href="@{/deleteMyList/{id}(id=${b.id})}"><i class="fa-solid fa-


trash"></i></a></td>

</tr>

</tbody>

</table>

</div>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous"></script>

<script src="https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/umd/popper.min.js"
integrity="sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p"
crossorigin="anonymous"></script>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"
integrity="sha384-cVKIPhGWiC2Al4u+LWgxfKTRIcfu0JTxR+EQDz/bgldoEyl4H0zUF0QKbrJ0EcQF"
crossorigin="anonymous"></script>

</body>

</html>
│ │ ├── application.properties
server.port=1001

spring.datasource.name=book

spring.datasource.url=jdbc:mysql://localhost:3306/book?ServerTimezone=UTC

spring.datasource.username=root

spring.datasource.password=root

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

spring.jpa.hibernate.ddl-auto=update

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect

│ └── src/test/java

package com.bookStore;

import org.junit.jupiter.api.Test;

import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest

class BookStoreApplicationTests {

@Test

void contextLoads() {

└── 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>2.7.5</version>

<relativePath/> <!-- lookup parent from repository -->

</parent>

<groupId>com.bookStore</groupId>

<artifactId>bookStore</artifactId>

<version>0.0.1-SNAPSHOT</version>

<name>bookStore</name>

<description>This is book store project</description>

<properties>

<java.version>11</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>

<scope>runtime</scope>

<optional>true</optional>

</dependency>

<dependency>

<groupId>com.mysql</groupId>

<artifactId>mysql-connector-j</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>

You might also like