📖
Maissen's Grimoire
  • Maissen's Grimoire
  • Html and css grimoire
    • HTML5 Periodical Table
    • HTML Cheat Sheet
    • CSS Cheatsheets
  • Javascript Grimoire
    • JavaScript Cheat Sheet
      • Javascript Array in depth
      • Tagged Template Literals
      • Guard Clauses - The Best Way To Write Complex Conditional Logic
      • JavaScript Optional Chaining
      • JavaScript Null Coalesce
      • What Are Magic Numbers And Why Are They Bad
      • ES6/ECMAScript2015 Cheatsheet
      • First-class and Higher Order Functions: Effective Functional JavaScript
    • Useful JavaScript Tips, Tricks and Best Practices
    • Bits of code
    • Useful JavaScript libraries
      • Components
      • Animation
      • Maps
      • Helpers
      • Presentations
      • Charts
      • Games
      • Audio
      • Images
      • Video
    • Js the right way
  • Angular Grimoire
    • Angular doc
    • Getting Started
    • Angular clean architecture
    • Angular Cheat Sheet
    • TypeScript Cheat Sheet
    • My Favorite Tips and Tricks in Angular
    • NgRx: tips & tricks
    • Bits of code
      • Execute Multiple HTTP Requests in Angular
      • Authentification
        • Angular 8 JWT Authentication with HttpInterceptor and Router
      • Integrations
        • Spring Boot
          • Rest Example
            • Angular,Spring Boot,Spring Data and Rest Example(CRUD)
          • Authentification
            • Angular, Spring Boot: JWT Authentication with Spring Security example
            • Angular Spring Boot Security Oauth2
              • Spring Boot OAUTH2 Role-Based Authorization
              • Spring Boot Security Google Oauth
              • Spring Security OAuth2 User Registration
    • Most used dependency
  • Node Grimoire
    • Express.js 4 Cheatsheet
    • Useful Dependencies
    • How To Use And Write Express Middleware
    • Node.js with SQL databases
      • Node.js Token Based Authentication & Authorization example
      • Node.js Rest APIs example with Express, Sequelize & MySQL
      • Node.js Express & PostgreSQL: CRUD Rest APIs example with Sequelize
      • Sequelize
        • Sequelize Many-to-Many Association example – Node.js & MySQL
        • Sequelize One-to-Many Association example with Node.js & MySQL
    • Node.js with NOSQL databases
      • Node.js + MongoDB: User Authentication & Authorization with JWT
      • Node.js, Express & MongoDb: Build a CRUD Rest Api example
      • MongoDB One-to-One relationship tutorial with Mongoose example
      • MongoDB One-to-Many Relationship tutorial with Mongoose examples
      • MongoDB Many-to-Many Relationship with Mongoose examples
  • Upload files
    • How to upload multiple files in Node.js
    • Upload & resize multiple images in Node.js using Express, Multer, Sharp
    • Upload/store images in MySQL using Node.js, Express & Multer
    • How to upload/store images in MongoDB using Node.js, Express & Multer
  • React Grimoire
    • React Doc
    • React Grimoire
    • React Cheat Sheet
  • spring boot Grimoire
    • Getting started
    • Spring Boot, Spring Data JPA – Rest CRUD API example
    • Spring Boot Token based Authentication with Spring Security & JWT
  • Mongo Grimoire
    • MongoDb-Mongoose Cheat Sheet
  • Development tools
    • Design Patterns
  • maissen_grimoire
Powered by GitBook
On this page
  • Introduction
  • Why Spring Data
  • What is Spring Data JPA
  • Different Spring Data Repositories
  • Server Side implementation
  • Define Data Model
  • Create Spring Rest APIs Controller
  • Defining Service class
  • Defining DAO class
  • Using EntityManager in Spring Data
  • Pagination and Filter with Spring Data JPA
  • Spring Data Page
  • Spring Data Pageable
  • Database Scripts
  • Run Application

Was this helpful?

  1. spring boot Grimoire

Spring Boot, Spring Data JPA – Rest CRUD API example

PreviousGetting startedNextSpring Boot Token based Authentication with Spring Security & JWT

Last updated 1 year ago

Was this helpful?

Introduction

Why Spring Data

Spring data the data access operations to a very greater extent. The most compelling feature of spring data is the ability to create repository implementations automatically, at runtime, from a repository interface. Hence, you only define the dao interface and the operations you want to perform such as save, read, delete and spring data will provide the implementations at runtime. Not only this, it also provides many inbuilt features for paginations, querying, auditing etc. Spring data provides support for both relational and NoSql DB.

What is Spring Data JPA

Among the many modules provided by Spring Data such as Spring Data Solr, Spring Data MongoDB, Spring Data REST to deal with the persistence layer, Spring Data JPA is also a sub project to deal with persisitence layer. Spring data provides enhanced support for JPA based implementations. We only require to define our repository interfaces, including custom finder methods, and Spring will provide the implementation automatically at run-time.

Different Spring Data Repositories

Lets discuss about different interfaces provided by spring data JPA to deal with persistence layer.

Repository - It is the central interface in the spring data repository abstraction. This is defined as a marker interface.

CrudRepository - CrudRepository provides methods such as save(), findOne(), findAll(), delete() etc. for the CRUD operations. This interface extends the Repository interface. While creating our dao interface we extend this interface with our custom interface and just invoke the abstract methods defined in CrudRepository and spring data will take care of providing the corresponding implementations at run-time.

JpaRepository - It is a JPA specific extension of Repository. It extends CrudRepository and provides some extra JPA related method such as flushing the persistence context and delete record in a batch.

PagingAndSortingRepository - It also extends CrudRepository provide methods to do pagination and sorting records.

Server Side implementation

Define Data Model

Following is the entity class. UserDetails.java

package com.maissen.model;

@Entity
@Table
public class UserDetails {
	
	@Id
	@Column
	@GeneratedValue(strategy = GenerationType.AUTO)
	private long id;
	@Column
	private String firstName;
	@Column
	private String lastName;
	@Column
	private String email;
	@Column
	private String password;
	
	//getters and setters goes here
	

– @Entity annotation indicates that the class is a persistent Java class. – @Table annotation provides the table that maps this entity. – @Id annotation is for the primary key. – @GeneratedValue annotation is used to define generation strategy for the primary key. GenerationType.AUTO means Auto Increment field. – @Column annotation is used to define the column in database that maps annotated field.

Create Spring Rest APIs Controller

Finally, we create a controller that provides APIs for creating, retrieving, updating, deleting and finding data

@RestController
@RequestMapping("/user")
public class UserController {
	
	@Autowired
	private UserService userService;
	
	@RequestMapping(value = "/list", method = RequestMethod.GET)
	public ResponseEntity> userDetails() {
        
		List userDetails = userService.getUserDetails();
		return new ResponseEntity>(userDetails, HttpStatus.OK);
	}

	@RequestMapping(value = "/{id}", method = RequestMethod.GET)
	public ResponseEntity findById(@PathVariable(name = "id", value = "id") Long id) {

		UserDetails userDetail = userService.findById(id);
		return new ResponseEntity(userDetail, HttpStatus.OK);
	}

	@RequestMapping(method = RequestMethod.POST)
	public ResponseEntity findById(@RequestBody UserDetails userDetails) {

		UserDetails userDetail = userService.save(userDetails);
		return new ResponseEntity(userDetail, HttpStatus.OK);
	}

	@RequestMapping(value = "/email/{email:.+}", method = RequestMethod.GET)
	public ResponseEntity findById(@PathVariable(name = "email", value = "email") String email) {

		UserDetails userDetail = userService.findByEmail(email);
		return new ResponseEntity(userDetail, HttpStatus.OK);
	}

    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
    public ResponseEntity delete(@PathVariable(name = "id", value = "id") Long id) {

        userService.delete(id);
        return new ResponseEntity("success", HttpStatus.OK);
    }
}

– @CrossOrigin is for configuring allowed origins. – @RestController annotation is used to define a controller and to indicate that the return value of the methods should be be bound to the web response body. – @RequestMapping("/user") declares that all Apis’ url in the controller will start with /api. – We use @Autowired to inject UserService bean to local variable.

Defining Service class

Following is the service class that acts as a bridge between controller and Repository.

@Service
public class UserServiceImpl implements UserService {
	
	@Autowired
	private UserDao userDao;

	@Override
	public List getUserDetails() {
		return (List) userDao.findAll();
	}

	@Override
	public UserDetails findById(Long id) {
		return  userDao.findOne(id);
	}

	@Override
	public UserDetails save(UserDetails user) {
		return  userDao.save(user);
	}

	@Override
	public UserDetails findByEmail(String email) {
		return  userDao.findByEmail(email);
	}

	@Override
	public void delete(Long id) {
		userDao.delete(id);
	}
}

Defining DAO class

The UserDao interface extends JpaRepository which has different crud methods such as create, findOne, delete etc and hence our UserDao automatically inherits them which is available for our service class to use. Its spring data which will generate the implementations at run time for these crud methods. Hence, we dont have to provide the implementations.

Notice the generic parameters in JpaRepository. Based on these parameters, Spring data will perform different crud operations at run time on our behalf.

Apart from the different default methods defined in the JpaRepository, we have defined our own method - findByEmail(). We have one parameter defined in our entiry class as email and by the naming conventions as findByEmail, Spring data will automatically identify that this is a search operation by email of the user.

public interface UserDao extends JpaRepository<UserDetails, Long> {
	
	UserDetails findByEmail(String email);
	
}

Now we can use JpaRepository’s methods: save(), findOne(), findById(), findAll(), count(), delete(), deleteById()… without implementing these methods.

Spring data is not limited to use of only JPA and some standards methods. Even it is possible to define some custom methods and custom operations too. You can also make use of JPA provided entitymanager to perform custom data manipulation as well as use hibernate session to make advanatage of different functions provided by hibernate.

Using EntityManager in Spring Data

Following is the implementation that uses entitymanager to save data in db while using spring data.

@Repository
public class UserDaoImpl implements Userdao {
	
	@PersistenceContext
    private EntityManager entityManager;

    @Override
    public void save(UserDetails user) {
        entityManager.persist(user);
    }
	
}

Pagination and Filter with Spring Data JPA

public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {
  Page<T> findAll(Pageable pageable);
}

findAll(Pageable pageable): returns a Page of entities meeting the paging condition provided by Pageable object.

Spring Data also supports many useful Query Creation from method names that we’re gonna use to filter result in this example such as:

Page<Tutorial> findByPublished(boolean published, Pageable pageable);
Page<Tutorial> findByTitleContaining(String title, Pageable pageable);

Spring Data Page

Page is a sub-interface of Slice with a couple of additional methods. It contains total amount of elements and total pages of the entire list.

public interface Page<T> extends Slice<T> {
  static <T> Page<T> empty();
  static <T> Page<T> empty(Pageable pageable);
  long getTotalElements();
  int getTotalPages();
  <U> Page<U> map(Function<? super T,? extends U> converter);
}

A Slice object knows less information than a Page, for example, whether the next one or previous one is available or not, or this slice is the first/last one. You can use it when you don’t need the total number of items and total pages.

public interface Slice<T> extends Streamable<T> {
  int getNumber();
  int getSize();
  int getNumberOfElements();
  List<T> getContent();
  boolean hasContent();
  Sort getSort();
  boolean isFirst();
  boolean isLast();
  boolean hasNext();
  boolean hasPrevious();
  ...
}

Spring Data Pageable

The Pageable interface contains the information about the requested page such as the size and the number of the page.

public interface Pageable {
  int getPageNumber();
  int getPageSize();
  long getOffset();
  Sort getSort();
  Pageable next();
  Pageable previousOrFirst();
  Pageable first();
  boolean hasPrevious();
  ...
}

So when we want to get pagination (with or without filter) in the results, we just add Pageable to the definition of the method as a parameter.

Page<Tutorial> findAll(Pageable pageable);
Page<Tutorial> findByPublished(boolean published, Pageable pageable);
Page<Tutorial> findByTitleContaining(String title, Pageable pageable);
Pageable paging = PageRequest.of(page, size);
  • page: zero-based page index, must NOT be negative.

  • size: number of items in a page to be returned, must be greater than 0.

@Repository
public interface UserPageableDao extends JpaRepository<UserDetails, Long> {
    Page listUsers(Pageable pageable);
}

From service implementation we can invoke this Repository method as below:

public List getUserDetails1() {
        Pageable pageable = PageRequest.of(0, 3, Sort.Direction.DESC,"createdOn");
        Page page = userPageableDao.listUsers(pageable);
        return page.getContent();
    }
	
//findOne() is removed.
@Override
public UserDetails findById(Long id) {
	return  userDao.findById(id).get();
}

//delete(id) is removed
@Override
public void delete(Long id) {
	userDao.deleteById(id);
}
  • getContent() to retrieve the List of items in the page.

  • getNumber() for current Page.

  • getTotalElements() for total items stored in database.

  • getTotalPages() for number of total pages

Database Scripts

Following are some sample DML. We will be creating some dummy user details using following insert statements.

create table User_Details (id integer not null auto_increment, email varchar(255), first_Name varchar(255), last_Name varchar(255), password varchar(255), primary key (id)) ENGINE=InnoDB;

INSERT INTO user_details(email,first_Name,last_Name,password) VALUES ('admin@admin.com','admin','admin','admin');

INSERT INTO user_details(email,first_Name,last_Name,password) VALUES ('john@gmail.com','john','doe','johndoe');

INSERT INTO user_details(email,first_Name,last_Name,password) VALUES ('sham@yahoo.com','sham','tis','shamtis');

Run Application

1. Run Application.java as a java application.+

To help us deal with this situation, Spring Data JPA provides way to implement pagination with .

PagingAndSortingRepository extends to provide additional methods to retrieve entities using the pagination abstraction.

You can find more supported keywords inside method names .

Let’s look at the object.

If the number of items increases, the performance could be affected, it’s the time you should think about .

Now we’re gonna see the parameter in Repository methods above. Spring Data infrastructure will recognizes this parameter automatically to apply pagination and sorting to database.

This is how we create Pageable objects using class which implements Pageable interface:

2. Now hit the url - and you can see following.

PagingAndSortingRepository
CrudRepository
here
Page
Slice
Pageable
PageRequest
localhost:8080/user/list
simplifies