1 of 32

SPRING BOOT DATA JPA

2 of 32

Java Persistence API

  • JPA provides developers with an object/relational mapping facility
    • Used for managing relational data in Java applications.

    • Entity Class => Database Table
    • Field of Entity => Database Table Column
    • Entity Instance => Database Table Row

3 of 32

Introduction

Bean

Instance

An Entity

4 of 32

Entities

  • An entity is a lightweight persistence domain object.
    • represents a table in a relational database
    • Each entity instance corresponds to a row in that table.

  • Requirements for Entity Classes
    • @Entity
      • Annotated with the javax.persistence.Entity annotation.
    • The class must have a public or protected, no-argument constructor.
    • The class may have other constructors.
    • Entity’s state must be accessed through accessor or business methods.

5 of 32

Table

  • @Table
    • To specify the details of the table that will be used to persist the entity in the database.

  • Can override the following attributes
    • Table Name
    • Catalogue Name
    • Schema Name

6 of 32

Primary Key

  • Every entity must have a primary key.

  • An entity may have either a simple or a composite primary key.

  • @Id
    • Simple primary keys use this annotation to denote the primary key property or field.

7 of 32

Persistent Fields�

  • Instance Variables should be added with mapping annotations
  • Each field is mapped to a column with the name of the field.

  • @Column (name="newColumnName").
    • Used to change the default name
    • Has many elements such as name, length, nullable, and unique

8 of 32

Entity Class

@Entity

@Table(name=“customers")

public class Customer {

@Id

@column(“custid”)

private Long custId;

@column(“customerName”)

private String customerName;

}

9 of 32

Primary Key Generation

  • Different primary key generation strategies
    • Added to the Primary Key property
  • AUTO
    • Selects the generation strategy based on the used dialect,
  • IDENTITY
    • Relies on an auto-incremented database column to generate the primary key,
  • SEQUENCE
    • Requests the primary key value from a database sequence,
  • TABLE
    • Uses a database table to simulate a sequence.

10 of 32

Primary Key Generation

  • @Generated Value
    • Used to automatically generate the primary key value
    • Applied to a Primary key property
    • Provides for the specification of generation strategies for the values of primary keys.

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

private int rollNumber;

11 of 32

Repository

  • A repository is a mechanism for encapsulating storage, retrieval, and search behavior which emulates a collection of objects.

  • It takes the domain class to manage as well as the ID type of the domain class as type arguments.

  • It’s a marker interface to capture the types to work with

  • CrudRepository interface provides sophisticated CRUD functionality for the entity class

12 of 32

�Repository�

  • CrudRepository
    • Extends Repository
    • provides CRUD functions

  • PagingAndSortingRepository
    • Extends CrudRepository
    • provides methods to do pagination and sort records

  • JpaRepository
    • Extends PagingandSortingRepository
    • Provides Methods such as flushing the persistence context and delete records in a batch
    • Querying methods return List's instead of Iterable’s

13 of 32

�CrudRepository Interface�

  • Extends Repository Interface and has the following Methods

    • <S extends T> S save(S entity)
    • <S extends T> Iterable<S> saveAll(Iterable<S> entities);
    • Optional<T> findById(ID primaryKey)
    • Iterable<T> findAll()
    • void delete(T entity)
    • long count()
    • boolean existsById(ID id);

14 of 32

�PagingAndSortingRepository

    • Extends CrudRepository Interface and has the following Methods
  • findAll(Pageable pageable)
      • Pageable object with following properties
        • Page size
        • Current page number
        • Sorting
        • findAll(Sort sort)
          • Sort Object with the Property on Which the sorting is to be done
          • Sort.by(propName)

15 of 32

CRUD Repository

  • Create an Interface extending CrudRepository

    • public interface BookRepository extends CrudRepository<Book, Long> {}

  • Need NOT create an implementation class
    • Spring will automatically create its implementation class at runtime.
  • The Repository class will be auto detected if suitably placed in the scan path

  • The Repository class will be auto detected if suitably placed in the scan path

16 of 32

Creating Spring Data Application

    • Create a repository interface and extend one of the repository interfaces provided by Spring Data.
    • If required add custom query methods to the created repository interface
    • Inject the repository interface to another component and use the implementation that is provided automatically by Spring.

17 of 32

Entity

@Entity

@Table(name = "demo_Book")

public class Book {

@Id

@column(“bookid”)

long bookId;

@column(“authorname”)

String authorName;

@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)

@column(“dateofpublication”)

LocalDate dateOfPublication;

@column(“amount”)

double amount;

}

18 of 32

Using CRUD Repository

@Service

public class BookService {

@Autowired

private BookRepository repo;

public Iterable<Book> getBooks(){

return repo.findAll();

}

public Book addBook(Book book) {

return repo.save(book);

}

}

19 of 32

Main Method

public static void main(String[] args) {

ConfigurableApplicationContext ctx

=SpringApplication.run(UnderstandingComponentScanApplication.class, args);

BookService service= ctx.getBean(BookService.class));

service.getBooks().forEach(System.out::println);

}

20 of 32

application.yml

spring:

datasource:

url: jdbc:mysql://localhost:3306/test

username: root

password: srivatsan

driver-class-name: com.mysql.cj.jdbc.Driver

jpa:

show-sql: true

hibernate:

ddl-auto: update

21 of 32

H2 In memory Data Base Configuration

spring:

datasource:

url: jdbc:h2:file:C:/h2data/sample

username: sa

password:

driver-class-name: org.h2.Driver

h2:

console:

enabled: true

path: /h2

jpa:

hibernate:

ddl-auto: update

naming:

physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

show-sql: true

22 of 32

Custom Query Methods

23 of 32

Query Method Syntax

  • Methods are defined in JPA repository that Spring Data JPA will auto-implement
    • The query parser will look for methods that start with find, query, read, count, or get.

  • Prefixes can be enhanced with other keywords until it gets to the B-Y, or By, of the method name.

  • findByAgeLike(Integer age);

24 of 32

Rules

  • Rule 1

    • The name of the query method must start with findBy or getBy or queryBy or countBy or readBy prefix.

  • Rule 2

    • The first character of field name should capital letter.

  • Rule 3

    • While using findBy or getBy or queryBy or countBy or readBy the character B must be in capital letter, else we will get an exception while deployment.

25 of 32

Valid Method

  • public List<Student> findByName(String name);
  • public List<Student> getByName(String name);
  • public List<Student> queryByName(String name);
  • public List<Student> countByName(String name);
  • public List<Student> readByName(String name);

26 of 32

Query Method Syntax

  • findByAgeLike(Integer age);
  • find
    • Method starts with find so that the query parser understands that it needs to implement this query contract.

  • By
    • Following the find keyword,
    • Signaling that the criteria information will be coming next in the method name.

  • Age
    • Matches the attribute name age JPA entity, and age is of data type Integer.

27 of 32

Query Method Syntax

  • findByAgeLike(Integer age);

  • Like
    • final keyword tells the implementation to create a Like query

    • Need to pass variable that the query implementation should use as the actual filter criteria.

    • It's of type Integer because data type of age in entity is of type Integer.

28 of 32

Custom Query Method

public interface BookRepository extends CrudRepository<Book, Long> {

List<Book> findByAuthor(String author);

List<Book> findDistinctByCategory(String category);

List<Book> findByAuthorAndCategory(String author, String category);

@Query("SELECT a FROM Book a WHERE a.author=:authore and a.price>:price")

List<Book> fetchBooks(@Param("author") String author, @Param("price") double price);

}

29 of 32

JPQL

  • JPQL queries are defined based on domain model.

  • JPA implementation handles the different database dialects so that the JPQL query is database agnostic.

  • JPQL only supports a subset of the SQL standard.
    • Not a great fit for complex queries.

  • Spring Data JPA provides the required JPA code to execute that query.

    @Query("FROM Author WHERE firstName = ?1")

    List<Author> findByFirstName(String firstName);

30 of 32

@Query

  • Used to write the more flexible query to fetch data.

  • Supports both JPQL and native SQL queries.

  • By default will be using JPQL to execute the queries.
    • Using normal SQL queries, would get the query syntax error exceptions.

  • Can use native SQL queries by setting nativeQuery flag to true.
    • Pagination and dynamic sorting for native queries are not supported in spring data jpa.

31 of 32

Custom Query Method

@Query(value = "select name,author,price from Book b where b.price>?1 and b.price<?2")

List<Book> findByPriceRange(long price1, long price2);

@Query(value = "select name,author,price from Book b where b.name = :name AND b.author=:author AND b.price=:price")

List<Book> findByNamedParam(@Param("name") String name, @Param("author") String author, @Param("price") long price);

@Query(value = "select * from Book b where b.name=?1", nativeQuery = true)

List<Book> findByName(String name); �

32 of 32

�Examples:�

  • SELECT o1 FROM Order o1, Order o2 WHERE o1.quantity > o2.quantity

  • SELECT p FROM Person p WHERE p.age BETWEEN 15 and 19

  • SELECT a FROM Address a WHERE a.country IN ( ‘UK’, ‘US’ , ‘France’ )

  • SELECT o FROM Order o WHERE o.lineItems IS EMPTY

  • SELECT a FROM Address a WHERE a.phone LIKE ‘12%3’