KEMBAR78
Rest Unit 2 Cls Notes | PDF | Databases | Data Management Software
0% found this document useful (0 votes)
7 views36 pages

Rest Unit 2 Cls Notes

Uploaded by

oopsitsmysteria
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)
7 views36 pages

Rest Unit 2 Cls Notes

Uploaded by

oopsitsmysteria
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/ 36

22IT910-REST APPLICATION DEVELOPMENT USING

SPRING BOOT AND JPA

UNIT II ADVANCED DATA MANAGEMENT WITH JAVA AND MYSQL

Build production-grade applications – MYSQL - mapping Java classes to relational


database - repository interface - data access operations – retrieving data from the database
–mapping of request body to entity - retrieve an entity - capture data from API requests -
building complex queries using keywords.

Build Production
Building production involves a series of steps to prepare an application for deployment
and use in a live environment. Here's a general overview of the process:

1. Project Setup

●​ Version Control: Ensure your project is in a version control system like Git.
●​ Dependencies: Define and manage dependencies using tools like npm, pip,
Maven, etc.

2. Environment Configuration

3. Build Process

4. Continuous Integration/Continuous Deployment (CI/CD)

5. Server and Infrastructure Setup

6. Deployment

7. Monitoring and Maintenance

8. Security
Building a production-ready Spring Boot application with JPA involves several key steps,
including setting up your development environment, writing and testing your code,
configuring your application, and deploying it. Here's a step-by-step guide:
1. Project Setup
2. Configure Your Database
3. Entity and Repository Setup
4. Service Layer
5. Controller Layer
6. Build and Test
7. Dockerize Your Application
8. Deploy to Production
9. Monitoring and Maintenance

Monitoring Tools

●​ Prometheus: Collect metrics from your application.


●​ Grafana: Visualize the metrics collected by Prometheus.

Logging

●​ ELK Stack (Elasticsearch, Logstash, Kibana): Centralize your logs and


analyze them.

Error Tracking

●​ Sentry: Track and fix errors in real time

10. Security

●​ HTTPS: Ensure your application uses HTTPS.


●​ Environment Variables: Store sensitive data in environment variables.
●​ Regular Updates: Keep your dependencies up to date.

Spring Boot – Dependency Management


Importance of Dependency Management
●​ It allows specifying all required dependencies according to the respective
Spring-Boot version in one place itself.
●​ You can specify or change the Spring-Boot version. On changing Spring-Boot
versions, all the versions of mentioned(added) dependencies will be updated
automatically.
●​ You can prevent conflicts of different Spring-Boot libraries versions, which is
beneficial for the ‘Multi-Module’ projects.
Working of Dependency Management in Spring-Boot
●​ Dependency is nothing but a ‘Library’ that provides specific functionality that we
can use in our application.
●​ In Spring-Boot, Dependency Management and Auto-Configuration work
simultaneously.
●​ It is the auto-configuration that makes managing dependencies supremely easy for
us.
●​ We have to add the dependencies in the pom.xml/build.gradle file.
●​ These added dependencies will then get downloaded from Maven Central.
●​ The downloaded dependencies will get stored into the ‘.m2’ folder in the local file
system.
●​ The Spring-Boot application can access these dependencies from ‘.m2’ and its
sub-directories.
●​ Example -( .m2 -> repository -> org, etc )
●​
Project Build Systems
1.​ You should work with the two most used builds Maven and Gradle.
2.​ Maven and Gradle use a different syntax for managing dependencies.
3.​ Also, you don’t need to mention the version of the dependencies, as Spring-Boot
configures them automatically. Though you can mention the version or override as
well.
4.​ The curated list published contains all the Spring Modules and third-party libraries
that you can use with Spring-Boot.
5.​ Maven manages them in the ‘pom.xml’ file, while Gradle manages them in the
‘build.gradle’ file.
Features of Maven build
1.​ It uses the default Java compiler.
2.​ It has UTF-8 source encoding
3.​ A useful feature of not mentioning the version information of dependencies is
inherited from POM ( spring-boot-dependencies ).
4.​ Resource filtering and plugin configurations.
5.​ Resource filtering is also for ‘application.properties’ and ‘application.yml’.
Spring Annotations
Spring Annotations are a form of metadata that provides data about a program.
Annotations are used to provide supplemental information about a program. It does not
have a direct effect on the operation of the code they annotate. It does not change the
action of the compiled program.

@Service Annotation
In an application, the business logic resides within the service layer so we use the
@Service Annotation to indicate that a class belongs to that layer. It is also a
specialization of @Component Annotation like the @Repository Annotation. One most
important thing about the @Service Annotation is it can be applied only to classes. It is
used to mark the class as a service provider. So overall @Service annotation is used with
classes that provide some business functionalities. Spring context will autodetect these
classes when annotation-based configuration and classpath scanning is used.

@Repository Annotation
@Repository Annotation is a specialization of @Component annotation which is used to
indicate that the class provides the mechanism for storage, retrieval, update, delete and
search operation on objects. Though it is a specialization of @Component annotation, so
Spring Repository classes are autodetected by spring framework through classpath
scanning. This annotation is a general-purpose stereotype annotation which very close to
the DAO pattern where DAO classes are responsible for providing CRUD operations on
database tables.

@Service Annotation @Repository Annotation

@Service annotation is used


with classes that provide some @Repository Annotation is used to indicate
business functionalities. that the class provides the mechanism for
storage, retrieval, update, delete and search
operation on objects.

@Service Annotation is a
@Repository Annotation is also a
specialization of @Component
specialization of @Component Annotation.
Annotation.

It can be applied only to


It is used at the class level.
classes.

It is used to mark the class as a It is used to mark the interface as DAO (Data
service provider. Access Object) provider.

It is a Stereotype Annotations. It is also a Stereotype Annotations.

To connect with the MySQL Database you have to write a bunch of lines. You can write the properties
like this
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
username: springuser
url: jdbc:mysql://${MYSQL_HOST:localhost}:3306/db_example
password: ThePassword
jpa:
hibernate:
ddl-auto: update
So to connect and perform CRUD operation with the MySQL DB with Spring Boot
application we have to just configure it inside the application.properties file as follows:
# Configuration for MySQL Database

spring.jpa.hibernate.ddl-auto=update

spring.datasource.url = jdbc:mysql://localhost:3306/schooldb
(Datasource URL of your DB and "schooldb", here is your schema name)

spring.datasource.username=amiya559 (Your MySQL Workbench user name)


spring.datasource.password=password.123 (Your MySQL Workbench password)
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.show-sql:true

Mapping java classes to relational database


Mapping Java classes to a relational database is typically done using Object-Relational
Mapping (ORM) frameworks. The most commonly used ORM framework in Java is
Hibernate, which is often integrated with JPA (Java Persistence API).

JPA and ORM Overview

JPA (Java Persistence API) and ORM (Object-Relational Mapping) are essential
concepts for managing and accessing relational databases in Java applications. Here’s an
overview of both:

1. JPA (Java Persistence API)

JPA is a specification for managing relational data in Java applications. It provides a


standard way to map Java objects to database tables, manage data, and perform CRUD
(Create, Read, Update, Delete) operations. JPA is part of the Java EE (Enterprise Edition)
specification but can also be used in Java SE (Standard Edition) applications.

Key Features of JPA

●​ Entity Management: Defines how Java classes (entities) are mapped to database
tables.
●​ JPQL (Java Persistence Query Language): A query language similar to SQL
but operates on entities rather than database tables.
●​ EntityManager: The primary API for interacting with the persistence context,
managing entities, and performing operations.
●​ Transaction Management: Supports declarative and programmatic transaction
management.

Core Annotations

●​ @Entity: Marks a class as an entity, meaning it is mapped to a database table.


●​ @Table: Specifies the name of the database table if it differs from the entity class
name.
●​ @Id: Denotes the primary key of the entity.
●​ @GeneratedValue: Defines how primary key values are generated (e.g.,
auto-increment).
●​ @Column: Maps a field to a database column and specifies column details like
name, nullable, etc.
●​ @ManyToOne, @OneToMany, @OneToOne, @ManyToMany: Define
relationships between entities.

2. ORM (Object-Relational Mapping)

ORM is a programming technique used to convert data between incompatible type


systems in object-oriented programming languages. ORM frameworks allow developers
to work with database records as Java objects, abstracting away the complexity of SQL.

Benefits of ORM

●​ Abstraction: Provides a high-level abstraction for interacting with the database,


allowing developers to work with objects rather than SQL queries.
●​ Productivity: Reduces boilerplate code for CRUD operations and complex
queries.
●​ Maintenance: Eases the maintenance of database-related code by using a
consistent object-oriented approach.
●​ Portability: Simplifies switching between different database systems.

Common ORM Frameworks

●​ Hibernate: The most widely used ORM framework for Java. It implements JPA
and provides additional features like caching and custom query languages.
●​ EclipseLink: The reference implementation of JPA, providing a comprehensive
ORM solution.
●​ Apache OpenJPA: An open-source implementation of JPA with support for
various advanced features.

\What is ORM and why is it needed?


Traditionally, developers had to write complex SQL queries and mapping code to
transform data between their Java objects and relational database tables. This process was
not only time-consuming but also prone to errors and inconsistencies in updates to
application code, particularly when there are changes to the database schema.

This is where Object-Relational Mapping (ORM) comes into play. ORM is a


programming technique that bridges the gap between the object-oriented programming
and relational databases. It enables developers to work with database entities as if they
were regular Java objects, abstracting away the intricacies of SQL queries and data
mapping.
In essence, ORM simplifies database interactions, making the development process more
efficient and less error-prone.

Spring Boot and ORM


Spring Boot provides extensive support for JPA (Java Persistence API), Hibernate and
more such widely adopted ORM standards. In this implementation we will use Spring
Data Spanner module as the ORM layer that connects the app and the data. It has
features similar to that of Spring Data JPA and Hibernate ORM, with annotations
designed for Spanner.

By incorporating ORM into Spring Boot apps, developers can improve code readability
(as we use high level Java objects), boost productivity (as an application developer, we no
longer focus on writing complex database queries), enhance portability (easily switch
between different databases with minimal code change) and achieve consistency (as ORM
layer enforces consistency in data operations). This is exactly why I said our app is going to
be healthy.

Spring Data JPA or JPA stands for Java Persistence API, so before looking into that, we
must know about ORM (Object Relation Mapping). So Object relation mapping is simply
the process of persisting any java object directly into a database table. Usually, the name
of the object being persisted becomes the name of the table, and each field within that
object becomes a column. With the table setup, each row corresponds to a record in the
application. Hibernate is one example of ORM. In short, JPA is the interface while
hibernate is the implementation.

The java persistence API provides a specification for persisting, reading, and managing
data from your java object to your relational tables in the database. JPA specifies the set
of rules and guidelines for developing interfaces that follow standards. Straight to the
point: JPA is just guidelines to implement ORM and there is no underlying code for the
implementation. Spring Data JPA is part of the spring framework. The goal of spring data
repository abstraction is to significantly reduce the amount of boilerplate code required to
implement a data access layer for various persistence stores. Spring Data JPA is not a JPA
provider, it is a library/framework that adds an extra layer of abstraction on the top of our
JPA provider line Hibernate.

Example: Using JPA with Hibernate

1. Setting Up Dependencies

Add dependencies to your pom.xml for Spring Boot, JPA, and Hibernate:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>

2. Configuration

Configure the database connection in application.properties:

spring.datasource.url=jdbc:mysql://localhost:3306/mydatabase
spring.datasource.username=myusername
spring.datasource.password=mypassword
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
3. Defining Entities

Create an entity class to map to a database table:

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Column;

@Entity
public class User {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(name = "name", nullable = false)


private String name;

@Column(name = "email", unique = true, nullable = false)


private String email;

// Getters and Setters


}
Modal layer:
Create a simple POJO(Plain old java class) with some JPA annotation.
●​ @Entity: This annotation defines that a class can be mapped to a table
●​ @Id: This annotation specifies the primary key of the entity.
●​ @GeneratedValue: This annotation is used to specify the primary key generation
strategy to use. i.e. Instructs database to generate a value for this field
automatically. If the strategy is not specified by default AUTO will be used.

4. Repository Interface

Define a repository interface to handle CRUD operations:


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

public interface UserRepository extends JpaRepository<User, Long> {


// Custom query methods can be added here
}
DAO(Data access object)-Repository layer:
●​ @Repository: The @Repository annotation is a marker for any class that fulfills
the role or stereotype of a repository (also known as Data Access Object or DAO).
●​ JpaRepository<User, Long> JpaRepository is a JPA-specific extension of the
Repository. It contains the full API of CrudRepository and
PagingAndSortingRepository. So it contains API for basic CRUD operations and
also API for pagination and sorting. Here we enable database operations for User.

5. Service Layer
@Service: This annotation is used with classes that provide some business
functionalities. Spring context will autodetect these classes when annotation-based
configuration and classpath scanning is used. Here JPA repository has lots of predefined
generic methods to perform the database operation some are used in the below code.

Implement a service class to manage business logic:

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

import java.util.List;

@Service
public class UserService {

@Autowired
private UserRepository userRepository;

public List<User> getAllUsers() {


return userRepository.findAll();
}

public User getUserById(Long id) {


return userRepository.findById(id).orElse(null);
}

public User saveUser(User user) {


return userRepository.save(user);
}

public void deleteUser(Long id) {


userRepository.deleteById(id);
}
}

6. Controller Layer

●​ @RestController: This is a Spring annotation that is used to build REST API in a


declarative way. RestController annotation is applied to a class to mark it as a
request handler, and Spring will do the building and provide the RESTful web
service at runtime.
●​ @Autowired: This annotation can be used to autowire bean on the setter method
just like @Required annotation, constructor, a property, or methods with arbitrary
names and/or multiple arguments.
●​ @PostMapping: This annotation maps HTTP POST requests onto specific handler
methods. It is a composed annotation that acts as a shortcut for
@RequestMapping(method = RequestMethod. POST)
●​ @GetMapping: This annotation is a specialized version of @RequestMapping
annotation that acts as a shortcut for @RequestMapping(method =
RequestMethod. GET). The @GetMapping annotated methods in the @Controller
annotated classes handle the HTTP GET requests matched with the given URI
expression.
●​ @DeleteMapping: This annotation maps HTTP DELETE requests onto specific
handler methods. It is a composed annotation that acts as a shortcut for
@RequestMapping(method = RequestMethod. DELETE)

Create a controller to handle HTTP requests:

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

@RestController
@RequestMapping("/api/users")
public class UserController {

@Autowired
private UserService userService;

@GetMapping
public List<User> getAllUsers() {
return userService.getAllUsers();
}

@GetMapping("/{id}")
public User getUserById(@PathVariable Long id) {
return userService.getUserById(id);
}

@PostMapping
public User createUser(@RequestBody User user) {
return userService.saveUser(user);
}

@PutMapping("/{id}")
public User updateUser(@PathVariable Long id, @RequestBody User user) {
user.setId(id);
return userService.saveUser(user);
}

@DeleteMapping("/{id}")
public void deleteUser(@PathVariable Long id) {
userService.deleteUser(id);
}
}
Summary

●​ JPA provides a standard API for managing relational data in Java applications.
●​ ORM frameworks, like Hibernate, implement JPA and offer additional features to
simplify database interactions.
●​ Setting up involves adding dependencies, configuring the database, defining
entities, and creating repository, service, and controller layers.

By leveraging JPA and ORM frameworks, you can efficiently manage relational data and
simplify database operations in your Java applications.

Repository interface
In Spring Boot and JPA, the repository interface is a central concept that allows you to
interact with your database entities. By extending Spring Data JPA’s repository interfaces,
you gain CRUD (Create, Read, Update, Delete) operations, pagination, and sorting
capabilities without having to write any boilerplate code.

Spring Data JPA provides several repository interfaces that you can extend based on your
needs:

●​ JpaRepository<T, ID>: Provides JPA related methods such as flushing the


persistence context and delete records in a batch.
●​ CrudRepository<T, ID>: Provides CRUD functions.
●​ PagingAndSortingRepository<T, ID>: Provides additional methods to retrieve
entities using pagination and sorting.

Methods in JPA repository

Spring Data JPA provides a rich set of predefined methods in its repository interfaces, as
well as the ability to define custom queries. The core repository interface in Spring Data
JPA is JpaRepository, which provides the most comprehensive set of methods for CRUD
(Create, Read, Update, Delete) operations, pagination, and sorting.

Here are some key methods available in the JpaRepository interface:

Basic CRUD Methods

1.​ Save
○​ S save(S entity): Saves a given entity.
○​ S saveAndFlush(S entity): Saves an entity and flushes changes instantly.
2.​ Find
○​ Optional<T> findById(ID id): Retrieves an entity by its id.
○​ boolean existsById(ID id): Checks if an entity with the given id exists.
○​ List<T> findAll(): Retrieves all entities.
○​ List<T> findAllById(Iterable<ID> ids): Retrieves all entities by their ids.
3.​ Delete
○​ void deleteById(ID id): Deletes an entity by its id.
○​ void delete(T entity): Deletes a given entity.
○​ void deleteAll(Iterable<? extends T> entities): Deletes the given entities.
○​ void deleteAll(): Deletes all entities.

Pagination and Sorting

1.​ Find with Sorting


○​ List<T> findAll(Sort sort): Retrieves all entities sorted by the given
options.
2.​ Find with Pagination
○​ Page<T> findAll(Pageable pageable): Retrieves all entities in a paginated
format.

Custom Query Methods

In addition to the predefined methods, you can define custom query methods in your
repository interfaces using method naming conventions or the @Query annotation.

Derived Query Methods

Spring Data JPA allows you to define query methods by simply declaring method names
that follow specific conventions.

package com.example.demo.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import com.example.demo.entity.User;

import java.util.List;

public interface UserRepository extends JpaRepository<User, Long> {

// Derived query method to find users by name


List<User> findByName(String name);

// Derived query method to find users by email


List<User> findByEmail(String email);
// Derived query method to find users by name and email
List<User> findByNameAndEmail(String name, String email);
}

UserService
package com.example.demo.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.demo.entity.User;
import com.example.demo.repository.UserRepository;

import java.util.List;

@Service
public class UserService {

@Autowired
private UserRepository userRepository;

// Custom methods
public List<User> findUsersByName(String name) {
return userRepository.findByName(name);
}

public List<User> findUsersByEmail(String email) {


return userRepository.findByEmail(email);
}

public List<User> findUsersByNameAndEmail(String name, String email) {


return userRepository.findByNameAndEmail(name, email);
}

public List<User> findUsersOrderedByName() {


return userRepository.findAllByOrderByNameAsc();
}
}

Advanced Methods

Count and Exists


1.​ Count
○​ long count(): Returns the number of entities.
○​ long countByEmail(String email): Returns the number of entities with the
given email (example of a derived query method).
2.​ Exists
○​ boolean existsById(ID id): Checks if an entity with the given id exists.
○​ boolean existsByEmail(String email): Checks if an entity with the given
email exists (example of a derived query method).

JpaRepository
JpaRepository is a JPA (Java Persistence API) specific extension of Repository. It
contains the full API of CrudRepository and PagingAndSortingRepository. So it contains
API for basic CRUD operations and also API for pagination and sorting.
Syntax:
public interface JpaRepository<T,ID>
extends PagingAndSortingRepository<T,ID>, QueryByExampleExecutor<T>

Some of the most important methods that are available inside the JpaRepository are given
below
public interface DepartmentRepository extends CrudRepository<Department, Long> {}

Method : save(): Saves a given entity. Use the returned instance for further operations as
the save operation might have changed the entity instance completely.
Syntax:
<S extends T> S save(S entity)
●​ Parameters: entity – must not be null.
●​ Returns: the saved entity; will never be null.
●​ Throws: IllegalArgumentException – in case the given entity is null.

saveAll(): Saves all given entities.


save(entity s):save the entity s
<S extends T> List<S> saveAll(Iterable<S> entities)

Method : getById(): Returns a reference to the entity with the given identifier.
Depending on how the JPA persistence provider is implemented this is very likely to
always return an instance and throw an EntityNotFoundException on first access. Some
of them will reject invalid identifiers immediately.
Syntax:
T getById(ID id)
Parameters: id – must not be null.
Return Type: a reference to the entity with the given identifier.

Method : findById(): Retrieves an entity by its id.


Syntax:
Optional<T> findById(ID id)
●​ Parameters: id – must not be null.
●​ Returns: the entity with the given id or Optional#empty() if none found.
●​ Exception Thrown: IllegalArgumentException is thrown if the ‘id’ is null.

Method : findAll(): Returns all instances of the type.


Syntax:
Iterable<T> findAll()
Return Type: All entities
Method : count(): Returns the number of entities available.
Syntax:
long count()
Return Type: the number of entities.
Method : deleteById(): Deletes the entity with the given id.
Syntax:
void deleteById(ID id)
Parameters: Id (must not be null)
Method : flush(): Flushes all pending changes to the database.
Syntax:
void flush()

Method : saveAndFlush(): Saves an entity and flushes changes instantly.


Syntax:
<S extends T> S saveAndFlush(S entity)
Parameters: The entity to be saved. Must not be null.
Return Type: The saved entity
Method : deleteAllInBatch(): Deletes the given entities in a batch which means it will
create a single query. This kind of operation leaves JPAs first-level cache and the
database out of sync. Consider flushing the EntityManager before calling this method.
Syntax:
void deleteAllInBatch(Iterable<T> entities)
Parameters: The entities to be deleted, must not be null.

Difference Between CrudRepository and JpaRepository

CRUD Repository
There is an interface available in Spring Boot named as CrudRepository that contains
methods for CRUD operations. It provides generic Crud operation on a repository. It is
defined in the package org.springframework.data.repository and It extends the Spring
Data Repository interface. If someone wants to use CrudRepository in the spring boot
application he/she has to create an interface and extend the CrudRepository interface.
Syntax:
public interface CrudRepository<T, ID> extends Repository<T, ID>
CrudRepository JpaRepository
It is a base interface and
It extends PagingAndSortingRepository that
extends Repository
extends CrudRepository.
Interface.

It contains the full API of CrudRepository and


It contains methods for
PagingAndSortingRepository. For example, it
CRUD operations. For
contains flush(), saveAndFlush(),
example save(),
saveAllAndFlush(), deleteInBatch(), etc along
saveAll(), findById(),
with the methods that are available in
findAll(), etc.
CrudRepository.

It doesn’t provide
methods for It provides all the methods for which are useful
implementing for implementing pagination.
pagination and sorting

It works as a marker It extends both CrudRepository and


interface. PagingAndSortingRepository.

To perform CRUD
operations, define To perform CRUD as well as batch operations,
repository extending define repository extends JpaRepository.
CrudRepository.
Syntax:
Syntax:

public interface
public interface JpaRepository<T,ID> extends
CrudRepository<T, ID>
PagingAndSortingRepository<T,ID>,
extends Repository<T,
QueryByExampleExecutor<T>
ID>

Data access operations


Data access operations in Spring Boot with JPA involve interacting with the
database to perform CRUD (Create, Read, Update, Delete) operations and other
data manipulations.
Note:Give an example discussed earlier for CRUD

Retrieving data from the database or retrieve an entity


Retrieving data from a database using Spring Data JPA involves using repository
interfaces and querying mechanisms to fetch entities from the database

Basic Retrieval Methods


a. Find All Entities

To retrieve all entities of a particular type, use the findAll() method provided by
JpaRepository.

b. Find by ID

To retrieve a single entity by its ID, use the findById(ID id) method, which returns
an Optional.

2. Custom Query Methods

a. Derived Query Methods


Spring Data JPA allows you to define query methods using method names

b. Custom JPQL Queries

For more complex queries, use the @Query annotation with JPQL (Java Persistence
Query Language).

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

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

import org.springframework.data.repository.query.Param;

import com.example.demo.entity.User;

import java.util.List;

public interface UserRepository extends JpaRepository<User, Long> {

@Query("SELECT u FROM User u WHERE u.name = :name")


List<User> findUsersByName(@Param("name") String name);

@Query("SELECT u FROM User u WHERE u.email = :email")


List<User> findUsersByEmail(@Param("email") String email);

c. Custom Native SQL Queries

You can also use native SQL queries with the @Query annotation.

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

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

import org.springframework.data.repository.query.Param;

import com.example.demo.entity.User;

import java.util.List;

public interface UserRepository extends JpaRepository<User, Long> {

@Query(value = "SELECT * FROM User WHERE email = :email", nativeQuery = true)


List<User> findUsersByEmailNative(@Param("email") String email);

Summary

1.​ Define Your Entity: Ensure you have a JPA entity that represents your data.
2.​ Create a Repository: Extend JpaRepository for basic CRUD operations.
3.​ Service Layer: Implement business logic and data retrieval using the repository.
4.​ Controller Layer: Expose service methods via RESTful endpoints.
5.​ Custom Queries and Pagination: Use custom queries, pagination, and sorting as
needed.

Mapping of request body to entity


In a Spring Boot application, mapping a request body to an entity involves converting
incoming HTTP request data into a Java object that corresponds to your database entity.
This is typically done using Spring's built-in data binding capabilities.

In Spring Boot, mapping a request body to an entity involves converting the JSON or
XML payload of an HTTP request into a Java object that represents the entity. This is
typically handled by Spring's data binding and Jackson (for JSON) or JAXB (for XML)
libraries.

Request Body Mapping

When an HTTP request is made to this endpoint, Spring Boot performs the following
steps:

1.​ HTTP Request Parsing: Spring Boot receives the HTTP request and parses the
request body. This parsing is done using an HTTP message converter, which is
configured to handle the request payload type (JSON, XML, etc.).
2.​ Data Binding: Spring Boot uses the Jackson library (for JSON) or JAXB (for
XML) to bind the request body to the Java object. Jackson is the default JSON
processor in Spring Boot and is configured automatically.
3.​ Object Creation: A new instance of the entity (or DTO) is created, and the data
from the request body is populated into this instance. The JSON keys in the
request body correspond to the fields in the entity class.
Capture data from API requests
Capturing data from API requests in a Spring Boot application involves extracting data
from HTTP requests and processing it in your application. This can be done using various
methods, including request parameters, request bodies, and path variables. Here’s a guide
on how to capture and process data from API requests:

1. Capture Request Parameters

Request parameters are typically sent as query parameters in the URL. You can
capture them using the @RequestParam annotation in your controller.
Example Controller with Request Parameters
package com.example.demo.controller;

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

@RestController
@RequestMapping("/api")
public class ApiController {

@GetMapping("/greet")
public String greet(@RequestParam(name = "name", defaultValue = "Guest")
String name) {
return "Hello, " + name;
}
}

Request: GET /api/greet?name=John


Response: Hello, John

2. Capture Path Variables


Path variables are part of the URL path and can be captured using the @PathVariable
annotation.

Example Controller with Path Variables


package com.example.demo.controller;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api")
public class ApiController {

@GetMapping("/users/{userId}")
public String getUserById(@PathVariable("userId") Long userId) {
return "User ID: " + userId;
}
}

●​ Request: GET /api/users/123


●​ Response: User ID: 123

3. Capture Request Body

The request body contains data sent in the body of POST or PUT requests. You can
capture it using the @RequestBody annotation. This is often used to capture JSON
or XML data.
Example Controller with Request Body
package com.example.demo.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;

@RestController
@RequestMapping("/api")
public class ApiController {

@Autowired
private UserService userService;
@PostMapping("/users")
public User createUser(@RequestBody User user) {
return userService.createUser(user);
}
}

Request Body:
json
{
"name": "John Doe",
"email": "john.doe@example.com"
}

Response: The created User object.

Capture Headers

You can capture HTTP headers using the @RequestHeader annotation.


Example Controller with Request Headers
package com.example.demo.controller;

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

@RestController
@RequestMapping("/api")
public class ApiController {

@GetMapping("/header")
public String getHeader(@RequestHeader("User-Agent") String userAgent) {
return "User-Agent: " + userAgent;
}
}

Request: GET /api/header with User-Agent: Mozilla/5.0


Response: User-Agent: Mozilla/5.0

5. Capture Request Attributes

Attributes can be captured if set in the request scope (e.g., by filters or


interceptors). You can use HttpServletRequest to capture these attributes.

Example Controller with Request Attributes


package com.example.demo.controller;

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

import javax.servlet.http.HttpServletRequest;

@RestController
@RequestMapping("/api")
public class ApiController {

@GetMapping("/attribute")
public String getAttribute(HttpServletRequest request) {
Object myAttribute = request.getAttribute("myAttribute");
return "Attribute: " + (myAttribute != null ? myAttribute : "Not found");
}
}

Summary

1.​ Request Parameters: Use @RequestParam for query parameters.


2.​ Path Variables: Use @PathVariable for path segments.
3.​ Request Body: Use @RequestBody for JSON or XML data.
4.​ Headers: Use @RequestHeader to access HTTP headers.
5.​ Attributes: Use HttpServletRequest to capture request attributes.
Building complex queries using keywords

In Spring Data JPA, you can build complex queries using various keywords and
techniques. These include method naming conventions, @Query annotations, and
the Criteria API. Here's a detailed guide on how to build complex queries using
these approaches:
I.Derived Query Methods:
Define queries by using method names. For example,
findByLastNameAndAgeGreaterThan can handle simple queries, but for more
complexity, this approach might not be enough.

1. Query Methods with Method Naming Conventions(custom query method)

Spring Data JPA allows you to define complex queries using method names in your
repository interfaces. The query derivation is based on the naming of the method.
Example Entity
package com.example.demo.entity;

import javax.persistence.*;

@Entity
public class User {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String name;


private String email;
private int age;

// Getters and Setters


}
Repository with Query Methods
package com.example.demo.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import com.example.demo.entity.User;

import java.util.List;

public interface UserRepository extends JpaRepository<User, Long> {

// Find by a single field


List<User> findByName(String name);

// Find by multiple fields


List<User> findByNameAndEmail(String name, String email);

// Find by a field with a specific keyword


List<User> findByAgeGreaterThan(int age);

// Find by a field with a specific keyword


List<User> findByNameLike(String namePattern);

// Find with sorting


List<User> findByAgeGreaterThanOrderByAgeAsc(int age);

// Find with pagination (requires Pageable parameter)


Page<User> findByName(String name, Pageable pageable);
}

II.@Query Annotation:
Use the @Query annotation to define JPQL (Java Persistence Query Language) or
native SQL queries. This is useful for more complex queries that cannot be easily
expressed with method names.

1.Custom JPQL Queries


For more complex queries, use the @Query annotation with JPQL (Java Persistence
Query Language).

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

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

import org.springframework.data.repository.query.Param;

import com.example.demo.entity.User;

import java.util.List;

public interface UserRepository extends JpaRepository<User, Long> {

@Query("SELECT u FROM User u WHERE u.name = :name")


List<User> findUsersByName(@Param("name") String name);

@Query("SELECT u FROM User u WHERE u.email = :email")


List<User> findUsersByEmail(@Param("email") String email);

2. Custom Native SQL Queries

You can also use native SQL queries with the @Query annotation.

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

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

import org.springframework.data.repository.query.Param;

import com.example.demo.entity.User;

import java.util.List;

public interface UserRepository extends JpaRepository<User, Long> {

@Query(value = "SELECT * FROM User WHERE email = :email", nativeQuery = true)

List<User> findUsersByEmailNative(@Param("email") String email);

}
III.Using JPA Criteria API
Build queries programmatically using CriteriaBuilder and CriteriaQuery for
dynamic conditions.
Using AND Condition: Retrieve all the persons whose age is >60 and living in the
city Delhi
@Service
public class PersonService {

@Autowired
private EntityManager entityManager;

public List<Person> findPersonsByAgeAndCity(int age, String city) {


CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Person> query = cb.createQuery(Person.class);
Root<Person> person = query.from(Person.class);

Predicate agePredicate = cb.greaterThan(person.get("age"), age);


Predicate cityPredicate = cb.equal(person.get("city"), city);
Predicate finalPredicate = cb.and(agePredicate, cityPredicate);

query.where(finalPredicate);
TypedQuery<Person> typedQuery = entityManager.createQuery(query);
return typedQuery.getResultList();
}
}

IV. Using Stored Procedure


Stored procedures are a way to execute complex operations directly in the database.

Example

1. Create the Stored Procedure

Assume you have a stored procedure in your database that performs some operations. For
example, in a MySQL database, you might have a stored procedure to get users by their
status:

DELIMITER $$
CREATE PROCEDURE GetUsersByStatus(IN userStatus VARCHAR(50))
BEGIN
SELECT * FROM users WHERE status = userStatus;
END$$

DELIMITER ;

You can use the @Procedure annotation in Spring Data JPA to call stored procedures.

1. Repository Method Definition

Here's how you can define a repository method to call a stored procedure:

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.data.jpa.repository.query.Procedure;

import java.util.List;

public interface UserRepository extends JpaRepository<User, Long> {

@Procedure(procedureName = "GetUsersByStatus")
List<User> getUsersByStatus(@Param("userStatus") String userStatus);
}

2. Using @Query for Native Queries

For more complex scenarios, you can use the @Query annotation with native queries.
This can also be used to call stored procedures.

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.List;
public interface UserRepository extends JpaRepository<User, Long> {

@Query(value = "CALL GetUsersByStatus(:userStatus)", nativeQuery = true)


List<User> getUsersByStatus(@Param("userStatus") String userStatus);
}

Queries using logical operations AND,OR


Example
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

private String firstName;


private String lastName;
private int age;
private String city;

// Getters and setters


}

AND Condition:

To find persons who are over 30 years old and live in "New York":
@Repository
public interface PersonRepository extends JpaRepository<Person, Long> {

@Query("SELECT p FROM Person p WHERE p.age > :age AND p.city = :city")
List<Person> findByAgeGreaterThanAndCity(@Param("age") int age,
@Param("city") String city);
}

OR Condition:
To find persons who are either younger than 20 years old or live in "Los Angeles":

@Repository
public interface PersonRepository extends JpaRepository<Person, Long> {

@Query("SELECT p FROM Person p WHERE p.age < :age OR p.city = :city")


List<Person> findByAgeLessThanOrCity(@Param("age") int age, @Param("city")
String city);
}
Queries using IN operator

To find persons who are all living in the city “chennai”

@Query("SELECT p FROM Person p WHERE p.city IN (:city)")


List<Person> findByCity( @Param("city") String city);

You might also like