Spring data : Basics (using jpa)

Spring data improves how we access data. The benefits of using Spring Data is that it removes a lot of boiler-plate code and provides a cleaner and more readable implementation of DAO layer. Spring data provides a consistent programming model fr a variety of different persistence stores like taditional rdbs -mysql, h2 etc and no-sql dbs like elastisearch, mongo etc. Spring data concepts are constant regardless of the underlying database technology you use.  It provides :

  • A CRUD repository – This gives create, read, update, delete commands
  • Paging and sorting support
  • Custom finder methods – This means you can type in a method that follows a particular format and have it create the query for you.

Let use spring data using JPA (hibernate imlementaion). I would be using spring -boot. If you are not familiar with spring-boot, I suggest you do that first. I have written few posts about it.  I would be using mysql database. Create a schema in mysql. I created my_company. Make the emplyoee table using following script:


CREATE TABLE `employee` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`first_name` varchar(45) NOT NULL,
`last_name` varchar(45) NOT NULL,
`dob` datetime NOT NULL,
`salary` double NOT NULL,
`gender` varchar(45) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

Populate it using following script:


INSERT INTO `employee` (`id`,`first_name`,`last_name`,`dob`,`salary`,`gender`) VALUES (1,'John','Doe','1990-07-03 00:00:00',123123,'M');
INSERT INTO `employee` (`id`,`first_name`,`last_name`,`dob`,`salary`,`gender`) VALUES (2,'Jane','Doe','1991-02-03 00:00:00',130000,'F');
INSERT INTO `employee` (`id`,`first_name`,`last_name`,`dob`,`salary`,`gender`) VALUES (3,'Nathan','Drake','1985-02-03 00:00:00',150000,'M');

Now your database is ready. Lets start creating a spring data project. Create a maven project with following 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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.mynotes</groupId>
<artifactId>spring-data-boot-jpa-basic-start</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>spring-data-boot-jpa-basic-start</name>
<description>Demo project for Spring Data</description>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

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

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

As you ca see we are using spring boot 1.4.1. We have dependencies of spring boot starter , spring data and mysql connector. Lets create our entity class Employee.java


package com.mynotes.entity;

import java.util.Calendar;

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

@Entity
@Table(name = "employee")
public class Employee {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
public int id;

@Column(name = "first_name")
public String fname;

@Column(name = "last_name")
public String lname;

@Column(name = "dob")
public Calendar dob;

@Column(name = "salary")
public Double salary;

@Column(name = "gender")
public String gender;
public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public Calendar getDob() {
return dob;
}

public void setDob(Calendar dob) {
this.dob = dob;
}

public Double getSalary() {
return salary;
}

public void setSalary(Double salary) {
this.salary = salary;
}

public String getFname() {
return fname;
}

public void setFname(String fname) {
this.fname = fname;
}

public String getLname() {
return lname;
}

public void setLname(String lname) {
this.lname = lname;
}

public String getGender() {
return gender;
}

public void setGender(String gender) {
this.gender = gender;
}

@Override
public String toString() {
return "Employee [id=" + id + ", fname=" + fname + ", lname=" + lname + ", dob=" + dob + ", salary=" + salary
+ ", gender=" + gender + "]";
}
}

Above we marked the class as @Entity. This represent the data we want to store. We mapped it to a table. Theen we have an @Id which is going to be the primary key of the table.  All attributes are mapped to their respective column names. The @GeneratedValue annotation is used to specify the primary key generation strategy to use.

The JPA specification supports 4 different primary key generation strategies which generate the primary key values programmatically or use database features, like auto-incremented columns or sequences.
The GenerationType.AUTO is the default generation type and lets the persistence provider choose the generation strategy. If you use Hibernate as your persistence provider, it selects a generation strategy based on the database specific dialect. For most popular databases, it selects GenerationType.IDENTITY.
The GenerationType.IDENTITY is easiest to use, it relies on an auto-incremented database column and lets the database generate a new value with each insert operation.
The GenerationType.SEQUENCE uses a database sequence to generate unique values. If you don’t provide any additional information, Hibernate will request the next value from its default sequence. You can change that by referencing the name of a @SequenceGenerator in the generator attribute of the @GeneratedValue annotation. The @SequenceGenerator annotation lets you define the name of the generator, the name and schema of the database sequence and the allocation and incremental size of the sequence.
The GenerationType.TABLE gets only rarely used nowadays. It simulates a sequence by storing and updating its current value in a database table which requires the use of pessimistic locks which put all transactions into a sequential order. This slows down your application.

Now Lets create our repository EmployeeRepository.java


package com.mynotes.repository;

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

import com.mynotes.entity.Employee;

@Repository
public interface EmployeeRepository extends CrudRepository<Employee,Integer>{

}

Above we use a CrudRepository. The 2 parameters are the type of data we got. The first tells spring which entity this reposirtory is for. The second is the datatype of the primary key. In our case its the id field which is int.
CrudRepository provides a whole bunch of methods (http://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/repository/CrudRepository.html). We can see various finds and save etc.  We can also use JpaRepository . It has some more characteristics.

When talking about the differences of CrudRepository and JpaRepository, it is a good idea to take a third interface into account: the PagingAndSortingRepository. This is because these interfaces the following inheritance hierarchy between them:

PagingAndSortingRepository extends CrudRepository
JpaRepository extends PagingAndSortingRepository
The CrudRepository interface provides methods for CRUD operations, so it allows you to create, read, update and delete records without having to define your own methods. The PagingAndSortingRepository provides additional methods to retrieve entities using pagination and sorting. Finally the JpaRepository add some more functionality that is specific to JPA.

Generally the best idea is to use CrudRepository or PagingAndSortingRepository depending on whether you need sorting and paging or not. The JpaRepository should be avoided if possible, because it ties you repositories to the JPA persistence technology, and in most cases you probably wouldn’t even use the extra methods provided by it.

Lets create our starter class Application.java


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

import com.mynotes.entity.Employee;
import com.mynotes.repository.EmployeeRepository;

@SpringBootApplication
public class Application {

public static void main(String[] args) {
ApplicationContext context =SpringApplication.run(Application.class, args);
EmployeeRepository repository = context.getBean(EmployeeRepository.class);
Iterable<Employee> empList = repository.findAll();
empList.forEach((emp)->System.out.println(emp));

}
}

Above we get the contex and the the reposirtory bean. With the repository we fired the findAll() method and printed in the console.

We have to tell spring about our mysql database. We give these in application.properties


spring.datasource.url=jdbc:mysql://localhost:3306/my_company?autoReconnect=true&useSSL=false
spring.datasource.username=root
spring.datasource.password=admin

spring.jpa.hibernate.ddl-auto=validate
logging.level=DEBUG
spring.jpa.show-sql=true

We used ‘spring.jpa.hibernate.ddl-auto’ as ‘validate’, since we dont want hibernate to create tables/columns for us. It just needs to validate. Other settings are self explanatory.

Lets run Application.java :

spring-data-jpa-basic1

Thats it. With just little configuration we are up and running. Notice we didnt have to write any queries. Spring data did it for us. We would be looking into further details in the next post. ou can get this the code from my github account in spring-data repository.

Advertisements
%d bloggers like this: