10. Data JPA Notes
10. Data JPA Notes
=> Spring Data JPA is used to develop Persistence layer in the application.
=> Spring Data JPA providing ready made methods to perform CRUD operation in DB
tables.
=> Data JPA providing ready made methods using interfaces like below
1) CrudRepository ( I )
2) JpaRepository ( I )
==========================
Spring Data JPA Terminology
==========================
###### 2) Entity Class : The class which is mapped with database table ########
@Entity
@Table
@Id
@Column
#### 3) Repository interface : For every Table we will create one repository
interface to perform Crud Operations ###
Note: For our Repository interface, implementation will be provided in the runtime
using Proxy Class.
1) save ( Entity )
2) saveAll (Iterable<Entity> i )
Note: Above two methods are called as "UPSERT" methods ( UPDATE + INSERT )
5) findAll ( )
6) count ( )
10) deleteAll ( )
==============================================
First Application Development Using Spring Data JPA
==============================================
a) springboot-starter-data-jpa
b) mysql-driver
======================Student.java=======================
@Entity
@Table(name = "STUDENT_DTLS") // optional
public class Student {
@Id
@Column(name="student_id") // optional
private Integer id;
@Column(name="student_name")
private String name;
@Column(name="student_rank")
private Long rank;
@Column(name="student_gender")
private String gender;
===========================StudentRepository.java===================
package in.ashokit.repository;
import org.springframework.data.repository.CrudRepository;
import in.ashokit.entity.Student;
//@Repository
public interface StudentRepository extends CrudRepository<Student, Integer>{
============================application.yml file====================
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
password: AshokIT@123
url: jdbc:mysql://localhost:3306/sbms27
username: ashokit
jpa:
hibernate:
ddl-auto: update
show-sql: true
===================================Start Class============================
package in.ashokit;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import in.ashokit.entity.Student;
import in.ashokit.repository.StudentRepository;
@SpringBootApplication
public class Application {
ConfigurableApplicationContext context =
SpringApplication.run(Application.class, args);
StudentRepository studentRepo =
context.getBean(StudentRepository.class);
studentRepo.save(s);
System.out.println("Record Inserted...");
studentRepo.saveAll(students);
if(optional.isPresent()) {
System.out.println(optional.get());
}
// findAll.forEach(System.out::println);
if(studentRepo.existsById(503)) {
studentRepo.deleteById(503);
System.out.println("Record Deleted....");
}else {
System.out.println("No Record Present...");
}
}
}
===========================
findByXXX methods in Data JPA
===========================
=> By using findByXXX ( ) methods we can retrieve the data based on non - primary
key columns also
=> When we write findByXXX method , JPA will construct query based on method name
=====================================Entity
Class====================================
@Entity
@Table(name = "STUDENT_DTLS") // optional
public class Student {
@Id
@Column(name = "student_id") // optional
private Integer id;
@Column(name = "student_name")
private String name;
@Column(name = "student_rank")
private Long rank;
@Column(name = "student_gender")
private String gender;
=========================Repository Interface==========================
===============
Custom Queries
===============
=> We can execute Custom Queries also in JPA (our own queries)
=> @Query will support for executing both HQL queries & Native SQL queries also.
=> In HQL, we will use Entity class name & Entity class variables
to write query
=> HQL queries will converted to SQL queries by Dialect class for
execution
=> In SQL, we will use table name & column names to write the
query
@Query("from Student")
public List<Student> getStudents();
=================================================================================
=================================================================
Selection : Retrieving specific rows from the table. We can achieve this by using '
where ' keyword in the query
=============
JpaRepository
=============
=> JpaRepository provided several methods to perform CRUD operations with database.
==================================================================
Pagination : Displaying table records in multiple pages is called as Pagination
===================================================================
Ex:
=> Google Search Results will display with pagination ( Page size : 10 )
=> Gmail inbox mails will display with pagination ( Page size : 50 )
===============================Pagination Example===============================
ConfigurableApplicationContext context =
SpringApplication.run(Application.class, args);
StudentRepository studentRepo =
context.getBean(StudentRepository.class);
}
}
@SpringBootApplication
public class Application {
ConfigurableApplicationContext context =
SpringApplication.run(Application.class, args);
StudentRepository studentRepo =
context.getBean(StudentRepository.class);
List<Student> students =
studentRepo.findAll(Sort.by("name").descending());
students.forEach(System.out::println);
}
}
================
QueryByExample
================
=> QBE is used to construct select query dynamically based on given entity object
data
@SpringBootApplication
public class Application {
ConfigurableApplicationContext context =
SpringApplication.run(Application.class, args);
StudentRepository studentRepo =
context.getBean(StudentRepository.class);
}
}
=> Insert, Update & Delete records using Custom Queries in Data JPA
=> If we want to perform Non Select Operations using Data JPA custom query then we
should use below 2 annotations at our method.
1) @Modifying
2) @Transactional
Note: The above annotations are not required for selection operation.
=============================Example==============================
=======================
Timestamping in Data JPA
=======================
@Entity
@Table(name = "STUDENT_DTLS") // optional
public class Student {
public Student() {
}
@Id
@Column(name = "student_id") // optional
private Integer id;
@Column(name = "student_name")
private String name;
@Column(name = "student_rank")
private Long rank;
@Column(name = "student_gender")
private String gender;
@CreationTimestamp
@Column(name = "CREATED_DATE", updatable = false)
private LocalDateTime createDate;
@UpdateTimestamp
@Column(name = "UPDATED_DATE", insertable = false)
private LocalDateTime updateDate;
}
Note: LocalDate class represents will date value, where as LocalDateTime class will
represent Date with Time.
======================
Soft Delete & Hard Delete
======================
=> Hard Delete means deleting the record from DB permanently using "Delete" query.
Once we perform Hard Delete we can't get data back from DB.
=> Soft delete means updating the record as IN-ACTIVE. Soft Deleted records will
present in DB so we can access whenever we want.
Ex : Active / De-Activate
Note: We can implement SOFT DELETE using additional column in DB table (ACTIVE_SW)
@SpringBootApplication
public class Application {
ConfigurableApplicationContext context =
SpringApplication.run(Application.class, args);
StudentRepository studentRepo =
context.getBean(StudentRepository.class);
studentRepo.save(student);
}
}
=====================================
Primary key & Composite Primary Key In DB
=====================================
=> We shouldn't ask end users to enter value for PK column because users may enter
duplicate value.
AUTO / SEQUENCE / TABLE ====> New table will be created to maintain primary column
values
IDENTITY ===> Will use AUTO_INCREMENT to generate value for Primary key column
value
AUTO => sequence to generate primary key value (default sequence name :
hibernate_sequence)
SEQUENCE ===> We can configure our own sequence to generate PK value like below
TABLE ====> New table will be created to maintain primary column values
@Id
@TableGenerator(initialValue = 100, name = "pid", table="pid_seq_tbl")
@GeneratedValue(strategy = GenerationType.TABLE, generator="pid")
private Integer productId;
================================================================================
=================================================================================
====================
Composite Primary Key
=====================
-> If a table contains more than one PK column then it is called Composite Primary
key
-> When we have Composite PKs then the combination PK columns data shouldn't be
repeated in table.
Note: We can't use generators to generate value for Composite Primary keys.
@Embeddable
public class AccountPK implements Serializable{
@Entity
public class Account {
@EmbeddedId
private AccountPK accountPk;
==============================Repository======================================
@SpringBootApplication
public class Application {
AccountRepository accountRepo =
context.getBean(AccountRepository.class);
accountRepo.save(acc);*/
===========================
Connection Pooling in Data JPA
===========================
=> Connection Pooling is used to maintain connections required for our application.
=> Getting Connection from DB directley is not recommended because it will degrade
our application.
=> We need to create connection pool to store connections when our application
starts.
=> To perform DB operations we need to get connection from Connection Pool instead
of getting from DB.
=> Using Connection Pool we can improve performance of the application.
Note: Spring Data JPA will use Hikari Connection Pool by default.
============================
Working with Stored Procedures
============================
DELIMITER $$
CREATE PROCEDURE getProducts()
BEGIN
SELECT * FROM PRODUCT;
END$$
DELIMITER ;
call getProducts();
-----------------------------------------------------------------------------------
-----------------------------------------
========================================
Association Mapping / Relationships in DB tables
=======================================
=> When DB tables are having Relation then we need to represent that relation in
our Entity classes also.
Ex: When we delete parent record then we want to delete all Child Records of
that Parent.
Fetch Type : Default Type is LAZY : It represents weather load child records along
with Parent or not
Ex: When we retrieve Parent record i want to retrieve all child records of
that Parent.
@Entity
@Data
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer empId;
private String empName;
private Double empSalary;
@Entity
@Data
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer addrId;
private String city;
private String state;
private String country;
@ManyToOne
@JoinColumn(name = "emp_id")
private Employee emp;
}
@SpringBootApplication
public class Application {
// empRepository.save(e);
// empRepository.findById(2);
// empRepository.deleteById(1);
// addrReposiotry.findById(3);
}
}
===================================================================================
=========